From: Liqiang Tao Date: Sun, 6 Jun 2021 03:49:37 +0000 (+0800) Subject: [llvm] Add interface to order inlining X-Git-Tag: llvmorg-14-init~4756 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=478dc47292b2edfda25c9a3664b60b7ca8c55372;p=platform%2Fupstream%2Fllvm.git [llvm] Add interface to order inlining This patch abstract Calls in Inliner:run() to InlineOrder. With this patch, it's possible to customize the inlining order, i.e. use queue or priority queue. Reviewed By: kazu Differential Revision: https://reviews.llvm.org/D103315 --- diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index f0dbf34..ebf152a 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -670,6 +670,54 @@ InlinerPass::getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM, return *IAA->getAdvisor(); } +template class InlineOrder { +public: + using reference = T &; + + virtual ~InlineOrder() {} + + virtual size_t size() = 0; + + virtual void push(const T &Elt) = 0; + + virtual void pop() = 0; + + virtual reference front() = 0; + + virtual void erase_if(function_ref Pred) = 0; + + bool empty() { return !size(); } +}; + +template > +class DefaultInlineOrder : public InlineOrder { + using reference = T &; + +public: + size_t size() override { return Calls.end() - Calls.begin() - FirstIndex; } + + void push(const T &Elt) override { Calls.push_back(Elt); } + + void pop() override { + assert(size() > 0); + FirstIndex++; + } + + reference front() override { + assert(Calls.begin() + FirstIndex < Calls.end()); + return Calls[FirstIndex]; + } + + void erase_if(function_ref Pred) override { + Calls.erase(std::remove_if(Calls.begin() + FirstIndex, Calls.end(), Pred), + Calls.end()); + } + +private: + Container Calls; + size_t FirstIndex = 0; +}; + PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR) { @@ -714,7 +762,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, // this model, but it is uniformly spread across all the functions in the SCC // and eventually they all become too large to inline, rather than // incrementally maknig a single function grow in a super linear fashion. - SmallVector, 16> Calls; + DefaultInlineOrder> Calls; // Populate the initial list of calls in this SCC. for (auto &N : InitialC) { @@ -729,7 +777,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, if (auto *CB = dyn_cast(&I)) if (Function *Callee = CB->getCalledFunction()) { if (!Callee->isDeclaration()) - Calls.push_back({CB, -1}); + Calls.push({CB, -1}); else if (!isa(I)) { using namespace ore; setInlineRemark(*CB, "unavailable definition"); @@ -766,12 +814,12 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, // Loop forward over all of the calls. Note that we cannot cache the size as // inlining can introduce new calls that need to be processed. - for (int I = 0; I < (int)Calls.size(); ++I) { + while (!Calls.empty()) { // We expect the calls to typically be batched with sequences of calls that // have the same caller, so we first set up some shared infrastructure for // this caller. We also do any pruning we can at this layer on the caller // alone. - Function &F = *Calls[I].first->getCaller(); + Function &F = *(Calls.front()).first->getCaller(); LazyCallGraph::Node &N = *CG.lookup(F); if (CG.lookupSCC(N) != C) continue; @@ -788,8 +836,9 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, // We bail out as soon as the caller has to change so we can update the // call graph and prepare the context of that new caller. bool DidInline = false; - for (; I < (int)Calls.size() && Calls[I].first->getCaller() == &F; ++I) { - auto &P = Calls[I]; + while (!Calls.empty() && Calls.front().first->getCaller() == &F) { + auto &P = Calls.front(); + Calls.pop(); CallBase *CB = P.first; const int InlineHistoryID = P.second; Function &Callee = *CB->getCalledFunction(); @@ -859,7 +908,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, } if (NewCallee) if (!NewCallee->isDeclaration()) - Calls.push_back({ICB, NewHistoryID}); + Calls.push({ICB, NewHistoryID}); } } @@ -876,12 +925,9 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, // made dead by this operation on other functions). Callee.removeDeadConstantUsers(); if (Callee.use_empty() && !CG.isLibFunction(Callee)) { - Calls.erase( - std::remove_if(Calls.begin() + I + 1, Calls.end(), - [&](const std::pair &Call) { - return Call.first->getCaller() == &Callee; - }), - Calls.end()); + Calls.erase_if([&](const std::pair &Call) { + return Call.first->getCaller() == &Callee; + }); // Clear the body and queue the function itself for deletion when we // finish inlining and call graph updates. // Note that after this point, it is an error to do anything other @@ -899,10 +945,6 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, Advice->recordInlining(); } - // Back the call index up by one to put us in a good position to go around - // the outer loop. - --I; - if (!DidInline) continue; Changed = true;