X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FInlineSimple.cpp;h=9b01d81b3c7c1ac8596e0d9e4a6c955e46bb66fa;hb=0e2c9c8c4ad6d658fd8f61896e5a9ff5d445a2b0;hp=8ae5235383360ca2f77351c21c23a94b6d33a132;hpb=c5e1ec47c719806fcc882470595960512edc7441;p=oota-llvm.git diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp index 8ae52353833..9b01d81b3c7 100644 --- a/lib/Transforms/IPO/InlineSimple.cpp +++ b/lib/Transforms/IPO/InlineSimple.cpp @@ -11,93 +11,95 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "inline" -#include "llvm/CallingConv.h" -#include "llvm/Instructions.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/Analysis/CallGraph.h" -#include "llvm/Support/CallSite.h" -#include "llvm/Support/Compiler.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/InlineCost.h" +#include "llvm/IR/CallSite.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" #include "llvm/Transforms/IPO/InlinerPass.h" -#include "llvm/Transforms/Utils/InlineCost.h" -#include "llvm/ADT/SmallPtrSet.h" using namespace llvm; +#define DEBUG_TYPE "inline" + namespace { - class VISIBILITY_HIDDEN SimpleInliner : public Inliner { - // Functions that are never inlined - SmallPtrSet NeverInline; - InlineCostAnalyzer CA; - public: - SimpleInliner() : Inliner(&ID) {} - SimpleInliner(int Threshold) : Inliner(&ID, Threshold) {} - static char ID; // Pass identification, replacement for typeid - InlineCost getInlineCost(CallSite CS) { - return CA.getInlineCost(CS, NeverInline); - } - float getInlineFudgeFactor(CallSite CS) { - return CA.getInlineFudgeFactor(CS); - } - virtual bool doInitialization(CallGraph &CG); - }; +/// \brief Actual inliner pass implementation. +/// +/// The common implementation of the inlining logic is shared between this +/// inliner pass and the always inliner pass. The two passes use different cost +/// analyses to determine when to inline. +class SimpleInliner : public Inliner { + InlineCostAnalysis *ICA; + +public: + SimpleInliner() : Inliner(ID), ICA(nullptr) { + initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); + } + + SimpleInliner(int Threshold) + : Inliner(ID, Threshold, /*InsertLifetime*/ true), ICA(nullptr) { + initializeSimpleInlinerPass(*PassRegistry::getPassRegistry()); + } + + static char ID; // Pass identification, replacement for typeid + + InlineCost getInlineCost(CallSite CS) override { + return ICA->getInlineCost(CS, getInlineThreshold(CS)); + } + + bool runOnSCC(CallGraphSCC &SCC) override; + void getAnalysisUsage(AnalysisUsage &AU) const override; +}; + +static int computeThresholdFromOptLevels(unsigned OptLevel, + unsigned SizeOptLevel) { + if (OptLevel > 2) + return 275; + if (SizeOptLevel == 1) // -Os + return 75; + if (SizeOptLevel == 2) // -Oz + return 25; + return 225; } +} // end anonymous namespace + char SimpleInliner::ID = 0; -static RegisterPass -X("inline", "Function Integration/Inlining"); +INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", + "Function Integration/Inlining", false, false) +INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) +INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) +INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) +INITIALIZE_PASS_END(SimpleInliner, "inline", + "Function Integration/Inlining", false, false) Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); } -Pass *llvm::createFunctionInliningPass(int Threshold) { +Pass *llvm::createFunctionInliningPass(int Threshold) { return new SimpleInliner(Threshold); } -// doInitialization - Initializes the vector of functions that have been -// annotated with the noinline attribute. -bool SimpleInliner::doInitialization(CallGraph &CG) { - - Module &M = CG.getModule(); - - for (Module::iterator I = M.begin(), E = M.end(); - I != E; ++I) - if (!I->isDeclaration() && I->hasFnAttr(Attribute::NoInline)) - NeverInline.insert(I); - - // Get llvm.noinline - GlobalVariable *GV = M.getNamedGlobal("llvm.noinline"); - - if (GV == 0) - return false; - - // Don't crash on invalid code - if (!GV->hasInitializer()) - return false; - - const ConstantArray *InitList = dyn_cast(GV->getInitializer()); - - if (InitList == 0) - return false; - - // Iterate over each element and add to the NeverInline set - for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { - - // Get Source - const Constant *Elt = InitList->getOperand(i); - - if (const ConstantExpr *CE = dyn_cast(Elt)) - if (CE->getOpcode() == Instruction::BitCast) - Elt = CE->getOperand(0); - - // Insert into set of functions to never inline - if (const Function *F = dyn_cast(Elt)) - NeverInline.insert(F); - } - - return false; +Pass *llvm::createFunctionInliningPass(unsigned OptLevel, + unsigned SizeOptLevel) { + return new SimpleInliner( + computeThresholdFromOptLevels(OptLevel, SizeOptLevel)); +} + +bool SimpleInliner::runOnSCC(CallGraphSCC &SCC) { + ICA = &getAnalysis(); + return Inliner::runOnSCC(SCC); } +void SimpleInliner::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + Inliner::getAnalysisUsage(AU); +}