1 //===- InlineSimple.cpp - Code to perform simple function inlining --------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements bottom-up inlining of functions into callees. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/IPO.h" 15 #include "llvm/Analysis/AliasAnalysis.h" 16 #include "llvm/Analysis/CallGraph.h" 17 #include "llvm/Analysis/InlineCost.h" 18 #include "llvm/IR/CallSite.h" 19 #include "llvm/IR/CallingConv.h" 20 #include "llvm/IR/DataLayout.h" 21 #include "llvm/IR/Instructions.h" 22 #include "llvm/IR/IntrinsicInst.h" 23 #include "llvm/IR/Module.h" 24 #include "llvm/IR/Type.h" 25 #include "llvm/Transforms/IPO/InlinerPass.h" 26 27 using namespace llvm; 28 29 #define DEBUG_TYPE "inline" 30 31 namespace { 32 33 /// \brief Actual inliner pass implementation. 34 /// 35 /// The common implementation of the inlining logic is shared between this 36 /// inliner pass and the always inliner pass. The two passes use different cost 37 /// analyses to determine when to inline. 38 class SimpleInliner : public Inliner { 39 InlineCostAnalysis *ICA; 40 41 public: 42 SimpleInliner() : Inliner(ID), ICA(nullptr) { 43 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); 44 } 45 46 SimpleInliner(int Threshold) 47 : Inliner(ID, Threshold, /*InsertLifetime*/ true), ICA(nullptr) { 48 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); 49 } 50 51 static char ID; // Pass identification, replacement for typeid 52 53 InlineCost getInlineCost(CallSite CS) override { 54 return ICA->getInlineCost(CS, getInlineThreshold(CS)); 55 } 56 57 bool runOnSCC(CallGraphSCC &SCC) override; 58 void getAnalysisUsage(AnalysisUsage &AU) const override; 59 }; 60 61 static int computeThresholdFromOptLevels(unsigned OptLevel, 62 unsigned SizeOptLevel) { 63 if (OptLevel > 2) 64 return 275; 65 if (SizeOptLevel == 1) // -Os 66 return 75; 67 if (SizeOptLevel == 2) // -Oz 68 return 25; 69 return 225; 70 } 71 72 } // end anonymous namespace 73 74 char SimpleInliner::ID = 0; 75 INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", 76 "Function Integration/Inlining", false, false) 77 INITIALIZE_AG_DEPENDENCY(AliasAnalysis) 78 INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) 79 INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) 80 INITIALIZE_PASS_END(SimpleInliner, "inline", 81 "Function Integration/Inlining", false, false) 82 83 Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); } 84 85 Pass *llvm::createFunctionInliningPass(int Threshold) { 86 return new SimpleInliner(Threshold); 87 } 88 89 Pass *llvm::createFunctionInliningPass(unsigned OptLevel, 90 unsigned SizeOptLevel) { 91 return new SimpleInliner( 92 computeThresholdFromOptLevels(OptLevel, SizeOptLevel)); 93 } 94 95 bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) { 96 ICA = &getAnalysis<InlineCostAnalysis>(); 97 return Inliner::runOnSCC(SCC); 98 } 99 100 void SimpleInliner::getAnalysisUsage(AnalysisUsage &AU) const { 101 AU.addRequired<InlineCostAnalysis>(); 102 Inliner::getAnalysisUsage(AU); 103 } 104