Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- Inliner.h - Inliner pass and infrastructure --------------*- C++ -*-===// |
| 2 | // |
||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
| 6 | // |
||
| 7 | //===----------------------------------------------------------------------===// |
||
| 8 | |||
| 9 | #ifndef LLVM_TRANSFORMS_IPO_INLINER_H |
||
| 10 | #define LLVM_TRANSFORMS_IPO_INLINER_H |
||
| 11 | |||
| 12 | #include "llvm/Analysis/CGSCCPassManager.h" |
||
| 13 | #include "llvm/Analysis/CallGraphSCCPass.h" |
||
| 14 | #include "llvm/Analysis/InlineAdvisor.h" |
||
| 15 | #include "llvm/Analysis/InlineCost.h" |
||
| 16 | #include "llvm/Analysis/LazyCallGraph.h" |
||
| 17 | #include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h" |
||
| 18 | #include "llvm/IR/PassManager.h" |
||
| 19 | |||
| 20 | namespace llvm { |
||
| 21 | |||
| 22 | class AssumptionCacheTracker; |
||
| 23 | class CallGraph; |
||
| 24 | class ProfileSummaryInfo; |
||
| 25 | |||
| 26 | /// This class contains all of the helper code which is used to perform the |
||
| 27 | /// inlining operations that do not depend on the policy. It contains the core |
||
| 28 | /// bottom-up inlining infrastructure that specific inliner passes use. |
||
| 29 | struct LegacyInlinerBase : public CallGraphSCCPass { |
||
| 30 | explicit LegacyInlinerBase(char &ID); |
||
| 31 | explicit LegacyInlinerBase(char &ID, bool InsertLifetime); |
||
| 32 | |||
| 33 | /// For this class, we declare that we require and preserve the call graph. |
||
| 34 | /// If the derived class implements this method, it should always explicitly |
||
| 35 | /// call the implementation here. |
||
| 36 | void getAnalysisUsage(AnalysisUsage &Info) const override; |
||
| 37 | |||
| 38 | using llvm::Pass::doInitialization; |
||
| 39 | |||
| 40 | bool doInitialization(CallGraph &CG) override; |
||
| 41 | |||
| 42 | /// Main run interface method, this implements the interface required by the |
||
| 43 | /// Pass class. |
||
| 44 | bool runOnSCC(CallGraphSCC &SCC) override; |
||
| 45 | |||
| 46 | using llvm::Pass::doFinalization; |
||
| 47 | |||
| 48 | /// Remove now-dead linkonce functions at the end of processing to avoid |
||
| 49 | /// breaking the SCC traversal. |
||
| 50 | bool doFinalization(CallGraph &CG) override; |
||
| 51 | |||
| 52 | /// This method must be implemented by the subclass to determine the cost of |
||
| 53 | /// inlining the specified call site. If the cost returned is greater than |
||
| 54 | /// the current inline threshold, the call site is not inlined. |
||
| 55 | virtual InlineCost getInlineCost(CallBase &CB) = 0; |
||
| 56 | |||
| 57 | /// Remove dead functions. |
||
| 58 | /// |
||
| 59 | /// This also includes a hack in the form of the 'AlwaysInlineOnly' flag |
||
| 60 | /// which restricts it to deleting functions with an 'AlwaysInline' |
||
| 61 | /// attribute. This is useful for the InlineAlways pass that only wants to |
||
| 62 | /// deal with that subset of the functions. |
||
| 63 | bool removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly = false); |
||
| 64 | |||
| 65 | /// This function performs the main work of the pass. The default of |
||
| 66 | /// Inlinter::runOnSCC() calls skipSCC() before calling this method, but |
||
| 67 | /// derived classes which cannot be skipped can override that method and call |
||
| 68 | /// this function unconditionally. |
||
| 69 | bool inlineCalls(CallGraphSCC &SCC); |
||
| 70 | |||
| 71 | private: |
||
| 72 | // Insert @llvm.lifetime intrinsics. |
||
| 73 | bool InsertLifetime = true; |
||
| 74 | |||
| 75 | protected: |
||
| 76 | AssumptionCacheTracker *ACT; |
||
| 77 | ProfileSummaryInfo *PSI; |
||
| 78 | std::function<const TargetLibraryInfo &(Function &)> GetTLI; |
||
| 79 | ImportedFunctionsInliningStatistics ImportedFunctionsStats; |
||
| 80 | }; |
||
| 81 | |||
| 82 | /// The inliner pass for the new pass manager. |
||
| 83 | /// |
||
| 84 | /// This pass wires together the inlining utilities and the inline cost |
||
| 85 | /// analysis into a CGSCC pass. It considers every call in every function in |
||
| 86 | /// the SCC and tries to inline if profitable. It can be tuned with a number of |
||
| 87 | /// parameters to control what cost model is used and what tradeoffs are made |
||
| 88 | /// when making the decision. |
||
| 89 | /// |
||
| 90 | /// It should be noted that the legacy inliners do considerably more than this |
||
| 91 | /// inliner pass does. They provide logic for manually merging allocas, and |
||
| 92 | /// doing considerable DCE including the DCE of dead functions. This pass makes |
||
| 93 | /// every attempt to be simpler. DCE of functions requires complex reasoning |
||
| 94 | /// about comdat groups, etc. Instead, it is expected that other more focused |
||
| 95 | /// passes be composed to achieve the same end result. |
||
| 96 | class InlinerPass : public PassInfoMixin<InlinerPass> { |
||
| 97 | public: |
||
| 98 | InlinerPass(bool OnlyMandatory = false, |
||
| 99 | ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None) |
||
| 100 | : OnlyMandatory(OnlyMandatory), LTOPhase(LTOPhase) {} |
||
| 101 | InlinerPass(InlinerPass &&Arg) = default; |
||
| 102 | |||
| 103 | PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, |
||
| 104 | LazyCallGraph &CG, CGSCCUpdateResult &UR); |
||
| 105 | |||
| 106 | void printPipeline(raw_ostream &OS, |
||
| 107 | function_ref<StringRef(StringRef)> MapClassName2PassName); |
||
| 108 | |||
| 109 | private: |
||
| 110 | InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM, |
||
| 111 | FunctionAnalysisManager &FAM, Module &M); |
||
| 112 | std::unique_ptr<InlineAdvisor> OwnedAdvisor; |
||
| 113 | const bool OnlyMandatory; |
||
| 114 | const ThinOrFullLTOPhase LTOPhase; |
||
| 115 | }; |
||
| 116 | |||
| 117 | /// Module pass, wrapping the inliner pass. This works in conjunction with the |
||
| 118 | /// InlineAdvisorAnalysis to facilitate inlining decisions taking into account |
||
| 119 | /// module-wide state, that need to keep track of inter-inliner pass runs, for |
||
| 120 | /// a given module. An InlineAdvisor is configured and kept alive for the |
||
| 121 | /// duration of the ModuleInlinerWrapperPass::run. |
||
| 122 | class ModuleInlinerWrapperPass |
||
| 123 | : public PassInfoMixin<ModuleInlinerWrapperPass> { |
||
| 124 | public: |
||
| 125 | ModuleInlinerWrapperPass( |
||
| 126 | InlineParams Params = getInlineParams(), bool MandatoryFirst = true, |
||
| 127 | InlineContext IC = {}, |
||
| 128 | InliningAdvisorMode Mode = InliningAdvisorMode::Default, |
||
| 129 | unsigned MaxDevirtIterations = 0); |
||
| 130 | ModuleInlinerWrapperPass(ModuleInlinerWrapperPass &&Arg) = default; |
||
| 131 | |||
| 132 | PreservedAnalyses run(Module &, ModuleAnalysisManager &); |
||
| 133 | |||
| 134 | /// Allow adding more CGSCC passes, besides inlining. This should be called |
||
| 135 | /// before run is called, as part of pass pipeline building. |
||
| 136 | CGSCCPassManager &getPM() { return PM; } |
||
| 137 | |||
| 138 | /// Add a module pass that runs before the CGSCC passes. |
||
| 139 | template <class T> void addModulePass(T Pass) { |
||
| 140 | MPM.addPass(std::move(Pass)); |
||
| 141 | } |
||
| 142 | |||
| 143 | /// Add a module pass that runs after the CGSCC passes. |
||
| 144 | template <class T> void addLateModulePass(T Pass) { |
||
| 145 | AfterCGMPM.addPass(std::move(Pass)); |
||
| 146 | } |
||
| 147 | |||
| 148 | void printPipeline(raw_ostream &OS, |
||
| 149 | function_ref<StringRef(StringRef)> MapClassName2PassName); |
||
| 150 | |||
| 151 | private: |
||
| 152 | const InlineParams Params; |
||
| 153 | const InlineContext IC; |
||
| 154 | const InliningAdvisorMode Mode; |
||
| 155 | const unsigned MaxDevirtIterations; |
||
| 156 | // TODO: Clean this up so we only have one ModulePassManager. |
||
| 157 | CGSCCPassManager PM; |
||
| 158 | ModulePassManager MPM; |
||
| 159 | ModulePassManager AfterCGMPM; |
||
| 160 | }; |
||
| 161 | } // end namespace llvm |
||
| 162 | |||
| 163 | #endif // LLVM_TRANSFORMS_IPO_INLINER_H |