LLVM API Documentation
00001 //===- InlineAlways.cpp - Code to inline always_inline functions ----------===// 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 a custom inliner that handles only functions that 00011 // are marked as "always inline". 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #define DEBUG_TYPE "inline" 00016 #include "llvm/CallingConv.h" 00017 #include "llvm/Instructions.h" 00018 #include "llvm/IntrinsicInst.h" 00019 #include "llvm/Module.h" 00020 #include "llvm/Type.h" 00021 #include "llvm/Analysis/CallGraph.h" 00022 #include "llvm/Support/CallSite.h" 00023 #include "llvm/Support/Compiler.h" 00024 #include "llvm/Transforms/IPO.h" 00025 #include "llvm/Transforms/IPO/InlinerPass.h" 00026 #include "llvm/Transforms/Utils/InlineCost.h" 00027 #include "llvm/ADT/SmallPtrSet.h" 00028 00029 using namespace llvm; 00030 00031 namespace { 00032 00033 // AlwaysInliner only inlines functions that are mark as "always inline". 00034 class VISIBILITY_HIDDEN AlwaysInliner : public Inliner { 00035 // Functions that are never inlined 00036 SmallPtrSet<const Function*, 16> NeverInline; 00037 InlineCostAnalyzer CA; 00038 public: 00039 // Use extremely low threshold. 00040 AlwaysInliner() : Inliner(&ID, -2000000000) {} 00041 static char ID; // Pass identification, replacement for typeid 00042 InlineCost getInlineCost(CallSite CS) { 00043 return CA.getInlineCost(CS, NeverInline); 00044 } 00045 float getInlineFudgeFactor(CallSite CS) { 00046 return CA.getInlineFudgeFactor(CS); 00047 } 00048 void resetCachedCostInfo(Function *Caller) { 00049 return CA.resetCachedCostInfo(Caller); 00050 } 00051 virtual bool doFinalization(CallGraph &CG) { 00052 return removeDeadFunctions(CG, &NeverInline); 00053 } 00054 virtual bool doInitialization(CallGraph &CG); 00055 }; 00056 } 00057 00058 char AlwaysInliner::ID = 0; 00059 static RegisterPass<AlwaysInliner> 00060 X("always-inline", "Inliner for always_inline functions"); 00061 00062 Pass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); } 00063 00064 // doInitialization - Initializes the vector of functions that have not 00065 // been annotated with the "always inline" attribute. 00066 bool AlwaysInliner::doInitialization(CallGraph &CG) { 00067 Module &M = CG.getModule(); 00068 00069 for (Module::iterator I = M.begin(), E = M.end(); 00070 I != E; ++I) 00071 if (!I->isDeclaration() && !I->hasFnAttr(Attribute::AlwaysInline)) 00072 NeverInline.insert(I); 00073 00074 return false; 00075 }