LLVM API Documentation

InlineAlways.cpp

Go to the documentation of this file.
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 }