[llvm-commits] [llvm] r40486 - in /llvm/trunk: include/llvm/Transforms/Utils/BasicInliner.h include/llvm/Transforms/Utils/InlineCost.h lib/Transforms/IPO/InlineSimple.cpp lib/Transforms/Utils/BasicInliner.cpp lib/Transforms/Utils/InlineCost.cpp

Devang Patel dpatel at apple.com
Wed Jul 25 11:00:26 PDT 2007


Author: dpatel
Date: Wed Jul 25 13:00:25 2007
New Revision: 40486

URL: http://llvm.org/viewvc/llvm-project?rev=40486&view=rev
Log:
Add BasicInliner interface. 
This interface allows clients to inline bunch of functions with module
level call graph information.:wq


Added:
    llvm/trunk/include/llvm/Transforms/Utils/BasicInliner.h
    llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h
    llvm/trunk/lib/Transforms/Utils/BasicInliner.cpp
    llvm/trunk/lib/Transforms/Utils/InlineCost.cpp
Modified:
    llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp

Added: llvm/trunk/include/llvm/Transforms/Utils/BasicInliner.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/BasicInliner.h?rev=40486&view=auto

==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/BasicInliner.h (added)
+++ llvm/trunk/include/llvm/Transforms/Utils/BasicInliner.h Wed Jul 25 13:00:25 2007
@@ -0,0 +1,55 @@
+//===- BasicInliner.h - Basic function level inliner ------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Devang Patel and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple function based inliner that does not use
+// call graph information. 
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BASICINLINER_H
+#define BASICINLINER_H
+
+#include "llvm/Transforms/Utils/InlineCost.h"
+
+namespace llvm {
+
+  class Function;
+  class TargetData;
+  class BasicInlinerImpl;
+
+  /// BasicInliner - BasicInliner provides function level inlining interface.
+  /// Clients provide list of functions which are inline without using
+  /// module level call graph information. Note that the BasicInliner is
+  /// free to delete a function if it is inlined into all call sites.
+  class BasicInliner {
+  public:
+    
+    BasicInliner(TargetData *T = NULL);
+    ~BasicInliner();
+
+    /// addFunction - Add function into the list of functions to process.
+    /// All functions must be inserted using this interface before invoking
+    /// inlineFunctions().
+    void addFunction(Function *F);
+
+    /// neverInlineFunction - Sometimes a function is never to be inlined 
+    /// because of one or other reason. 
+    void neverInlineFunction(Function *F);
+
+    /// inlineFuctions - Walk all call sites in all functions supplied by
+    /// client. Inline as many call sites as possible. Delete completely
+    /// inlined functions.
+    void inlineFunctions();
+
+  private:
+    BasicInlinerImpl *Impl;
+  };
+}
+
+#endif

Added: llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h?rev=40486&view=auto

==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h (added)
+++ llvm/trunk/include/llvm/Transforms/Utils/InlineCost.h Wed Jul 25 13:00:25 2007
@@ -0,0 +1,80 @@
+//===- InlineCost.cpp - Cost analysis for inliner ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements bottom-up inlining of functions into callees.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INLINECOST_H
+#define INLINECOST_H
+
+#include <set>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+  class Value;
+  class Function;
+  class CallSite;
+
+  /// InlineCostAnalyzer - Cost analyzer used by inliner.
+  class InlineCostAnalyzer {
+    struct ArgInfo {
+    public:
+      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 {
+      // NumInsts, NumBlocks - Keep track of how large each function is, which is
+      // used to estimate the code size cost of inlining it.
+      unsigned NumInsts, NumBlocks;
+      
+      // 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<ArgInfo> ArgumentWeights;
+      
+      FunctionInfo() : NumInsts(0), NumBlocks(0) {}
+      
+      /// analyzeFunction - Fill in the current structure with information gleaned
+      /// from the specified function.
+      void analyzeFunction(Function *F);
+
+      // CountCodeReductionForConstant - Figure out an approximation for how many
+      // instructions will be constant folded if the specified value is constant.
+      //
+      unsigned CountCodeReductionForConstant(Value *V);
+      
+      // 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.
+      //
+      unsigned CountCodeReductionForAlloca(Value *V);
+    };
+
+    std::map<const Function *, FunctionInfo>CachedFunctionInfo;
+
+  public:
+
+    // getInlineCost - The heuristic used to determine if we should inline the
+    // function call or not.
+    //
+    int getInlineCost(CallSite CS, std::set<const Function *> &NeverInline);
+  };
+}
+
+#endif

