summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineOutliner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/MachineOutliner.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineOutliner.cpp111
1 files changed, 75 insertions, 36 deletions
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp
index cf919a0928c..1bc869e02e6 100644
--- a/llvm/lib/CodeGen/MachineOutliner.cpp
+++ b/llvm/lib/CodeGen/MachineOutliner.cpp
@@ -149,6 +149,8 @@ private:
unsigned OccurrenceCount = 0;
public:
+ std::vector<std::shared_ptr<Candidate>> Candidates;
+
/// The actual outlined function created.
/// This is initialized after we go through and create the actual function.
MachineFunction *MF = nullptr;
@@ -807,10 +809,11 @@ struct MachineOutliner : public ModulePass {
/// type of candidate.
///
/// \returns The length of the longest candidate found.
- unsigned findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
- InstructionMapper &Mapper,
- std::vector<Candidate> &CandidateList,
- std::vector<OutlinedFunction> &FunctionList);
+ unsigned
+ findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
+ InstructionMapper &Mapper,
+ std::vector<std::shared_ptr<Candidate>> &CandidateList,
+ std::vector<OutlinedFunction> &FunctionList);
/// \brief Replace the sequences of instructions represented by the
/// \p Candidates in \p CandidateList with calls to \p MachineFunctions
@@ -820,7 +823,8 @@ struct MachineOutliner : public ModulePass {
/// \param CandidateList A list of candidates to be outlined.
/// \param FunctionList A list of functions to be inserted into the module.
/// \param Mapper Contains the instruction mappings for the module.
- bool outline(Module &M, const ArrayRef<Candidate> &CandidateList,
+ bool outline(Module &M,
+ const ArrayRef<std::shared_ptr<Candidate>> &CandidateList,
std::vector<OutlinedFunction> &FunctionList,
InstructionMapper &Mapper);
@@ -841,10 +845,11 @@ struct MachineOutliner : public ModulePass {
/// \param TII TargetInstrInfo for the module.
///
/// \returns The length of the longest candidate found. 0 if there are none.
- unsigned buildCandidateList(std::vector<Candidate> &CandidateList,
- std::vector<OutlinedFunction> &FunctionList,
- SuffixTree &ST, InstructionMapper &Mapper,
- const TargetInstrInfo &TII);
+ unsigned
+ buildCandidateList(std::vector<std::shared_ptr<Candidate>> &CandidateList,
+ std::vector<OutlinedFunction> &FunctionList,
+ SuffixTree &ST, InstructionMapper &Mapper,
+ const TargetInstrInfo &TII);
/// Helper function for pruneOverlaps.
/// Removes \p C from the candidate list, and updates its \p OutlinedFunction.
@@ -863,7 +868,7 @@ struct MachineOutliner : public ModulePass {
/// \param Mapper Contains instruction mapping info for outlining.
/// \param MaxCandidateLen The length of the longest candidate.
/// \param TII TargetInstrInfo for the module.
- void pruneOverlaps(std::vector<Candidate> &CandidateList,
+ void pruneOverlaps(std::vector<std::shared_ptr<Candidate>> &CandidateList,
std::vector<OutlinedFunction> &FunctionList,
InstructionMapper &Mapper, unsigned MaxCandidateLen,
const TargetInstrInfo &TII);
@@ -887,11 +892,10 @@ ModulePass *createMachineOutlinerPass(bool OutlineFromLinkOnceODRs) {
INITIALIZE_PASS(MachineOutliner, DEBUG_TYPE, "Machine Function Outliner", false,
false)
-unsigned
-MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
- InstructionMapper &Mapper,
- std::vector<Candidate> &CandidateList,
- std::vector<OutlinedFunction> &FunctionList) {
+unsigned MachineOutliner::findCandidates(
+ SuffixTree &ST, const TargetInstrInfo &TII, InstructionMapper &Mapper,
+ std::vector<std::shared_ptr<Candidate>> &CandidateList,
+ std::vector<OutlinedFunction> &FunctionList) {
CandidateList.clear();
FunctionList.clear();
unsigned MaxLen = 0;
@@ -1004,13 +1008,17 @@ MachineOutliner::findCandidates(SuffixTree &ST, const TargetInstrInfo &TII,
// At this point, the candidate class is seen as beneficial. Set their
// benefit values and save them in the candidate list.
+ std::vector<std::shared_ptr<Candidate>> CandidatesForFn;
for (Candidate &C : CandidatesForRepeatedSeq) {
C.Benefit = Benefit;
C.MInfo = MInfo;
- CandidateList.push_back(C);
+ std::shared_ptr<Candidate> Cptr = std::make_shared<Candidate>(C);
+ CandidateList.push_back(Cptr);
+ CandidatesForFn.push_back(Cptr);
}
FunctionList.push_back(OF);
+ FunctionList.back().Candidates = CandidatesForFn;
// Move to the next function.
Parent.IsInTree = false;
@@ -1038,11 +1046,10 @@ void MachineOutliner::prune(Candidate &C,
<< "\n";);
}
-void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
- std::vector<OutlinedFunction> &FunctionList,
- InstructionMapper &Mapper,
- unsigned MaxCandidateLen,
- const TargetInstrInfo &TII) {
+void MachineOutliner::pruneOverlaps(
+ std::vector<std::shared_ptr<Candidate>> &CandidateList,
+ std::vector<OutlinedFunction> &FunctionList, InstructionMapper &Mapper,
+ unsigned MaxCandidateLen, const TargetInstrInfo &TII) {
// Return true if this candidate became unbeneficial for outlining in a
// previous step.
@@ -1069,7 +1076,7 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
// This is O(MaxCandidateLen * CandidateList.size()).
for (auto It = CandidateList.begin(), Et = CandidateList.end(); It != Et;
It++) {
- Candidate &C1 = *It;
+ Candidate &C1 = **It;
// If C1 was already pruned, or its function is no longer beneficial for
// outlining, move to the next candidate.
@@ -1088,7 +1095,7 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
// FarthestPossibleIdx indices away from C1. There are at most
// MaxCandidateLen of these.
for (auto Sit = It + 1; Sit != Et; Sit++) {
- Candidate &C2 = *Sit;
+ Candidate &C2 = **Sit;
// Is this candidate too far away to overlap?
if (C2.getStartIdx() < FarthestPossibleIdx)
@@ -1130,11 +1137,10 @@ void MachineOutliner::pruneOverlaps(std::vector<Candidate> &CandidateList,
}
}
-unsigned
-MachineOutliner::buildCandidateList(std::vector<Candidate> &CandidateList,
- std::vector<OutlinedFunction> &FunctionList,
- SuffixTree &ST, InstructionMapper &Mapper,
- const TargetInstrInfo &TII) {
+unsigned MachineOutliner::buildCandidateList(
+ std::vector<std::shared_ptr<Candidate>> &CandidateList,
+ std::vector<OutlinedFunction> &FunctionList, SuffixTree &ST,
+ InstructionMapper &Mapper, const TargetInstrInfo &TII) {
std::vector<unsigned> CandidateSequence; // Current outlining candidate.
unsigned MaxCandidateLen = 0; // Length of the longest candidate.
@@ -1145,7 +1151,10 @@ MachineOutliner::buildCandidateList(std::vector<Candidate> &CandidateList,
// Sort the candidates in decending order. This will simplify the outlining
// process when we have to remove the candidates from the mapping by
// allowing us to cut them out without keeping track of an offset.
- std::stable_sort(CandidateList.begin(), CandidateList.end());
+ std::stable_sort(
+ CandidateList.begin(), CandidateList.end(),
+ [](const std::shared_ptr<Candidate> &LHS,
+ const std::shared_ptr<Candidate> &RHS) { return *LHS < *RHS; });
return MaxCandidateLen;
}
@@ -1204,15 +1213,14 @@ MachineOutliner::createOutlinedFunction(Module &M, const OutlinedFunction &OF,
return &MF;
}
-bool MachineOutliner::outline(Module &M,
- const ArrayRef<Candidate> &CandidateList,
- std::vector<OutlinedFunction> &FunctionList,
- InstructionMapper &Mapper) {
+bool MachineOutliner::outline(
+ Module &M, const ArrayRef<std::shared_ptr<Candidate>> &CandidateList,
+ std::vector<OutlinedFunction> &FunctionList, InstructionMapper &Mapper) {
bool OutlinedSomething = false;
// Replace the candidates with calls to their respective outlined functions.
- for (const Candidate &C : CandidateList) {
-
+ for (const std::shared_ptr<Candidate> &Cptr : CandidateList) {
+ Candidate &C = *Cptr;
// Was the candidate removed during pruneOverlaps?
if (!C.InCandidateList)
continue;
@@ -1240,6 +1248,37 @@ bool MachineOutliner::outline(Module &M,
// Does this candidate have a function yet?
if (!OF.MF) {
OF.MF = createOutlinedFunction(M, OF, Mapper);
+ MachineBasicBlock *MBB = &*OF.MF->begin();
+
+ // Output a remark telling the user that an outlined function was created,
+ // and explaining where it came from.
+ MachineOptimizationRemarkEmitter MORE(*OF.MF, nullptr);
+ MachineOptimizationRemark R(DEBUG_TYPE, "OutlinedFunction",
+ MBB->findDebugLoc(MBB->begin()), MBB);
+ R << "Saved " << NV("OutliningBenefit", OF.getBenefit())
+ << " instructions by "
+ << "outlining " << NV("Length", OF.Sequence.size()) << " instructions "
+ << "from " << NV("NumOccurrences", OF.getOccurrenceCount())
+ << " locations. "
+ << "(Found at: ";
+
+ // Tell the user the other places the candidate was found.
+ for (size_t i = 0, e = OF.Candidates.size(); i < e; i++) {
+
+ // Skip over things that were pruned.
+ if (!OF.Candidates[i]->InCandidateList)
+ continue;
+
+ R << NV(
+ (Twine("StartLoc") + Twine(i)).str(),
+ Mapper.InstrList[OF.Candidates[i]->getStartIdx()]->getDebugLoc());
+ if (i != e - 1)
+ R << ", ";
+ }
+
+ R << ")";
+
+ MORE.emit(R);
FunctionsCreated++;
}
@@ -1300,7 +1339,7 @@ bool MachineOutliner::runOnModule(Module &M) {
// Construct a suffix tree, use it to find candidates, and then outline them.
SuffixTree ST(Mapper.UnsignedVec);
- std::vector<Candidate> CandidateList;
+ std::vector<std::shared_ptr<Candidate>> CandidateList;
std::vector<OutlinedFunction> FunctionList;
// Find all of the outlining candidates.
OpenPOWER on IntegriCloud