1 //===- InlineSimple.cpp - Code to perform simple function inlining --------===// 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 // This file implements bottom-up inlining of functions into callees. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Analysis/AssumptionCache.h" 14 #include "llvm/Analysis/InlineCost.h" 15 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 16 #include "llvm/Analysis/TargetTransformInfo.h" 17 #include "llvm/InitializePasses.h" 18 #include "llvm/Transforms/IPO.h" 19 #include "llvm/Transforms/IPO/Inliner.h" 20 21 using namespace llvm; 22 23 #define DEBUG_TYPE "inline" 24 25 namespace { 26 27 /// Actual inliner pass implementation. 28 /// 29 /// The common implementation of the inlining logic is shared between this 30 /// inliner pass and the always inliner pass. The two passes use different cost 31 /// analyses to determine when to inline. 32 class SimpleInliner : public LegacyInlinerBase { 33 34 InlineParams Params; 35 36 public: 37 SimpleInliner() : LegacyInlinerBase(ID), Params(llvm::getInlineParams()) { 38 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); 39 } 40 41 explicit SimpleInliner(InlineParams Params) 42 : LegacyInlinerBase(ID), Params(std::move(Params)) { 43 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); 44 } 45 46 static char ID; // Pass identification, replacement for typeid 47 48 InlineCost getInlineCost(CallBase &CB) override { 49 Function *Callee = CB.getCalledFunction(); 50 TargetTransformInfo &TTI = TTIWP->getTTI(*Callee); 51 52 bool RemarksEnabled = false; 53 const auto &BBs = CB.getCaller()->getBasicBlockList(); 54 if (!BBs.empty()) { 55 auto DI = OptimizationRemark(DEBUG_TYPE, "", DebugLoc(), &BBs.front()); 56 if (DI.isEnabled()) 57 RemarksEnabled = true; 58 } 59 OptimizationRemarkEmitter ORE(CB.getCaller()); 60 61 std::function<AssumptionCache &(Function &)> GetAssumptionCache = 62 [&](Function &F) -> AssumptionCache & { 63 return ACT->getAssumptionCache(F); 64 }; 65 return llvm::getInlineCost(CB, Params, TTI, GetAssumptionCache, GetTLI, 66 /*GetBFI=*/nullptr, PSI, 67 RemarksEnabled ? &ORE : nullptr); 68 } 69 70 bool runOnSCC(CallGraphSCC &SCC) override; 71 void getAnalysisUsage(AnalysisUsage &AU) const override; 72 73 private: 74 TargetTransformInfoWrapperPass *TTIWP; 75 76 }; 77 78 } // end anonymous namespace 79 80 char SimpleInliner::ID = 0; 81 INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", "Function Integration/Inlining", 82 false, false) 83 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) 84 INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) 85 INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) 86 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) 87 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 88 INITIALIZE_PASS_END(SimpleInliner, "inline", "Function Integration/Inlining", 89 false, false) 90 91 Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); } 92 93 Pass *llvm::createFunctionInliningPass(int Threshold) { 94 return new SimpleInliner(llvm::getInlineParams(Threshold)); 95 } 96 97 Pass *llvm::createFunctionInliningPass(unsigned OptLevel, 98 unsigned SizeOptLevel, 99 bool DisableInlineHotCallSite) { 100 auto Param = llvm::getInlineParams(OptLevel, SizeOptLevel); 101 if (DisableInlineHotCallSite) 102 Param.HotCallSiteThreshold = 0; 103 return new SimpleInliner(Param); 104 } 105 106 Pass *llvm::createFunctionInliningPass(InlineParams &Params) { 107 return new SimpleInliner(Params); 108 } 109 110 bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) { 111 TTIWP = &getAnalysis<TargetTransformInfoWrapperPass>(); 112 return LegacyInlinerBase::runOnSCC(SCC); 113 } 114 115 void SimpleInliner::getAnalysisUsage(AnalysisUsage &AU) const { 116 AU.addRequired<TargetTransformInfoWrapperPass>(); 117 LegacyInlinerBase::getAnalysisUsage(AU); 118 } 119