Modified: llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp?rev=40486&r1=40485&r2=40486&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/InlineSimple.cpp Wed Jul 25 13:00:25 2007
@@ -22,46 +22,22 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/InlinerPass.h"
+#include "llvm/Transforms/Utils/InlineCost.h"
 #include <set>
 
 using namespace llvm;
 
 namespace {
-  struct VISIBILITY_HIDDEN 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 VISIBILITY_HIDDEN FunctionInfo {
-    // NumInsts, NumBlocks - Keep track of how large each function is, which is
-    // used to estimate the code size cost of inlining it.
-    unsigned NumInsts, NumBlocks;
-
-    // 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<ArgInfo> ArgumentWeights;
-
-    FunctionInfo() : NumInsts(0), NumBlocks(0) {}
-
-    /// analyzeFunction - Fill in the current structure with information gleaned
-    /// from the specified function.
-    void analyzeFunction(Function *F);
-  };
 
   class VISIBILITY_HIDDEN SimpleInliner : public Inliner {
-    std::map<const Function*, FunctionInfo> CachedFunctionInfo;
     std::set<const Function*> NeverInline; // Functions that are never inlined
+    InlineCostAnalyzer CA;
   public:
     SimpleInliner() : Inliner(&ID) {}
     static char ID; // Pass identification, replacement for typeid
-    int getInlineCost(CallSite CS);
+    int getInlineCost(CallSite CS) {
+      return CA.getInlineCost(CS, NeverInline);
+    }
     virtual bool doInitialization(CallGraph &CG);
   };
   char SimpleInliner::ID = 0;
@@ -70,223 +46,6 @@
 
 Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
 
-// CountCodeReductionForConstant - Figure out an approximation for how many
-// instructions will be constant folded if the specified value is constant.
-//
-static unsigned CountCodeReductionForConstant(Value *V) {
-  unsigned Reduction = 0;
-  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
-    if (isa<BranchInst>(*UI))
-      Reduction += 40;          // Eliminating a conditional branch is a big win
-    else if (SwitchInst *SI = dyn_cast<SwitchInst>(*UI))
-      // Eliminating a switch is a big win, proportional to the number of edges
-      // deleted.
-      Reduction += (SI->getNumSuccessors()-1) * 40;
-    else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
-      // Turning an indirect call into a direct call is a BIG win
-      Reduction += CI->getCalledValue() == V ? 500 : 0;
-    } else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
-      // Turning an indirect call into a direct call is a BIG win
-      Reduction += II->getCalledValue() == V ? 500 : 0;
-    } else {
-      // Figure out if this instruction will be removed due to simple constant
-      // propagation.
-      Instruction &Inst = cast<Instruction>(**UI);
-      bool AllOperandsConstant = true;
-      for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
-        if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
-          AllOperandsConstant = false;
-          break;
-        }
-
-      if (AllOperandsConstant) {
-        // We will get to remove this instruction...
-        Reduction += 7;
-
-        // And any other instructions that use it which become constants
-        // themselves.
-        Reduction += CountCodeReductionForConstant(&Inst);
-      }
-    }
-
-  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;
-}
-
-/// analyzeFunction - Fill in the current structure with information gleaned
-/// from the specified function.
-void FunctionInfo::analyzeFunction(Function *F) {
-  unsigned NumInsts = 0, NumBlocks = 0;
-
-  // Look at the size of the callee.  Each basic block counts as 20 units, and
-  // each instruction counts as 10.
-  for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
-    for (BasicBlock::const_iterator II = BB->begin(), E = BB->end();
-         II != E; ++II) {
-      if (isa<DbgInfoIntrinsic>(II)) continue;  // Debug intrinsics don't count.
-      
-      // Noop casts, including ptr <-> int,  don't count.
-      if (const CastInst *CI = dyn_cast<CastInst>(II)) {
-        if (CI->isLosslessCast() || isa<IntToPtrInst>(CI) || 
-            isa<PtrToIntInst>(CI))
-          continue;
-      } else if (const GetElementPtrInst *GEPI =
-                         dyn_cast<GetElementPtrInst>(II)) {
-        // If a GEP has all constant indices, it will probably be folded with
-        // a load/store.
-        bool AllConstant = true;
-        for (unsigned i = 1, e = GEPI->getNumOperands(); i != e; ++i)
-          if (!isa<ConstantInt>(GEPI->getOperand(i))) {
-            AllConstant = false;
-            break;
-          }
-        if (AllConstant) continue;
-      }
-      
-      ++NumInsts;
-    }
-
-    ++NumBlocks;
-  }
-
-  this->NumBlocks = NumBlocks;
-  this->NumInsts  = NumInsts;
-
-  // 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.
-  for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
-    ArgumentWeights.push_back(ArgInfo(CountCodeReductionForConstant(I),
-                                      CountCodeReductionForAlloca(I)));
-}
-
-
-// getInlineCost - The heuristic used to determine if we should inline the
-// function call or not.
-//
-int SimpleInliner::getInlineCost(CallSite CS) {
-  Instruction *TheCall = CS.getInstruction();
-  Function *Callee = CS.getCalledFunction();
-  const Function *Caller = TheCall->getParent()->getParent();
-
-  // Don't inline a directly recursive call.
-  if (Caller == Callee ||
-      // Don't inline functions which can be redefined at link-time to mean
-      // something else.  link-once linkage is ok though.
-      Callee->hasWeakLinkage() ||
-      
-      // Don't inline functions marked noinline.
-      NeverInline.count(Callee))
-    return 2000000000;
-  
-  // InlineCost - This value measures how good of an inline candidate this call
-  // site is to inline.  A lower inline cost make is more likely for the call to
-  // be inlined.  This value may go negative.
-  //
-  int InlineCost = 0;
-
-  // If there is only one call of the function, and it has internal linkage,
-  // make it almost guaranteed to be inlined.
-  //
-  if (Callee->hasInternalLinkage() && Callee->hasOneUse())
-    InlineCost -= 30000;
-
-  // If this function uses the coldcc calling convention, prefer not to inline
-  // it.
-  if (Callee->getCallingConv() == CallingConv::Cold)
-    InlineCost += 2000;
-
-  // If the instruction after the call, or if the normal destination of the
-  // invoke is an unreachable instruction, the function is noreturn.  As such,
-  // there is little point in inlining this.
-  if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
-    if (isa<UnreachableInst>(II->getNormalDest()->begin()))
-      InlineCost += 10000;
-  } else if (isa<UnreachableInst>(++BasicBlock::iterator(TheCall)))
-    InlineCost += 10000;
-
-  // Get information about the callee...
-  FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
-
-  // If we haven't calculated this information yet, do so now.
-  if (CalleeFI.NumBlocks == 0)
-    CalleeFI.analyzeFunction(Callee);
-
-  // Add to the inline quality for properties that make the call valuable to
-  // inline.  This includes factors that indicate that the result of inlining
-  // the function will be optimizable.  Currently this just looks at arguments
-  // passed into the function.
-  //
-  unsigned ArgNo = 0;
-  for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
-       I != E; ++I, ++ArgNo) {
-    // Each argument passed in has a cost at both the caller and the callee
-    // sides.  This favors functions that take many arguments over functions
-    // that take few arguments.
-    InlineCost -= 20;
-
-    // If this is a function being passed in, it is very likely that we will be
-    // able to turn an indirect function call into a direct function call.
-    if (isa<Function>(I))
-      InlineCost -= 100;
-
-    // If an alloca is passed in, inlining this function is likely to allow
-    // significant future optimization possibilities (like scalar promotion, and
-    // scalarization), so encourage the inlining of the function.
-    //
-    else if (isa<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)) {
-      if (ArgNo < CalleeFI.ArgumentWeights.size())
-        InlineCost -= CalleeFI.ArgumentWeights[ArgNo].ConstantWeight;
-    }
-  }
-
-  // Now that we have considered all of the factors that make the call site more
-  // likely to be inlined, look at factors that make us not want to inline it.
-
-  // 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()/20;
-
-
-  // Look at the size of the callee.  Each basic block counts as 20 units, and
-  // each instruction counts as 5.
-  InlineCost += CalleeFI.NumInsts*5 + CalleeFI.NumBlocks*20;
-  return InlineCost;
-}
-
 // doInitialization - Initializes the vector of functions that have been
 // annotated with the noinline attribute.
 bool SimpleInliner::doInitialization(CallGraph &CG) {
@@ -321,3 +80,4 @@
   
   return false;
 }
