diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineOutliner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineOutliner.cpp | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/llvm/lib/CodeGen/MachineOutliner.cpp b/llvm/lib/CodeGen/MachineOutliner.cpp index 4b56a46..42f410c 100644 --- a/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/llvm/lib/CodeGen/MachineOutliner.cpp @@ -456,8 +456,9 @@ struct MachineOutliner : public ModulePass { /// \param Mapper Contains outlining mapping information. /// \param[out] FunctionList Filled with a list of \p OutlinedFunctions /// each type of candidate. - void findCandidates(InstructionMapper &Mapper, - std::vector<OutlinedFunction> &FunctionList); + void + findCandidates(InstructionMapper &Mapper, + std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList); /// Replace the sequences of instructions represented by \p OutlinedFunctions /// with calls to functions. @@ -465,7 +466,9 @@ struct MachineOutliner : public ModulePass { /// \param M The module we are outlining from. /// \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, std::vector<OutlinedFunction> &FunctionList, + /// \param[out] OutlinedFunctionNum The outlined function number. + bool outline(Module &M, + std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList, InstructionMapper &Mapper, unsigned &OutlinedFunctionNum); /// Creates a function for \p OF and inserts it into the module. @@ -583,7 +586,8 @@ void MachineOutliner::emitOutlinedFunctionRemark(OutlinedFunction &OF) { } void MachineOutliner::findCandidates( - InstructionMapper &Mapper, std::vector<OutlinedFunction> &FunctionList) { + InstructionMapper &Mapper, + std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList) { FunctionList.clear(); SuffixTree ST(Mapper.UnsignedVec, OutlinerLeafDescendants); @@ -658,11 +662,12 @@ void MachineOutliner::findCandidates( << "\n"); LLVM_DEBUG(dbgs() << " Candidates kept: " << NumKept << "\n\n"); #endif + unsigned MinRepeats = 2; // We've found something we might want to outline. // Create an OutlinedFunction to store it and check if it'd be beneficial // to outline. - if (CandidatesForRepeatedSeq.size() < 2) + if (CandidatesForRepeatedSeq.size() < MinRepeats) continue; // Arbitrarily choose a TII from the first candidate. @@ -670,21 +675,23 @@ void MachineOutliner::findCandidates( const TargetInstrInfo *TII = CandidatesForRepeatedSeq[0].getMF()->getSubtarget().getInstrInfo(); - std::optional<OutlinedFunction> OF = - TII->getOutliningCandidateInfo(*MMI, CandidatesForRepeatedSeq); + std::optional<std::unique_ptr<OutlinedFunction>> OF = + TII->getOutliningCandidateInfo(*MMI, CandidatesForRepeatedSeq, + MinRepeats); // If we deleted too many candidates, then there's nothing worth outlining. // FIXME: This should take target-specified instruction sizes into account. - if (!OF || OF->Candidates.size() < 2) + if (!OF.has_value() || OF.value()->Candidates.size() < MinRepeats) continue; // Is it better to outline this candidate than not? - if (OF->getBenefit() < OutlinerBenefitThreshold) { - emitNotOutliningCheaperRemark(StringLen, CandidatesForRepeatedSeq, *OF); + if (OF.value()->getBenefit() < OutlinerBenefitThreshold) { + emitNotOutliningCheaperRemark(StringLen, CandidatesForRepeatedSeq, + *OF.value()); continue; } - FunctionList.push_back(*OF); + FunctionList.emplace_back(std::move(OF.value())); } } @@ -827,10 +834,9 @@ MachineFunction *MachineOutliner::createOutlinedFunction( return &MF; } -bool MachineOutliner::outline(Module &M, - std::vector<OutlinedFunction> &FunctionList, - InstructionMapper &Mapper, - unsigned &OutlinedFunctionNum) { +bool MachineOutliner::outline( + Module &M, std::vector<std::unique_ptr<OutlinedFunction>> &FunctionList, + InstructionMapper &Mapper, unsigned &OutlinedFunctionNum) { LLVM_DEBUG(dbgs() << "*** Outlining ***\n"); LLVM_DEBUG(dbgs() << "NUMBER OF POTENTIAL FUNCTIONS: " << FunctionList.size() << "\n"); @@ -838,23 +844,23 @@ bool MachineOutliner::outline(Module &M, // Sort by priority where priority := getNotOutlinedCost / getOutliningCost. // The function with highest priority should be outlined first. - stable_sort(FunctionList, - [](const OutlinedFunction &LHS, const OutlinedFunction &RHS) { - return LHS.getNotOutlinedCost() * RHS.getOutliningCost() > - RHS.getNotOutlinedCost() * LHS.getOutliningCost(); - }); + stable_sort(FunctionList, [](const std::unique_ptr<OutlinedFunction> &LHS, + const std::unique_ptr<OutlinedFunction> &RHS) { + return LHS->getNotOutlinedCost() * RHS->getOutliningCost() > + RHS->getNotOutlinedCost() * LHS->getOutliningCost(); + }); // Walk over each function, outlining them as we go along. Functions are // outlined greedily, based off the sort above. auto *UnsignedVecBegin = Mapper.UnsignedVec.begin(); LLVM_DEBUG(dbgs() << "WALKING FUNCTION LIST\n"); - for (OutlinedFunction &OF : FunctionList) { + for (auto &OF : FunctionList) { #ifndef NDEBUG - auto NumCandidatesBefore = OF.Candidates.size(); + auto NumCandidatesBefore = OF->Candidates.size(); #endif // If we outlined something that overlapped with a candidate in a previous // step, then we can't outline from it. - erase_if(OF.Candidates, [&UnsignedVecBegin](Candidate &C) { + erase_if(OF->Candidates, [&UnsignedVecBegin](Candidate &C) { return std::any_of(UnsignedVecBegin + C.getStartIdx(), UnsignedVecBegin + C.getEndIdx() + 1, [](unsigned I) { return I == static_cast<unsigned>(-1); @@ -862,36 +868,36 @@ bool MachineOutliner::outline(Module &M, }); #ifndef NDEBUG - auto NumCandidatesAfter = OF.Candidates.size(); + auto NumCandidatesAfter = OF->Candidates.size(); LLVM_DEBUG(dbgs() << "PRUNED: " << NumCandidatesBefore - NumCandidatesAfter << "/" << NumCandidatesBefore << " candidates\n"); #endif // If we made it unbeneficial to outline this function, skip it. - if (OF.getBenefit() < OutlinerBenefitThreshold) { - LLVM_DEBUG(dbgs() << "SKIP: Expected benefit (" << OF.getBenefit() + if (OF->getBenefit() < OutlinerBenefitThreshold) { + LLVM_DEBUG(dbgs() << "SKIP: Expected benefit (" << OF->getBenefit() << " B) < threshold (" << OutlinerBenefitThreshold << " B)\n"); continue; } - LLVM_DEBUG(dbgs() << "OUTLINE: Expected benefit (" << OF.getBenefit() + LLVM_DEBUG(dbgs() << "OUTLINE: Expected benefit (" << OF->getBenefit() << " B) > threshold (" << OutlinerBenefitThreshold << " B)\n"); // It's beneficial. Create the function and outline its sequence's // occurrences. - OF.MF = createOutlinedFunction(M, OF, Mapper, OutlinedFunctionNum); - emitOutlinedFunctionRemark(OF); + OF->MF = createOutlinedFunction(M, *OF, Mapper, OutlinedFunctionNum); + emitOutlinedFunctionRemark(*OF); FunctionsCreated++; OutlinedFunctionNum++; // Created a function, move to the next name. - MachineFunction *MF = OF.MF; + MachineFunction *MF = OF->MF; const TargetSubtargetInfo &STI = MF->getSubtarget(); const TargetInstrInfo &TII = *STI.getInstrInfo(); // Replace occurrences of the sequence with calls to the new function. LLVM_DEBUG(dbgs() << "CREATE OUTLINED CALLS\n"); - for (Candidate &C : OF.Candidates) { + for (Candidate &C : OF->Candidates) { MachineBasicBlock &MBB = *C.getMBB(); MachineBasicBlock::iterator StartIt = C.begin(); MachineBasicBlock::iterator EndIt = std::prev(C.end()); @@ -1180,7 +1186,7 @@ bool MachineOutliner::doOutline(Module &M, unsigned &OutlinedFunctionNum) { // Prepare instruction mappings for the suffix tree. populateMapper(Mapper, M); - std::vector<OutlinedFunction> FunctionList; + std::vector<std::unique_ptr<OutlinedFunction>> FunctionList; // Find all of the outlining candidates. findCandidates(Mapper, FunctionList); |