InlineAlways.cpp revision 212904
1//===- InlineAlways.cpp - Code to inline always_inline functions ----------===// 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 a custom inliner that handles only functions that 11// are marked as "always inline". 12// 13//===----------------------------------------------------------------------===// 14 15#define DEBUG_TYPE "inline" 16#include "llvm/CallingConv.h" 17#include "llvm/Instructions.h" 18#include "llvm/IntrinsicInst.h" 19#include "llvm/Module.h" 20#include "llvm/Type.h" 21#include "llvm/Analysis/CallGraph.h" 22#include "llvm/Analysis/InlineCost.h" 23#include "llvm/Support/CallSite.h" 24#include "llvm/Transforms/IPO.h" 25#include "llvm/Transforms/IPO/InlinerPass.h" 26#include "llvm/ADT/SmallPtrSet.h" 27 28using namespace llvm; 29 30namespace { 31 32 // AlwaysInliner only inlines functions that are mark as "always inline". 33 class AlwaysInliner : public Inliner { 34 // Functions that are never inlined 35 SmallPtrSet<const Function*, 16> NeverInline; 36 InlineCostAnalyzer CA; 37 public: 38 // Use extremely low threshold. 39 AlwaysInliner() : Inliner(ID, -2000000000) {} 40 static char ID; // Pass identification, replacement for typeid 41 InlineCost getInlineCost(CallSite CS) { 42 return CA.getInlineCost(CS, NeverInline); 43 } 44 float getInlineFudgeFactor(CallSite CS) { 45 return CA.getInlineFudgeFactor(CS); 46 } 47 void resetCachedCostInfo(Function *Caller) { 48 CA.resetCachedCostInfo(Caller); 49 } 50 void growCachedCostInfo(Function* Caller, Function* Callee) { 51 CA.growCachedCostInfo(Caller, Callee); 52 } 53 virtual bool doFinalization(CallGraph &CG) { 54 return removeDeadFunctions(CG, &NeverInline); 55 } 56 virtual bool doInitialization(CallGraph &CG); 57 void releaseMemory() { 58 CA.clear(); 59 } 60 }; 61} 62 63char AlwaysInliner::ID = 0; 64INITIALIZE_PASS(AlwaysInliner, "always-inline", 65 "Inliner for always_inline functions", false, false); 66 67Pass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); } 68 69// doInitialization - Initializes the vector of functions that have not 70// been annotated with the "always inline" attribute. 71bool AlwaysInliner::doInitialization(CallGraph &CG) { 72 Module &M = CG.getModule(); 73 74 for (Module::iterator I = M.begin(), E = M.end(); 75 I != E; ++I) 76 if (!I->isDeclaration() && !I->hasFnAttr(Attribute::AlwaysInline)) 77 NeverInline.insert(I); 78 79 return false; 80} 81