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 #include "llvm/Transforms/IPO.h" 00016 #include "llvm/ADT/SmallPtrSet.h" 00017 #include "llvm/Analysis/AliasAnalysis.h" 00018 #include "llvm/Analysis/AssumptionTracker.h" 00019 #include "llvm/Analysis/CallGraph.h" 00020 #include "llvm/Analysis/InlineCost.h" 00021 #include "llvm/IR/CallSite.h" 00022 #include "llvm/IR/CallingConv.h" 00023 #include "llvm/IR/DataLayout.h" 00024 #include "llvm/IR/Instructions.h" 00025 #include "llvm/IR/IntrinsicInst.h" 00026 #include "llvm/IR/Module.h" 00027 #include "llvm/IR/Type.h" 00028 #include "llvm/Transforms/IPO/InlinerPass.h" 00029 00030 using namespace llvm; 00031 00032 #define DEBUG_TYPE "inline" 00033 00034 namespace { 00035 00036 /// \brief Inliner pass which only handles "always inline" functions. 00037 class AlwaysInliner : public Inliner { 00038 InlineCostAnalysis *ICA; 00039 00040 public: 00041 // Use extremely low threshold. 00042 AlwaysInliner() : Inliner(ID, -2000000000, /*InsertLifetime*/ true), 00043 ICA(nullptr) { 00044 initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry()); 00045 } 00046 00047 AlwaysInliner(bool InsertLifetime) 00048 : Inliner(ID, -2000000000, InsertLifetime), ICA(nullptr) { 00049 initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry()); 00050 } 00051 00052 static char ID; // Pass identification, replacement for typeid 00053 00054 InlineCost getInlineCost(CallSite CS) override; 00055 00056 void getAnalysisUsage(AnalysisUsage &AU) const override; 00057 bool runOnSCC(CallGraphSCC &SCC) override; 00058 00059 using llvm::Pass::doFinalization; 00060 bool doFinalization(CallGraph &CG) override { 00061 return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/ true); 00062 } 00063 }; 00064 00065 } 00066 00067 char AlwaysInliner::ID = 0; 00068 INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", 00069 "Inliner for always_inline functions", false, false) 00070 INITIALIZE_AG_DEPENDENCY(AliasAnalysis) 00071 INITIALIZE_PASS_DEPENDENCY(AssumptionTracker) 00072 INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) 00073 INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) 00074 INITIALIZE_PASS_END(AlwaysInliner, "always-inline", 00075 "Inliner for always_inline functions", false, false) 00076 00077 Pass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); } 00078 00079 Pass *llvm::createAlwaysInlinerPass(bool InsertLifetime) { 00080 return new AlwaysInliner(InsertLifetime); 00081 } 00082 00083 /// \brief Get the inline cost for the always-inliner. 00084 /// 00085 /// The always inliner *only* handles functions which are marked with the 00086 /// attribute to force inlining. As such, it is dramatically simpler and avoids 00087 /// using the powerful (but expensive) inline cost analysis. Instead it uses 00088 /// a very simple and boring direct walk of the instructions looking for 00089 /// impossible-to-inline constructs. 00090 /// 00091 /// Note, it would be possible to go to some lengths to cache the information 00092 /// computed here, but as we only expect to do this for relatively few and 00093 /// small functions which have the explicit attribute to force inlining, it is 00094 /// likely not worth it in practice. 00095 InlineCost AlwaysInliner::getInlineCost(CallSite CS) { 00096 Function *Callee = CS.getCalledFunction(); 00097 00098 // Only inline direct calls to functions with always-inline attributes 00099 // that are viable for inlining. FIXME: We shouldn't even get here for 00100 // declarations. 00101 if (Callee && !Callee->isDeclaration() && 00102 CS.hasFnAttr(Attribute::AlwaysInline) && 00103 ICA->isInlineViable(*Callee)) 00104 return InlineCost::getAlways(); 00105 00106 return InlineCost::getNever(); 00107 } 00108 00109 bool AlwaysInliner::runOnSCC(CallGraphSCC &SCC) { 00110 ICA = &getAnalysis<InlineCostAnalysis>(); 00111 return Inliner::runOnSCC(SCC); 00112 } 00113 00114 void AlwaysInliner::getAnalysisUsage(AnalysisUsage &AU) const { 00115 AU.addRequired<InlineCostAnalysis>(); 00116 Inliner::getAnalysisUsage(AU); 00117 }