+

Added: llvm/trunk/lib/Transforms/Utils/BasicInliner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/BasicInliner.cpp?rev=40486&view=auto

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/BasicInliner.cpp (added)
+++ llvm/trunk/lib/Transforms/Utils/BasicInliner.cpp Wed Jul 25 13:00:25 2007
@@ -0,0 +1,171 @@
+//===- BasicInliner.cpp - Basic function level inliner --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Devang Patel and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple function based inliner that does not use
+// call graph information. 
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "basicinliner"
+
+#include "llvm/Module.h"
+#include "llvm/Function.h"
+#include "llvm/Transforms/Utils/BasicInliner.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <vector>
+#include <set>
+
+using namespace llvm;
+
+namespace {
+  cl::opt<unsigned>     
+  BasicInlineThreshold("inline-threshold", cl::Hidden, cl::init(200),
+                       cl::desc("Control the amount of basic inlining to perform (default = 200)"));
+}
+
+namespace llvm {
+
+  /// BasicInlinerImpl - BasicInliner implemantation class. This hides
+  /// container info, used by basic inliner, from public interface.
+  struct VISIBILITY_HIDDEN BasicInlinerImpl {
+    
+    BasicInlinerImpl(const BasicInlinerImpl&); // DO NOT IMPLEMENT
+    void operator=(const BasicInlinerImpl&); // DO NO IMPLEMENT
+  public:
+    BasicInlinerImpl(TargetData *T) : TD(T) {}
+
+    /// addFunction - Add function into the list of functions to process.
+    /// All functions must be inserted using this interface before invoking
+    /// inlineFunctions().
+    void addFunction(Function *F) {
+      Functions.push_back(F);
+    }
+
+    /// neverInlineFunction - Sometimes a function is never to be inlined 
+    /// because of one or other reason. 
+    void neverInlineFunction(Function *F) {
+      NeverInline.insert(F);
+    }
+
+    /// inlineFuctions - Walk all call sites in all functions supplied by
+    /// client. Inline as many call sites as possible. Delete completely
+    /// inlined functions.
+    void inlineFunctions();
+    
+  private:
+    TargetData *TD;
+    std::vector<Function *> Functions;
+    std::set<const Function *> NeverInline;
+    SmallPtrSet<Function *, 8> DeadFunctions;
+    InlineCostAnalyzer CA;
+  };
+
+/// inlineFuctions - Walk all call sites in all functions supplied by
+/// client. Inline as many call sites as possible. Delete completely
+/// inlined functions.
+void BasicInlinerImpl::inlineFunctions() {
+      
+  // Scan through and identify all call sites ahead of time so that we only
+  // inline call sites in the original functions, not call sites that result
+  // from inlining other functions.
+  std::vector<CallSite> CallSites;
+  
+  for (std::vector<Function *>::iterator FI = Functions.begin(),
+         FE = Functions.end(); FI != FE; ++FI) {
+    Function *F = *FI;
+    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+      for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
+        CallSite CS = CallSite::get(I);
+        if (CS.getInstruction() && CS.getCalledFunction()
+            && !CS.getCalledFunction()->isDeclaration())
+          CallSites.push_back(CS);
+      }
+  }
+  
+  DOUT << ": " << CallSites.size() << " call sites.\n";
+  
+  // Inline call sites.
+  bool Changed = false;
+  do {
+    Changed = false;
+    for (unsigned index = 0; index != CallSites.size() && !CallSites.empty(); ++index) {
+      CallSite CS = CallSites[index];
+      if (Function *Callee = CS.getCalledFunction()) {
+        
+        // Eliminate calls taht are never inlinable.
+        if (Callee->isDeclaration() ||
+            CS.getInstruction()->getParent()->getParent() == Callee) {
+          CallSites.erase(CallSites.begin() + index);
+              --index;
+              continue;
+        }
+        int InlineCost = CA.getInlineCost(CS, NeverInline);
+        if (InlineCost >= (int) BasicInlineThreshold) {
+              DOUT << "  NOT Inlining: cost = " << InlineCost
+                   << ", call: " <<  *CS.getInstruction();
+              continue;
+        }
+        
+        DOUT << "  Inlining: cost=" << InlineCost
+             <<", call: " << *CS.getInstruction();
+        
+        // Inline
+        if (InlineFunction(CS, NULL, TD)) {
+          if (Callee->use_empty() && Callee->hasInternalLinkage())
+                DeadFunctions.insert(Callee);
+          Changed = true;
+          CallSites.erase(CallSites.begin() + index);
+          --index;
+        }
+      }
+    }
+  } while (Changed);
+  
+  // Remove completely inlined functions from module.
+  for(SmallPtrSet<Function *, 8>::iterator I = DeadFunctions.begin(),
+        E = DeadFunctions.end(); I != E; ++I) {
+    Function *D = *I;
+    Module *M = D->getParent();
+    M->getFunctionList().remove(D);
+  }
+}
+
+BasicInliner::BasicInliner(TargetData *TD) {
+  Impl = new BasicInlinerImpl(TD);
+}
+
+BasicInliner::~BasicInliner() {
+  delete Impl;
+}
+
+/// addFunction - Add function into the list of functions to process.
+/// All functions must be inserted using this interface before invoking
+/// inlineFunctions().
+void BasicInliner::addFunction(Function *F) {
+  Impl->addFunction(F);
+}
+
+/// neverInlineFunction - Sometimes a function is never to be inlined because
+/// of one or other reason. 
+void BasicInliner::neverInlineFunction(Function *F) {
+  Impl->neverInlineFunction(F);
+}
+
+/// inlineFuctions - Walk all call sites in all functions supplied by
+/// client. Inline as many call sites as possible. Delete completely
+/// inlined functions.
+void BasicInliner::inlineFunctions() {
+  Impl->inlineFunctions();
+}
+
+}

