LLVM API Documentation
00001 //===- InlineSimple.cpp - Code to perform simple function inlining --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements bottom-up inlining of functions into callees. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Transforms/IPO.h" 00015 #include "llvm/Analysis/AliasAnalysis.h" 00016 #include "llvm/Analysis/AssumptionTracker.h" 00017 #include "llvm/Analysis/CallGraph.h" 00018 #include "llvm/Analysis/InlineCost.h" 00019 #include "llvm/IR/CallSite.h" 00020 #include "llvm/IR/CallingConv.h" 00021 #include "llvm/IR/DataLayout.h" 00022 #include "llvm/IR/Instructions.h" 00023 #include "llvm/IR/IntrinsicInst.h" 00024 #include "llvm/IR/Module.h" 00025 #include "llvm/IR/Type.h" 00026 #include "llvm/Transforms/IPO/InlinerPass.h" 00027 00028 using namespace llvm; 00029 00030 #define DEBUG_TYPE "inline" 00031 00032 namespace { 00033 00034 /// \brief Actual inliner pass implementation. 00035 /// 00036 /// The common implementation of the inlining logic is shared between this 00037 /// inliner pass and the always inliner pass. The two passes use different cost 00038 /// analyses to determine when to inline. 00039 class SimpleInliner : public Inliner { 00040 InlineCostAnalysis *ICA; 00041 00042 public: 00043 SimpleInliner() : Inliner(ID), ICA(nullptr) { 00044 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); 00045 } 00046 00047 SimpleInliner(int Threshold) 00048 : Inliner(ID, Threshold, /*InsertLifetime*/ true), ICA(nullptr) { 00049 initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); 00050 } 00051 00052 static char ID; // Pass identification, replacement for typeid 00053 00054 InlineCost getInlineCost(CallSite CS) override { 00055 return ICA->getInlineCost(CS, getInlineThreshold(CS)); 00056 } 00057 00058 bool runOnSCC(CallGraphSCC &SCC) override; 00059 void getAnalysisUsage(AnalysisUsage &AU) const override; 00060 }; 00061 00062 static int computeThresholdFromOptLevels(unsigned OptLevel, 00063 unsigned SizeOptLevel) { 00064 if (OptLevel > 2) 00065 return 275; 00066 if (SizeOptLevel == 1) // -Os 00067 return 75; 00068 if (SizeOptLevel == 2) // -Oz 00069 return 25; 00070 return 225; 00071 } 00072 00073 } // end anonymous namespace 00074 00075 char SimpleInliner::ID = 0; 00076 INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", 00077 "Function Integration/Inlining", false, false) 00078 INITIALIZE_AG_DEPENDENCY(AliasAnalysis) 00079 INITIALIZE_PASS_DEPENDENCY(AssumptionTracker) 00080 INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) 00081 INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) 00082 INITIALIZE_PASS_END(SimpleInliner, "inline", 00083 "Function Integration/Inlining", false, false) 00084 00085 Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); } 00086 00087 Pass *llvm::createFunctionInliningPass(int Threshold) { 00088 return new SimpleInliner(Threshold); 00089 } 00090 00091 Pass *llvm::createFunctionInliningPass(unsigned OptLevel, 00092 unsigned SizeOptLevel) { 00093 return new SimpleInliner( 00094 computeThresholdFromOptLevels(OptLevel, SizeOptLevel)); 00095 } 00096 00097 bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) { 00098 ICA = &getAnalysis<InlineCostAnalysis>(); 00099 return Inliner::runOnSCC(SCC); 00100 } 00101 00102 void SimpleInliner::getAnalysisUsage(AnalysisUsage &AU) const { 00103 AU.addRequired<InlineCostAnalysis>(); 00104 Inliner::getAnalysisUsage(AU); 00105 }