1193323Sed//===- InlineAlways.cpp - Code to inline always_inline functions ----------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements a custom inliner that handles only functions that 11193323Sed// are marked as "always inline". 12193323Sed// 13193323Sed//===----------------------------------------------------------------------===// 14193323Sed 15193323Sed#define DEBUG_TYPE "inline" 16249423Sdim#include "llvm/Transforms/IPO.h" 17249423Sdim#include "llvm/ADT/SmallPtrSet.h" 18193323Sed#include "llvm/Analysis/CallGraph.h" 19198090Srdivacky#include "llvm/Analysis/InlineCost.h" 20249423Sdim#include "llvm/IR/CallingConv.h" 21249423Sdim#include "llvm/IR/DataLayout.h" 22249423Sdim#include "llvm/IR/Instructions.h" 23249423Sdim#include "llvm/IR/IntrinsicInst.h" 24249423Sdim#include "llvm/IR/Module.h" 25249423Sdim#include "llvm/IR/Type.h" 26193323Sed#include "llvm/Support/CallSite.h" 27193323Sed#include "llvm/Transforms/IPO/InlinerPass.h" 28193323Sed 29193323Sedusing namespace llvm; 30193323Sed 31193323Sednamespace { 32193323Sed 33249423Sdim/// \brief Inliner pass which only handles "always inline" functions. 34249423Sdimclass AlwaysInliner : public Inliner { 35249423Sdim InlineCostAnalysis *ICA; 36249423Sdim 37249423Sdimpublic: 38249423Sdim // Use extremely low threshold. 39249423Sdim AlwaysInliner() : Inliner(ID, -2000000000, /*InsertLifetime*/ true), ICA(0) { 40249423Sdim initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry()); 41249423Sdim } 42249423Sdim 43249423Sdim AlwaysInliner(bool InsertLifetime) 44249423Sdim : Inliner(ID, -2000000000, InsertLifetime), ICA(0) { 45249423Sdim initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry()); 46249423Sdim } 47249423Sdim 48249423Sdim static char ID; // Pass identification, replacement for typeid 49249423Sdim 50249423Sdim virtual InlineCost getInlineCost(CallSite CS); 51249423Sdim 52249423Sdim virtual void getAnalysisUsage(AnalysisUsage &AU) const; 53249423Sdim virtual bool runOnSCC(CallGraphSCC &SCC); 54249423Sdim 55249423Sdim using llvm::Pass::doFinalization; 56249423Sdim virtual bool doFinalization(CallGraph &CG) { 57249423Sdim return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/ true); 58249423Sdim } 59249423Sdim}; 60249423Sdim 61193323Sed} 62193323Sed 63193323Sedchar AlwaysInliner::ID = 0; 64218893SdimINITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", 65218893Sdim "Inliner for always_inline functions", false, false) 66263508SdimINITIALIZE_PASS_DEPENDENCY(CallGraph) 67249423SdimINITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) 68218893SdimINITIALIZE_PASS_END(AlwaysInliner, "always-inline", 69218893Sdim "Inliner for always_inline functions", false, false) 70193323Sed 71193323SedPass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); } 72193323Sed 73234353SdimPass *llvm::createAlwaysInlinerPass(bool InsertLifetime) { 74234353Sdim return new AlwaysInliner(InsertLifetime); 75234353Sdim} 76234353Sdim 77234353Sdim/// \brief Get the inline cost for the always-inliner. 78234353Sdim/// 79234353Sdim/// The always inliner *only* handles functions which are marked with the 80234353Sdim/// attribute to force inlining. As such, it is dramatically simpler and avoids 81234353Sdim/// using the powerful (but expensive) inline cost analysis. Instead it uses 82234353Sdim/// a very simple and boring direct walk of the instructions looking for 83234353Sdim/// impossible-to-inline constructs. 84234353Sdim/// 85234353Sdim/// Note, it would be possible to go to some lengths to cache the information 86234353Sdim/// computed here, but as we only expect to do this for relatively few and 87234353Sdim/// small functions which have the explicit attribute to force inlining, it is 88234353Sdim/// likely not worth it in practice. 89234353SdimInlineCost AlwaysInliner::getInlineCost(CallSite CS) { 90234353Sdim Function *Callee = CS.getCalledFunction(); 91234353Sdim 92249423Sdim // Only inline direct calls to functions with always-inline attributes 93249423Sdim // that are viable for inlining. FIXME: We shouldn't even get here for 94249423Sdim // declarations. 95249423Sdim if (Callee && !Callee->isDeclaration() && 96249423Sdim Callee->getAttributes().hasAttribute(AttributeSet::FunctionIndex, 97249423Sdim Attribute::AlwaysInline) && 98249423Sdim ICA->isInlineViable(*Callee)) 99249423Sdim return InlineCost::getAlways(); 100234353Sdim 101249423Sdim return InlineCost::getNever(); 102249423Sdim} 103234353Sdim 104249423Sdimbool AlwaysInliner::runOnSCC(CallGraphSCC &SCC) { 105249423Sdim ICA = &getAnalysis<InlineCostAnalysis>(); 106249423Sdim return Inliner::runOnSCC(SCC); 107234353Sdim} 108234353Sdim 109249423Sdimvoid AlwaysInliner::getAnalysisUsage(AnalysisUsage &AU) const { 110249423Sdim AU.addRequired<InlineCostAnalysis>(); 111249423Sdim Inliner::getAnalysisUsage(AU); 112193323Sed} 113