diff options
| author | Chris Lattner <sabre@nondot.org> | 2004-03-13 23:15:45 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2004-03-13 23:15:45 +0000 | 
| commit | 2dc85b27e4de4e414faab987022f194c98160051 (patch) | |
| tree | 3731660ede8b97a2edfbabee811fb436c470c28e /llvm/lib/Transforms | |
| parent | 797cb2f6c1ddbf4f0bc3e8cf9f6f94cc8a448741 (diff) | |
| download | bcm5719-llvm-2dc85b27e4de4e414faab987022f194c98160051.tar.gz bcm5719-llvm-2dc85b27e4de4e414faab987022f194c98160051.zip | |
This change makes two big adjustments.
 * Be a lot more accurate about what the effects will be when inlining a call
   to a function when an argument is an alloca.
 * Dramatically reduce the penalty for inlining a call in a large function.
   This heuristic made it almost impossible to inline a function into a large
   function, no matter how small the callee is.
llvm-svn: 12363
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/IPO/InlineSimple.cpp | 60 | 
1 files changed, 49 insertions, 11 deletions
| diff --git a/llvm/lib/Transforms/IPO/InlineSimple.cpp b/llvm/lib/Transforms/IPO/InlineSimple.cpp index eec2ebd694a..d28fcbf85d5 100644 --- a/llvm/lib/Transforms/IPO/InlineSimple.cpp +++ b/llvm/lib/Transforms/IPO/InlineSimple.cpp @@ -14,11 +14,20 @@  #include "Inliner.h"  #include "llvm/Instructions.h"  #include "llvm/Function.h" +#include "llvm/Type.h"  #include "llvm/Support/CallSite.h"  #include "llvm/Transforms/IPO.h"  using namespace llvm;  namespace { +  struct ArgInfo { +    unsigned ConstantWeight; +    unsigned AllocaWeight; + +    ArgInfo(unsigned CWeight, unsigned AWeight) +      : ConstantWeight(CWeight), AllocaWeight(AWeight) {} +  }; +    // FunctionInfo - For each function, calculate the size of it in blocks and    // instructions.    struct FunctionInfo { @@ -26,11 +35,11 @@ namespace {      // used to estimate the code size cost of inlining it.      unsigned NumInsts, NumBlocks; -    // ConstantArgumentWeights - Each formal argument of the function is -    // inspected to see if it is used in any contexts where making it a constant +    // ArgumentWeights - Each formal argument of the function is inspected to +    // see if it is used in any contexts where making it a constant or alloca      // would reduce the code size.  If so, we add some value to the argument      // entry here. -    std::vector<unsigned> ConstantArgumentWeights; +    std::vector<ArgInfo> ArgumentWeights;      FunctionInfo() : NumInsts(0), NumBlocks(0) {}    }; @@ -88,6 +97,33 @@ static unsigned CountCodeReductionForConstant(Value *V) {    return Reduction;  } +// CountCodeReductionForAlloca - Figure out an approximation of how much smaller +// the function will be if it is inlined into a context where an argument +// becomes an alloca. +// +static unsigned CountCodeReductionForAlloca(Value *V) { +  if (!isa<PointerType>(V->getType())) return 0;  // Not a pointer +  unsigned Reduction = 0; +  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){ +    Instruction *I = cast<Instruction>(*UI); +    if (isa<LoadInst>(I) || isa<StoreInst>(I)) +      Reduction += 10; +    else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) { +      // If the GEP has variable indices, we won't be able to do much with it. +      for (Instruction::op_iterator I = GEP->op_begin()+1, E = GEP->op_end(); +           I != E; ++I) +        if (!isa<Constant>(*I)) return 0; +      Reduction += CountCodeReductionForAlloca(GEP)+15; +    } else { +      // If there is some other strange instruction, we're not going to be able +      // to do much if we inline this. +      return 0; +    } +  } + +  return Reduction; +} +  // getInlineCost - The heuristic used to determine if we should inline the  // function call or not.  // @@ -131,11 +167,12 @@ int SimpleInliner::getInlineCost(CallSite CS) {      // Check out all of the arguments to the function, figuring out how much      // code can be eliminated if one of the arguments is a constant. -    std::vector<unsigned> &ArgWeights = CalleeFI.ConstantArgumentWeights; +    std::vector<ArgInfo> &ArgWeights = CalleeFI.ArgumentWeights;      for (Function::aiterator I = Callee->abegin(), E = Callee->aend();           I != E; ++I) -      ArgWeights.push_back(CountCodeReductionForConstant(I)); +      ArgWeights.push_back(ArgInfo(CountCodeReductionForConstant(I), +                                   CountCodeReductionForAlloca(I)));    } @@ -161,15 +198,16 @@ int SimpleInliner::getInlineCost(CallSite CS) {      // significant future optimization possibilities (like scalar promotion, and      // scalarization), so encourage the inlining of the function.      // -    else if (isa<AllocaInst>(I)) -      InlineCost -= 60; +    else if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) { +      if (ArgNo < CalleeFI.ArgumentWeights.size()) +        InlineCost -= CalleeFI.ArgumentWeights[ArgNo].AllocaWeight;      // If this is a constant being passed into the function, use the argument      // weights calculated for the callee to determine how much will be folded      // away with this information. -    else if (isa<Constant>(I) || isa<GlobalVariable>(I)) { -      if (ArgNo < CalleeFI.ConstantArgumentWeights.size()) -        InlineCost -= CalleeFI.ConstantArgumentWeights[ArgNo]; +    } else if (isa<Constant>(I) || isa<GlobalVariable>(I)) { +      if (ArgNo < CalleeFI.ArgumentWeights.size()) +        InlineCost -= CalleeFI.ArgumentWeights[ArgNo].ConstantWeight;      }    } @@ -178,7 +216,7 @@ int SimpleInliner::getInlineCost(CallSite CS) {    // Don't inline into something too big, which would make it bigger.  Here, we    // count each basic block as a single unit. -  InlineCost += Caller->size()*2; +  InlineCost += Caller->size()/20;    // Look at the size of the callee.  Each basic block counts as 20 units, and | 

