diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineOutliner.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineOutliner.cpp | 152 |
1 files changed, 71 insertions, 81 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineOutliner.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineOutliner.cpp index 3a9104bda0d1..80a235aeaa5c 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MachineOutliner.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineOutliner.cpp @@ -68,7 +68,6 @@ #include "llvm/IR/DIBuilder.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Mangler.h" -#include "llvm/InitializePasses.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -92,7 +91,8 @@ STATISTIC(FunctionsCreated, "Number of functions created"); // this is off by default. It should, however, be the default behaviour in // LTO. static cl::opt<bool> EnableLinkOnceODROutlining( - "enable-linkonceodr-outlining", cl::Hidden, + "enable-linkonceodr-outlining", + cl::Hidden, cl::desc("Enable the machine outliner on linkonceodr functions"), cl::init(false)); @@ -253,7 +253,7 @@ private: /// Ukkonen's algorithm. struct ActiveState { /// The next node to insert at. - SuffixTreeNode *Node = nullptr; + SuffixTreeNode *Node; /// The index of the first character in the substring currently being added. unsigned Idx = EmptyIdx; @@ -301,8 +301,8 @@ private: "Non-root internal nodes must have parents!"); unsigned *E = new (InternalEndIdxAllocator) unsigned(EndIdx); - SuffixTreeNode *N = - new (NodeAllocator.Allocate()) SuffixTreeNode(StartIdx, E, Root); + SuffixTreeNode *N = new (NodeAllocator.Allocate()) + SuffixTreeNode(StartIdx, E, Root); if (Parent) Parent->Children[Edge] = N; @@ -311,31 +311,26 @@ private: /// Set the suffix indices of the leaves to the start indices of their /// respective suffixes. - void setSuffixIndices() { - // List of nodes we need to visit along with the current length of the - // string. - std::vector<std::pair<SuffixTreeNode *, unsigned>> ToVisit; - - // Current node being visited. - SuffixTreeNode *CurrNode = Root; - - // Sum of the lengths of the nodes down the path to the current one. - unsigned CurrNodeLen = 0; - ToVisit.push_back({CurrNode, CurrNodeLen}); - while (!ToVisit.empty()) { - std::tie(CurrNode, CurrNodeLen) = ToVisit.back(); - ToVisit.pop_back(); - CurrNode->ConcatLen = CurrNodeLen; - for (auto &ChildPair : CurrNode->Children) { - assert(ChildPair.second && "Node had a null child!"); - ToVisit.push_back( - {ChildPair.second, CurrNodeLen + ChildPair.second->size()}); - } - - // No children, so we are at the end of the string. - if (CurrNode->Children.size() == 0 && !CurrNode->isRoot()) - CurrNode->SuffixIdx = Str.size() - CurrNodeLen; + /// + /// \param[in] CurrNode The node currently being visited. + /// \param CurrNodeLen The concatenation of all node sizes from the root to + /// this node. Used to produce suffix indices. + void setSuffixIndices(SuffixTreeNode &CurrNode, unsigned CurrNodeLen) { + + bool IsLeaf = CurrNode.Children.size() == 0 && !CurrNode.isRoot(); + + // Store the concatenation of lengths down from the root. + CurrNode.ConcatLen = CurrNodeLen; + // Traverse the tree depth-first. + for (auto &ChildPair : CurrNode.Children) { + assert(ChildPair.second && "Node had a null child!"); + setSuffixIndices(*ChildPair.second, + CurrNodeLen + ChildPair.second->size()); } + + // Is this node a leaf? If it is, give it a suffix index. + if (IsLeaf) + CurrNode.SuffixIdx = Str.size() - CurrNodeLen; } /// Construct the suffix tree for the prefix of the input ending at @@ -478,6 +473,7 @@ public: // Keep track of the number of suffixes we have to add of the current // prefix. unsigned SuffixesToAdd = 0; + Active.Node = Root; // Construct the suffix tree iteratively on each prefix of the string. // PfxEndIdx is the end index of the current prefix. @@ -491,12 +487,13 @@ public: // Set the suffix indices of each leaf. assert(Root && "Root node can't be nullptr!"); - setSuffixIndices(); + setSuffixIndices(*Root, 0); } + /// Iterator for finding all repeated substrings in the suffix tree. struct RepeatedSubstringIterator { - private: + private: /// The current node we're visiting. SuffixTreeNode *N = nullptr; @@ -598,7 +595,7 @@ public: advance(); } } - }; +}; typedef RepeatedSubstringIterator iterator; iterator begin() { return iterator(Root); } @@ -697,10 +694,9 @@ struct InstructionMapper { /// IllegalInstrNumber. /// /// \returns The integer that \p *It was mapped to. - unsigned mapToIllegalUnsigned( - MachineBasicBlock::iterator &It, bool &CanOutlineWithPrevInstr, - std::vector<unsigned> &UnsignedVecForMBB, - std::vector<MachineBasicBlock::iterator> &InstrListForMBB) { + unsigned mapToIllegalUnsigned(MachineBasicBlock::iterator &It, + bool &CanOutlineWithPrevInstr, std::vector<unsigned> &UnsignedVecForMBB, + std::vector<MachineBasicBlock::iterator> &InstrListForMBB) { // Can't outline an illegal instruction. Set the flag. CanOutlineWithPrevInstr = false; @@ -768,12 +764,12 @@ struct InstructionMapper { std::vector<unsigned> UnsignedVecForMBB; std::vector<MachineBasicBlock::iterator> InstrListForMBB; - for (MachineBasicBlock::iterator Et = MBB.end(); It != Et; ++It) { + for (MachineBasicBlock::iterator Et = MBB.end(); It != Et; It++) { // Keep track of where this instruction is in the module. switch (TII.getOutliningType(It, Flags)) { case InstrType::Illegal: - mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB, - InstrListForMBB); + mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, + UnsignedVecForMBB, InstrListForMBB); break; case InstrType::Legal: @@ -787,7 +783,7 @@ struct InstructionMapper { // The instruction also acts as a terminator, so we have to record that // in the string. mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB, - InstrListForMBB); + InstrListForMBB); break; case InstrType::Invisible: @@ -806,7 +802,7 @@ struct InstructionMapper { // boundaries since the "end" is encoded uniquely and thus appears in no // repeated substring. mapToIllegalUnsigned(It, CanOutlineWithPrevInstr, UnsignedVecForMBB, - InstrListForMBB); + InstrListForMBB); InstrList.insert(InstrList.end(), InstrListForMBB.begin(), InstrListForMBB.end()); UnsignedVec.insert(UnsignedVec.end(), UnsignedVecForMBB.begin(), @@ -850,8 +846,8 @@ struct MachineOutliner : public ModulePass { StringRef getPassName() const override { return "Machine Outliner"; } void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired<MachineModuleInfoWrapperPass>(); - AU.addPreserved<MachineModuleInfoWrapperPass>(); + AU.addRequired<MachineModuleInfo>(); + AU.addPreserved<MachineModuleInfo>(); AU.setPreservesAll(); ModulePass::getAnalysisUsage(AU); } @@ -892,27 +888,24 @@ struct MachineOutliner : public ModulePass { /// \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, - InstructionMapper &Mapper, unsigned &OutlinedFunctionNum); + InstructionMapper &Mapper); /// Creates a function for \p OF and inserts it into the module. MachineFunction *createOutlinedFunction(Module &M, OutlinedFunction &OF, InstructionMapper &Mapper, unsigned Name); - /// Calls 'doOutline()'. - bool runOnModule(Module &M) override; - /// Construct a suffix tree on the instructions in \p M and outline repeated /// strings from that tree. - bool doOutline(Module &M, unsigned &OutlinedFunctionNum); + bool runOnModule(Module &M) override; /// Return a DISubprogram for OF if one exists, and null otherwise. Helper /// function for remark emission. DISubprogram *getSubprogramOrNull(const OutlinedFunction &OF) { + DISubprogram *SP; for (const Candidate &C : OF.Candidates) - if (MachineFunction *MF = C.getMF()) - if (DISubprogram *SP = MF->getFunction().getSubprogram()) - return SP; + if (C.getMF() && (SP = C.getMF()->getFunction().getSubprogram())) + return SP; return nullptr; } @@ -925,14 +918,15 @@ struct MachineOutliner : public ModulePass { /// FIXME: This should be handled by the pass manager, not the outliner. /// FIXME: This is nearly identical to the initSizeRemarkInfo in the legacy /// pass manager. - void initSizeRemarkInfo(const Module &M, const MachineModuleInfo &MMI, - StringMap<unsigned> &FunctionToInstrCount); + void initSizeRemarkInfo( + const Module &M, const MachineModuleInfo &MMI, + StringMap<unsigned> &FunctionToInstrCount); /// Emit the remark. // FIXME: This should be handled by the pass manager, not the outliner. - void - emitInstrCountChangedRemark(const Module &M, const MachineModuleInfo &MMI, - const StringMap<unsigned> &FunctionToInstrCount); + void emitInstrCountChangedRemark( + const Module &M, const MachineModuleInfo &MMI, + const StringMap<unsigned> &FunctionToInstrCount); }; } // Anonymous namespace. @@ -1009,12 +1003,13 @@ void MachineOutliner::emitOutlinedFunctionRemark(OutlinedFunction &OF) { MORE.emit(R); } -void MachineOutliner::findCandidates( - InstructionMapper &Mapper, std::vector<OutlinedFunction> &FunctionList) { +void +MachineOutliner::findCandidates(InstructionMapper &Mapper, + std::vector<OutlinedFunction> &FunctionList) { FunctionList.clear(); SuffixTree ST(Mapper.UnsignedVec); - // First, find all of the repeated substrings in the tree of minimum length + // First, find dall of the repeated substrings in the tree of minimum length // 2. std::vector<Candidate> CandidatesForRepeatedSeq; for (auto It = ST.begin(), Et = ST.end(); It != Et; ++It) { @@ -1092,8 +1087,10 @@ void MachineOutliner::findCandidates( } } -MachineFunction *MachineOutliner::createOutlinedFunction( - Module &M, OutlinedFunction &OF, InstructionMapper &Mapper, unsigned Name) { +MachineFunction * +MachineOutliner::createOutlinedFunction(Module &M, OutlinedFunction &OF, + InstructionMapper &Mapper, + unsigned Name) { // Create the function name. This should be unique. // FIXME: We should have a better naming scheme. This should be stable, @@ -1131,7 +1128,7 @@ MachineFunction *MachineOutliner::createOutlinedFunction( IRBuilder<> Builder(EntryBB); Builder.CreateRetVoid(); - MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); + MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>(); MachineFunction &MF = MMI.getOrCreateMachineFunction(*F); MachineBasicBlock &MBB = *MF.CreateMachineBasicBlock(); const TargetSubtargetInfo &STI = MF.getSubtarget(); @@ -1193,11 +1190,13 @@ MachineFunction *MachineOutliner::createOutlinedFunction( bool MachineOutliner::outline(Module &M, std::vector<OutlinedFunction> &FunctionList, - InstructionMapper &Mapper, - unsigned &OutlinedFunctionNum) { + InstructionMapper &Mapper) { bool OutlinedSomething = false; + // Number to append to the current outlined function. + unsigned OutlinedFunctionNum = 0; + // Sort by benefit. The most beneficial functions should be outlined first. llvm::stable_sort(FunctionList, [](const OutlinedFunction &LHS, const OutlinedFunction &RHS) { @@ -1261,7 +1260,7 @@ bool MachineOutliner::outline(Module &M, true /* isImp = true */)); } if (MI.isCall()) - MI.getMF()->eraseCallSiteInfo(&MI); + MI.getMF()->updateCallSiteInfo(&MI); }; // Copy over the defs in the outlined range. // First inst in outlined range <-- Anything that's defined in this @@ -1398,7 +1397,8 @@ void MachineOutliner::emitInstrCountChangedRemark( MachineOptimizationRemarkEmitter MORE(*MF, nullptr); MORE.emit([&]() { MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange", - DiagnosticLocation(), &MF->front()); + DiagnosticLocation(), + &MF->front()); R << DiagnosticInfoOptimizationBase::Argument("Pass", "Machine Outliner") << ": Function: " << DiagnosticInfoOptimizationBase::Argument("Function", F.getName()) @@ -1421,30 +1421,21 @@ bool MachineOutliner::runOnModule(Module &M) { if (M.empty()) return false; - // Number to append to the current outlined function. - unsigned OutlinedFunctionNum = 0; - - if (!doOutline(M, OutlinedFunctionNum)) - return false; - return true; -} - -bool MachineOutliner::doOutline(Module &M, unsigned &OutlinedFunctionNum) { - MachineModuleInfo &MMI = getAnalysis<MachineModuleInfoWrapperPass>().getMMI(); + MachineModuleInfo &MMI = getAnalysis<MachineModuleInfo>(); // If the user passed -enable-machine-outliner=always or // -enable-machine-outliner, the pass will run on all functions in the module. // Otherwise, if the target supports default outlining, it will run on all // functions deemed by the target to be worth outlining from by default. Tell // the user how the outliner is running. - LLVM_DEBUG({ + LLVM_DEBUG( dbgs() << "Machine Outliner: Running on "; if (RunOnAllFunctions) dbgs() << "all functions"; else dbgs() << "target-default functions"; - dbgs() << "\n"; - }); + dbgs() << "\n" + ); // If the user specifies that they want to outline from linkonceodrs, set // it here. @@ -1473,8 +1464,7 @@ bool MachineOutliner::doOutline(Module &M, unsigned &OutlinedFunctionNum) { initSizeRemarkInfo(M, MMI, FunctionToInstrCount); // Outline each of the candidates and return true if something was outlined. - bool OutlinedSomething = - outline(M, FunctionList, Mapper, OutlinedFunctionNum); + bool OutlinedSomething = outline(M, FunctionList, Mapper); // If we outlined something, we definitely changed the MI count of the // module. If we've asked for size remarks, then output them. |