Added: llvm/trunk/lib/Transforms/Utils/InlineCost.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineCost.cpp?rev=40486&view=auto

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InlineCost.cpp (added)
+++ llvm/trunk/lib/Transforms/Utils/InlineCost.cpp Wed Jul 25 13:00:25 2007
@@ -0,0 +1,241 @@
+//===- InlineCoast.cpp - Cost analysis for inliner ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements inline cost analysis.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "llvm/Transforms/Utils/InlineCost.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/CallingConv.h"
+#include "llvm/IntrinsicInst.h"
+
+using namespace llvm;
+
+// CountCodeReductionForConstant - Figure out an approximation for how many
+// instructions will be constant folded if the specified value is constant.
+//
+unsigned InlineCostAnalyzer::FunctionInfo::
+         CountCodeReductionForConstant(Value *V) {
+  unsigned Reduction = 0;
+  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
+    if (isa<BranchInst>(*UI))
+      Reduction += 40;          // Eliminating a conditional branch is a big win
+    else if (SwitchInst *SI = dyn_cast<SwitchInst>(*UI))
+      // Eliminating a switch is a big win, proportional to the number of edges
+      // deleted.
+      Reduction += (SI->getNumSuccessors()-1) * 40;
+    else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
+      // Turning an indirect call into a direct call is a BIG win
+      Reduction += CI->getCalledValue() == V ? 500 : 0;
+    } else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
+      // Turning an indirect call into a direct call is a BIG win
+      Reduction += II->getCalledValue() == V ? 500 : 0;
+    } else {
+      // Figure out if this instruction will be removed due to simple constant
+      // propagation.
+      Instruction &Inst = cast<Instruction>(**UI);
+      bool AllOperandsConstant = true;
+      for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
+        if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
+          AllOperandsConstant = false;
+          break;
+        }
+
+      if (AllOperandsConstant) {
+        // We will get to remove this instruction...
+        Reduction += 7;
+
+        // And any other instructions that use it which become constants
+        // themselves.
+        Reduction += CountCodeReductionForConstant(&Inst);
+      }
+    }
+
+  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.
+//
+unsigned InlineCostAnalyzer::FunctionInfo::
+         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;
+}
+
+/// analyzeFunction - Fill in the current structure with information gleaned
+/// from the specified function.
+void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
+  unsigned NumInsts = 0, NumBlocks = 0;
+
+  // Look at the size of the callee.  Each basic block counts as 20 units, and
+  // each instruction counts as 10.
+  for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
+    for (BasicBlock::const_iterator II = BB->begin(), E = BB->end();
+         II != E; ++II) {
+      if (isa<DbgInfoIntrinsic>(II)) continue;  // Debug intrinsics don't count.
+      
+      // Noop casts, including ptr <-> int,  don't count.
+      if (const CastInst *CI = dyn_cast<CastInst>(II)) {
+        if (CI->isLosslessCast() || isa<IntToPtrInst>(CI) || 
+            isa<PtrToIntInst>(CI))
+          continue;
+      } else if (const GetElementPtrInst *GEPI =
+                         dyn_cast<GetElementPtrInst>(II)) {
+        // If a GEP has all constant indices, it will probably be folded with
+        // a load/store.
+        bool AllConstant = true;
+        for (unsigned i = 1, e = GEPI->getNumOperands(); i != e; ++i)
+          if (!isa<ConstantInt>(GEPI->getOperand(i))) {
+            AllConstant = false;
+            break;
+          }
+        if (AllConstant) continue;
+      }
+      
+      ++NumInsts;
+    }
+
+    ++NumBlocks;
+  }
+
+  this->NumBlocks = NumBlocks;
+  this->NumInsts  = NumInsts;
+
+  // 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.
+  for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+    ArgumentWeights.push_back(ArgInfo(CountCodeReductionForConstant(I),
+                                      CountCodeReductionForAlloca(I)));
+}
+
+
+
+// getInlineCost - The heuristic used to determine if we should inline the
+// function call or not.
+//
+int InlineCostAnalyzer::getInlineCost(CallSite CS, std::set<const Function *> &NeverInline) {
+  Instruction *TheCall = CS.getInstruction();
+  Function *Callee = CS.getCalledFunction();
+  const Function *Caller = TheCall->getParent()->getParent();
+  
+  // Don't inline a directly recursive call.
+  if (Caller == Callee ||
+      // Don't inline functions which can be redefined at link-time to mean
+      // something else.  link-once linkage is ok though.
+      Callee->hasWeakLinkage() ||
+      
+      // Don't inline functions marked noinline.
+      NeverInline.count(Callee))
+    return 2000000000;
+  
+  // InlineCost - This value measures how good of an inline candidate this call
+  // site is to inline.  A lower inline cost make is more likely for the call to
+  // be inlined.  This value may go negative.
+  //
+  int InlineCost = 0;
+  
+  // If there is only one call of the function, and it has internal linkage,
+  // make it almost guaranteed to be inlined.
+  //
+  if (Callee->hasInternalLinkage() && Callee->hasOneUse())
+    InlineCost -= 30000;
+  
+  // If this function uses the coldcc calling convention, prefer not to inline
+  // it.
+  if (Callee->getCallingConv() == CallingConv::Cold)
+    InlineCost += 2000;
+  
+  // If the instruction after the call, or if the normal destination of the
+  // invoke is an unreachable instruction, the function is noreturn.  As such,
+  // there is little point in inlining this.
+  if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
+    if (isa<UnreachableInst>(II->getNormalDest()->begin()))
+      InlineCost += 10000;
+  } else if (isa<UnreachableInst>(++BasicBlock::iterator(TheCall)))
+    InlineCost += 10000;
+  
+  // Get information about the callee...
+  FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
+  
+  // If we haven't calculated this information yet, do so now.
+  if (CalleeFI.NumBlocks == 0)
+    CalleeFI.analyzeFunction(Callee);
+    
+  // Add to the inline quality for properties that make the call valuable to
+  // inline.  This includes factors that indicate that the result of inlining
+  // the function will be optimizable.  Currently this just looks at arguments
+  // passed into the function.
+  //
+  unsigned ArgNo = 0;
+  for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
+       I != E; ++I, ++ArgNo) {
+    // Each argument passed in has a cost at both the caller and the callee
+    // sides.  This favors functions that take many arguments over functions
+    // that take few arguments.
+    InlineCost -= 20;
+    
+    // If this is a function being passed in, it is very likely that we will be
+    // able to turn an indirect function call into a direct function call.
+    if (isa<Function>(I))
+      InlineCost -= 100;
+    
+    // If an alloca is passed in, inlining this function is likely to allow
+    // significant future optimization possibilities (like scalar promotion, and
+    // scalarization), so encourage the inlining of the function.
+    //
+    else if (isa<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)) {
+      if (ArgNo < CalleeFI.ArgumentWeights.size())
+        InlineCost -= CalleeFI.ArgumentWeights[ArgNo].ConstantWeight;
+    }
+  }
+  
+  // Now that we have considered all of the factors that make the call site more
+  // likely to be inlined, look at factors that make us not want to inline it.
+  
+  // 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()/20;
+  
+  
+  // Look at the size of the callee.  Each basic block counts as 20 units, and
+  // each instruction counts as 5.
+  InlineCost += CalleeFI.NumInsts*5 + CalleeFI.NumBlocks*20;
+  return InlineCost;
+}
+





More information about the llvm-commits mailing list