@@ -87,6 +87,9 @@ struct Candidate {
87
87
// / \p OutlinedFunctions.
88
88
size_t FunctionIdx;
89
89
90
+ // / Target-defined unsigned defining how to emit a call for this candidate.
91
+ unsigned CallClass = 0 ;
92
+
90
93
// / \brief The number of instructions that would be saved by outlining every
91
94
// / candidate of this type.
92
95
// /
@@ -96,8 +99,9 @@ struct Candidate {
96
99
// / for some given candidate.
97
100
unsigned Benefit = 0 ;
98
101
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) {}
101
105
102
106
Candidate () {}
103
107
@@ -127,15 +131,14 @@ struct OutlinedFunction {
127
131
// / The number of instructions this function would save.
128
132
unsigned Benefit = 0 ;
129
133
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 ;
133
136
134
137
OutlinedFunction (size_t Name, size_t OccurrenceCount,
135
138
const std::vector<unsigned > &Sequence, unsigned Benefit,
136
- bool IsTailCall )
139
+ unsigned FrameClass )
137
140
: Name(Name), OccurrenceCount(OccurrenceCount), Sequence(Sequence),
138
- Benefit (Benefit), IsTailCall(IsTailCall ) {}
141
+ Benefit (Benefit), FrameClass(FrameClass ) {}
139
142
};
140
143
141
144
// / Represents an undefined index in the suffix tree.
@@ -842,9 +845,18 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
842
845
// Figure out if this candidate is beneficial.
843
846
size_t StringLen = Leaf->ConcatLen - Leaf->size ();
844
847
size_t CallOverhead = 0 ;
845
- size_t FrameOverhead = 0 ;
846
848
size_t SequenceOverhead = StringLen;
847
849
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
+
848
860
// Figure out the call overhead for each instance of the sequence.
849
861
for (auto &ChildPair : Parent.Children ) {
850
862
SuffixTreeNode *M = ChildPair.second ;
@@ -854,16 +866,24 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
854
866
MachineBasicBlock::iterator StartIt = Mapper.InstrList [M->SuffixIdx ];
855
867
MachineBasicBlock::iterator EndIt =
856
868
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 ;
858
881
}
859
882
}
860
883
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 ;
867
887
868
888
size_t OutliningCost = CallOverhead + FrameOverhead + SequenceOverhead;
869
889
size_t NotOutliningCost = SequenceOverhead * Parent.OccurrenceCount ;
@@ -876,26 +896,21 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
876
896
if (StringLen > MaxLen)
877
897
MaxLen = StringLen;
878
898
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);
890
904
}
891
905
892
906
// Save the function for the new candidate sequence.
893
907
std::vector<unsigned > CandidateSequence;
894
908
for (unsigned i = Leaf->SuffixIdx ; i < Leaf->SuffixIdx + StringLen; i++)
895
909
CandidateSequence.push_back (ST.Str [i]);
896
910
897
- FunctionList.emplace_back (FnIdx, OccurrenceCount, CandidateSequence,
898
- Benefit, false );
911
+ FunctionList.emplace_back (FnIdx, CandidatesForRepeatedSeq.size (),
912
+ CandidateSequence, Benefit,
913
+ FrameOverheadPair.second );
899
914
900
915
// Move to the next function.
901
916
FnIdx++;
@@ -996,7 +1011,8 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
996
1011
MachineBasicBlock::iterator StartIt = Mapper.InstrList [C2.StartIdx ];
997
1012
MachineBasicBlock::iterator EndIt =
998
1013
Mapper.InstrList [C2.StartIdx + C2.Len - 1 ];
999
- F2.Benefit += TII.getOutliningCallOverhead (StartIt, EndIt);
1014
+
1015
+ F2.Benefit += TII.getOutliningCallOverhead (StartIt, EndIt).first ;
1000
1016
// Add back one instance of the sequence.
1001
1017
1002
1018
if (F2.Sequence .size () > F2.Benefit )
@@ -1022,7 +1038,8 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
1022
1038
MachineBasicBlock::iterator StartIt = Mapper.InstrList [C1.StartIdx ];
1023
1039
MachineBasicBlock::iterator EndIt =
1024
1040
Mapper.InstrList [C1.StartIdx + C1.Len - 1 ];
1025
- F2.Benefit += TII.getOutliningCallOverhead (StartIt, EndIt);
1041
+
1042
+ F1.Benefit += TII.getOutliningCallOverhead (StartIt, EndIt).first ;
1026
1043
1027
1044
// Add back one instance of the sequence.
1028
1045
if (F1.Sequence .size () > F1.Benefit )
@@ -1056,10 +1073,6 @@ MachineOutliner::buildCandidateList(std::vector<Candidate> &CandidateList,
1056
1073
MaxCandidateLen =
1057
1074
findCandidates (ST, TII, Mapper, CandidateList, FunctionList);
1058
1075
1059
- for (auto &OF : FunctionList)
1060
- OF.IsTailCall =
1061
- Mapper.IntegerInstructionMap [OF.Sequence .back ()]->isTerminator ();
1062
-
1063
1076
// Sort the candidates in decending order. This will simplify the outlining
1064
1077
// process when we have to remove the candidates from the mapping by
1065
1078
// allowing us to cut them out without keeping track of an offset.
@@ -1102,7 +1115,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
1102
1115
// Insert the new function into the module.
1103
1116
MF.insert (MF.begin (), &MBB);
1104
1117
1105
- TII.insertOutlinerPrologue (MBB, MF, OF.IsTailCall );
1118
+ TII.insertOutlinerPrologue (MBB, MF, OF.FrameClass );
1106
1119
1107
1120
// Copy over the instructions for the function using the integer mappings in
1108
1121
// its sequence.
@@ -1117,7 +1130,7 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
1117
1130
MBB.insert (MBB.end (), NewMI);
1118
1131
}
1119
1132
1120
- TII.insertOutlinerEpilogue (MBB, MF, OF.IsTailCall );
1133
+ TII.insertOutlinerEpilogue (MBB, MF, OF.FrameClass );
1121
1134
1122
1135
return &MF;
1123
1136
}
@@ -1166,7 +1179,7 @@ bool MachineOutliner::outline(Module &M,
1166
1179
const TargetInstrInfo &TII = *STI.getInstrInfo ();
1167
1180
1168
1181
// 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 );
1170
1183
StartIt = Mapper.InstrList [C.StartIdx ];
1171
1184
MBB->erase (StartIt, EndIt);
1172
1185
0 commit comments