Skip to content

Commit 38e69b8

Browse files
author
Jessica Paquette
committed
[MachineOutliner] NFC: Change IsTailCall to a call class + frame class
This commit - Removes IsTailCall and replaces it with a target-defined unsigned - Refactors getOutliningCallOverhead and getOutliningFrameOverhead so that they don't use IsTailCall - Adds a call class + frame class classification to OutlinedFunction and Candidate respectively This accomplishes a couple things. Firstly, we don't need the notion of *tail call* in the general outlining algorithm. Secondly, we now can have different "outlining classes" for each candidate within a set of candidates. This will make it easy to add new ways to outline sequences for certain targets and dynamically choose an appropriate cost model for a sequence depending on the context that that sequence lives in. Ultimately, this should get us closer to being able to do something like, say avoid saving the link register when outlining AArch64 instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309475 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 4ea03c9 commit 38e69b8

File tree

6 files changed

+288
-205
lines changed

6 files changed

+288
-205
lines changed

include/llvm/Target/TargetInstrInfo.h

+17-8
Original file line numberDiff line numberDiff line change
@@ -1556,7 +1556,11 @@ class TargetInstrInfo : public MCInstrInfo {
15561556
/// \brief Returns the number of instructions that will be taken to call a
15571557
/// function defined by the sequence on the closed interval [ \p StartIt, \p
15581558
/// EndIt].
1559-
virtual size_t
1559+
///
1560+
/// \returns The number of instructions for the call in the first member,
1561+
/// and a target-defined unsigned describing what type of call to emit in the
1562+
/// second member.
1563+
virtual std::pair<size_t, unsigned>
15601564
getOutliningCallOverhead(MachineBasicBlock::iterator &StartIt,
15611565
MachineBasicBlock::iterator &EndIt) const {
15621566
llvm_unreachable(
@@ -1566,11 +1570,16 @@ class TargetInstrInfo : public MCInstrInfo {
15661570
/// \brief Returns the number of instructions that will be taken to construct
15671571
/// an outlined function frame for a function defined on the closed interval
15681572
/// [ \p StartIt, \p EndIt].
1569-
virtual size_t
1570-
getOutliningFrameOverhead(MachineBasicBlock::iterator &StartIt,
1571-
MachineBasicBlock::iterator &EndIt) const {
1573+
///
1574+
/// \returns The number of instructions for the frame in the first member
1575+
/// and a target-defined unsigned describing what type of frame to construct
1576+
/// in the second member.
1577+
virtual std::pair<size_t, unsigned> getOutliningFrameOverhead(
1578+
std::vector<
1579+
std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
1580+
&CandidateClass) const {
15721581
llvm_unreachable(
1573-
"Target didn't implement TargetInstrInfo::getOutliningCallOverhead!");
1582+
"Target didn't implement TargetInstrInfo::getOutliningFrameOverhead!");
15741583
}
15751584

15761585
/// Represents how an instruction should be mapped by the outliner.
@@ -1591,7 +1600,7 @@ class TargetInstrInfo : public MCInstrInfo {
15911600
/// emitted.
15921601
virtual void insertOutlinerEpilogue(MachineBasicBlock &MBB,
15931602
MachineFunction &MF,
1594-
bool IsTailCall) const {
1603+
unsigned FrameClass) const {
15951604
llvm_unreachable(
15961605
"Target didn't implement TargetInstrInfo::insertOutlinerEpilogue!");
15971606
}
@@ -1602,7 +1611,7 @@ class TargetInstrInfo : public MCInstrInfo {
16021611
virtual MachineBasicBlock::iterator
16031612
insertOutlinedCall(Module &M, MachineBasicBlock &MBB,
16041613
MachineBasicBlock::iterator &It, MachineFunction &MF,
1605-
bool IsTailCall) const {
1614+
unsigned CallClass) const {
16061615
llvm_unreachable(
16071616
"Target didn't implement TargetInstrInfo::insertOutlinedCall!");
16081617
}
@@ -1611,7 +1620,7 @@ class TargetInstrInfo : public MCInstrInfo {
16111620
/// This may be empty, in which case no prologue will be emitted.
16121621
virtual void insertOutlinerPrologue(MachineBasicBlock &MBB,
16131622
MachineFunction &MF,
1614-
bool IsTailCall) const {
1623+
unsigned FrameClass) const {
16151624
llvm_unreachable(
16161625
"Target didn't implement TargetInstrInfo::insertOutlinerPrologue!");
16171626
}

lib/CodeGen/MachineOutliner.cpp

+50-37
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ struct Candidate {
8787
/// \p OutlinedFunctions.
8888
size_t FunctionIdx;
8989

90+
/// Target-defined unsigned defining how to emit a call for this candidate.
91+
unsigned CallClass = 0;
92+
9093
/// \brief The number of instructions that would be saved by outlining every
9194
/// candidate of this type.
9295
///
@@ -96,8 +99,9 @@ struct Candidate {
9699
/// for some given candidate.
97100
unsigned Benefit = 0;
98101

99-
Candidate(size_t StartIdx, size_t Len, size_t FunctionIdx)
100-
: StartIdx(StartIdx), Len(Len), FunctionIdx(FunctionIdx) {}
102+
Candidate(size_t StartIdx, size_t Len, size_t FunctionIdx, unsigned CallClass)
103+
: StartIdx(StartIdx), Len(Len), FunctionIdx(FunctionIdx),
104+
CallClass(CallClass) {}
101105

102106
Candidate() {}
103107

@@ -127,15 +131,14 @@ struct OutlinedFunction {
127131
/// The number of instructions this function would save.
128132
unsigned Benefit = 0;
129133

130-
/// \brief Set to true if candidates for this outlined function should be
131-
/// replaced with tail calls to this OutlinedFunction.
132-
bool IsTailCall = false;
134+
/// Target-defined unsigned defining how to emit the frame for this function.
135+
unsigned FrameClass = 0;
133136

134137
OutlinedFunction(size_t Name, size_t OccurrenceCount,
135138
const std::vector<unsigned> &Sequence, unsigned Benefit,
136-
bool IsTailCall)
139+
unsigned FrameClass)
137140
: Name(Name), OccurrenceCount(OccurrenceCount), Sequence(Sequence),
138-
Benefit(Benefit), IsTailCall(IsTailCall) {}
141+
Benefit(Benefit), FrameClass(FrameClass) {}
139142
};
140143

141144
/// Represents an undefined index in the suffix tree.
@@ -842,9 +845,18 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
842845
// Figure out if this candidate is beneficial.
843846
size_t StringLen = Leaf->ConcatLen - Leaf->size();
844847
size_t CallOverhead = 0;
845-
size_t FrameOverhead = 0;
846848
size_t SequenceOverhead = StringLen;
847849

850+
// If this is a beneficial class of candidate, then every one is stored in
851+
// this vector.
852+
std::vector<Candidate> CandidatesForRepeatedSeq;
853+
854+
// Used for getOutliningFrameOverhead.
855+
// FIXME: CandidatesForRepeatedSeq and this should be combined.
856+
std::vector<
857+
std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>>
858+
CandidateClass;
859+
848860
// Figure out the call overhead for each instance of the sequence.
849861
for (auto &ChildPair : Parent.Children) {
850862
SuffixTreeNode *M = ChildPair.second;
@@ -854,16 +866,24 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
854866
MachineBasicBlock::iterator StartIt = Mapper.InstrList[M->SuffixIdx];
855867
MachineBasicBlock::iterator EndIt =
856868
Mapper.InstrList[M->SuffixIdx + StringLen - 1];
857-
CallOverhead += TII.getOutliningCallOverhead(StartIt, EndIt);
869+
870+
// Get the overhead for calling a function for this sequence and any
871+
// target-specified data for how to construct the call.
872+
std::pair<size_t, unsigned> CallOverheadPair =
873+
TII.getOutliningCallOverhead(StartIt, EndIt);
874+
CallOverhead += CallOverheadPair.first;
875+
CandidatesForRepeatedSeq.emplace_back(M->SuffixIdx, StringLen, FnIdx,
876+
CallOverheadPair.second);
877+
CandidateClass.emplace_back(std::make_pair(StartIt, EndIt));
878+
879+
// Never visit this leaf again.
880+
M->IsInTree = false;
858881
}
859882
}
860883

861-
// Figure out how many instructions it'll take to construct an outlined
862-
// function frame for this sequence.
863-
MachineBasicBlock::iterator StartIt = Mapper.InstrList[Leaf->SuffixIdx];
864-
MachineBasicBlock::iterator EndIt =
865-
Mapper.InstrList[Leaf->SuffixIdx + StringLen - 1];
866-
FrameOverhead = TII.getOutliningFrameOverhead(StartIt, EndIt);
884+
std::pair<size_t, unsigned> FrameOverheadPair =
885+
TII.getOutliningFrameOverhead(CandidateClass);
886+
size_t FrameOverhead = FrameOverheadPair.first;
867887

868888
size_t OutliningCost = CallOverhead + FrameOverhead + SequenceOverhead;
869889
size_t NotOutliningCost = SequenceOverhead * Parent.OccurrenceCount;
@@ -876,26 +896,21 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
876896
if (StringLen > MaxLen)
877897
MaxLen = StringLen;
878898

879-
unsigned OccurrenceCount = 0;
880-
for (auto &ChildPair : Parent.Children) {
881-
SuffixTreeNode *M = ChildPair.second;
882-
883-
// Is it a leaf? If so, we have an occurrence of this candidate.
884-
if (M && M->IsInTree && M->isLeaf()) {
885-
OccurrenceCount++;
886-
CandidateList.emplace_back(M->SuffixIdx, StringLen, FnIdx);
887-
CandidateList.back().Benefit = Benefit;
888-
M->IsInTree = false;
889-
}
899+
// At this point, the candidate class is seen as beneficial. Set their
900+
// benefit values and save them in the candidate list.
901+
for (Candidate &C : CandidatesForRepeatedSeq) {
902+
C.Benefit = Benefit;
903+
CandidateList.push_back(C);
890904
}
891905

892906
// Save the function for the new candidate sequence.
893907
std::vector<unsigned> CandidateSequence;
894908
for (unsigned i = Leaf->SuffixIdx; i < Leaf->SuffixIdx + StringLen; i++)
895909
CandidateSequence.push_back(ST.Str[i]);
896910

897-
FunctionList.emplace_back(FnIdx, OccurrenceCount, CandidateSequence,
898-
Benefit, false);
911+
FunctionList.emplace_back(FnIdx, CandidatesForRepeatedSeq.size(),
912+
CandidateSequence, Benefit,
913+
FrameOverheadPair.second);
899914

900915
// Move to the next function.
901916
FnIdx++;
@@ -996,7 +1011,8 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
9961011
MachineBasicBlock::iterator StartIt = Mapper.InstrList[C2.StartIdx];
9971012
MachineBasicBlock::iterator EndIt =
9981013
Mapper.InstrList[C2.StartIdx + C2.Len - 1];
999-
F2.Benefit += TII.getOutliningCallOverhead(StartIt, EndIt);
1014+
1015+
F2.Benefit += TII.getOutliningCallOverhead(StartIt, EndIt).first;
10001016
// Add back one instance of the sequence.
10011017

10021018
if (F2.Sequence.size() > F2.Benefit)
@@ -1022,7 +1038,8 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
10221038
MachineBasicBlock::iterator StartIt = Mapper.InstrList[C1.StartIdx];
10231039
MachineBasicBlock::iterator EndIt =
10241040
Mapper.InstrList[C1.StartIdx + C1.Len - 1];
1025-
F2.Benefit += TII.getOutliningCallOverhead(StartIt, EndIt);
1041+
1042+
F1.Benefit += TII.getOutliningCallOverhead(StartIt, EndIt).first;
10261043

10271044
// Add back one instance of the sequence.
10281045
if (F1.Sequence.size() > F1.Benefit)
@@ -1056,10 +1073,6 @@ MachineOutliner::buildCandidateList(std::vector<Candidate> &CandidateList,
10561073
MaxCandidateLen =
10571074
findCandidates(ST, TII, Mapper, CandidateList, FunctionList);
10581075

1059-
for (auto &OF : FunctionList)
1060-
OF.IsTailCall =
1061-
Mapper.IntegerInstructionMap[OF.Sequence.back()]->isTerminator();
1062-
10631076
// Sort the candidates in decending order. This will simplify the outlining
10641077
// process when we have to remove the candidates from the mapping by
10651078
// allowing us to cut them out without keeping track of an offset.
@@ -1102,7 +1115,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
11021115
// Insert the new function into the module.
11031116
MF.insert(MF.begin(), &MBB);
11041117

1105-
TII.insertOutlinerPrologue(MBB, MF, OF.IsTailCall);
1118+
TII.insertOutlinerPrologue(MBB, MF, OF.FrameClass);
11061119

11071120
// Copy over the instructions for the function using the integer mappings in
11081121
// its sequence.
@@ -1117,7 +1130,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
11171130
MBB.insert(MBB.end(), NewMI);
11181131
}
11191132

1120-
TII.insertOutlinerEpilogue(MBB, MF, OF.IsTailCall);
1133+
TII.insertOutlinerEpilogue(MBB, MF, OF.FrameClass);
11211134

11221135
return &MF;
11231136
}
@@ -1166,7 +1179,7 @@ bool MachineOutliner::outline(Module &M,
11661179
const TargetInstrInfo &TII = *STI.getInstrInfo();
11671180

11681181
// Insert a call to the new function and erase the old sequence.
1169-
TII.insertOutlinedCall(M, *MBB, StartIt, *MF, OF.IsTailCall);
1182+
TII.insertOutlinedCall(M, *MBB, StartIt, *MF, C.CallClass);
11701183
StartIt = Mapper.InstrList[C.StartIdx];
11711184
MBB->erase(StartIt, EndIt);
11721185

lib/Target/AArch64/AArch64InstrInfo.cpp

+27-22
Original file line numberDiff line numberDiff line change
@@ -4432,27 +4432,34 @@ AArch64InstrInfo::getSerializableMachineMemOperandTargetFlags() const {
44324432
return makeArrayRef(TargetFlags);
44334433
}
44344434

4435-
size_t AArch64InstrInfo::getOutliningCallOverhead(
4435+
// Constants defining how certain sequences should be outlined.
4436+
const unsigned MachineOutlinerDefaultFn = 0;
4437+
const unsigned MachineOutlinerTailCallFn = 1;
4438+
4439+
std::pair<size_t, unsigned> AArch64InstrInfo::getOutliningCallOverhead(
44364440
MachineBasicBlock::iterator &StartIt,
44374441
MachineBasicBlock::iterator &EndIt) const {
44384442
// Is this a tail-call?
4439-
if (EndIt->isTerminator())
4440-
return 1; // Yes, so we don't need to save/restore LR.
4443+
if (EndIt->isTerminator()) {
4444+
// Yes, so we only have to emit a call. Return a cost of 1 + signify that
4445+
// this candidate should be tail-called.
4446+
return std::make_pair(1, MachineOutlinerTailCallFn);
4447+
}
44414448

44424449
// No, so save + restore LR.
4443-
return 3;
4450+
return std::make_pair(3, MachineOutlinerDefaultFn);
44444451
}
44454452

4446-
size_t AArch64InstrInfo::getOutliningFrameOverhead(
4447-
MachineBasicBlock::iterator &StartIt,
4448-
MachineBasicBlock::iterator &EndIt) const {
4453+
std::pair<size_t, unsigned> AArch64InstrInfo::getOutliningFrameOverhead(
4454+
std::vector<std::pair<MachineBasicBlock::iterator,
4455+
MachineBasicBlock::iterator>> &CandidateClass) const {
44494456

4450-
// Is this a tail-call?
4451-
if (EndIt->isTerminator())
4452-
return 0; // Yes, so we already have a return.
4457+
// Is the last instruction in this class a terminator?
4458+
if (CandidateClass[0].second->isTerminator())
4459+
return std::make_pair(0, MachineOutlinerTailCallFn);
44534460

44544461
// No, so we have to add a return to the end.
4455-
return 1;
4462+
return std::make_pair(1, MachineOutlinerDefaultFn);
44564463
}
44574464

44584465
bool AArch64InstrInfo::isFunctionSafeToOutlineFrom(MachineFunction &MF) const {
@@ -4568,10 +4575,10 @@ void AArch64InstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const {
45684575

45694576
void AArch64InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB,
45704577
MachineFunction &MF,
4571-
bool IsTailCall) const {
4578+
unsigned FrameClass) const {
45724579

45734580
// If this is a tail call outlined function, then there's already a return.
4574-
if (IsTailCall)
4581+
if (FrameClass == MachineOutlinerTailCallFn)
45754582
return;
45764583

45774584
// It's not a tail call, so we have to insert the return ourselves.
@@ -4585,18 +4592,17 @@ void AArch64InstrInfo::insertOutlinerEpilogue(MachineBasicBlock &MBB,
45854592

45864593
void AArch64InstrInfo::insertOutlinerPrologue(MachineBasicBlock &MBB,
45874594
MachineFunction &MF,
4588-
bool IsTailCall) const {}
4595+
unsigned FrameClass) const {}
45894596

45904597
MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall(
45914598
Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It,
4592-
MachineFunction &MF, bool IsTailCall) const {
4599+
MachineFunction &MF, unsigned CallClass) const {
45934600

45944601
// Are we tail calling?
4595-
if (IsTailCall) {
4602+
if (CallClass == MachineOutlinerTailCallFn) {
45964603
// If yes, then we can just branch to the label.
4597-
It = MBB.insert(It,
4598-
BuildMI(MF, DebugLoc(), get(AArch64::B))
4599-
.addGlobalAddress(M.getNamedValue(MF.getName())));
4604+
It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::B))
4605+
.addGlobalAddress(M.getNamedValue(MF.getName())));
46004606
return It;
46014607
}
46024608

@@ -4611,9 +4617,8 @@ MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall(
46114617
It++;
46124618

46134619
// Insert the call.
4614-
It = MBB.insert(It,
4615-
BuildMI(MF, DebugLoc(), get(AArch64::BL))
4616-
.addGlobalAddress(M.getNamedValue(MF.getName())));
4620+
It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::BL))
4621+
.addGlobalAddress(M.getNamedValue(MF.getName())));
46174622

46184623
It++;
46194624

0 commit comments

Comments
 (0)