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) OnlyMandatory(OnlyMandatory)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. getPM()136 CGSCCPassManager &getPM() { return PM; } 137 138 /// Add a module pass that runs before the CGSCC passes. addModulePass(T Pass)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. addLateModulePass(T Pass)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 164