Implement bitfield clears
[oota-llvm.git] / lib / Transforms / IPO / InlineSimple.cpp
index d28fcbf85d5495351e683a5b0acb3c7e172786a2..4355c6c4a19faa95fa3823a7ae9d76c8a3f1fff6 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "Inliner.h"
 #include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
 #include "llvm/Function.h"
 #include "llvm/Type.h"
 #include "llvm/Support/CallSite.h"
@@ -31,6 +32,16 @@ namespace {
   // FunctionInfo - For each function, calculate the size of it in blocks and
   // instructions.
   struct FunctionInfo {
+    // HasAllocas - Keep track of whether or not a function contains an alloca
+    // instruction that is not in the entry block of the function.  Inlining
+    // this call could cause us to blow out the stack, because the stack memory
+    // would never be released.
+    //
+    // FIXME: LLVM needs a way of dealloca'ing memory, which would make this
+    // irrelevant!
+    //
+    bool HasAllocas;
+
     // 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;
@@ -41,7 +52,11 @@ namespace {
     // entry here.
     std::vector<ArgInfo> ArgumentWeights;
 
-    FunctionInfo() : NumInsts(0), NumBlocks(0) {}
+    FunctionInfo() : HasAllocas(false), NumInsts(0), NumBlocks(0) {}
+
+    /// analyzeFunction - Fill in the current structure with information gleaned
+    /// from the specified function.
+    void analyzeFunction(Function *F);
   };
 
   class SimpleInliner : public Inliner {
@@ -52,7 +67,7 @@ namespace {
   RegisterOpt<SimpleInliner> X("inline", "Function Integration/Inlining");
 }
 
-Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
+ModulePass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
 
 // CountCodeReductionForConstant - Figure out an approximation for how many
 // instructions will be constant folded if the specified value is constant.
@@ -78,8 +93,7 @@ static unsigned CountCodeReductionForConstant(Value *V) {
       Instruction &Inst = cast<Instruction>(**UI);
       bool AllOperandsConstant = true;
       for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
-        if (!isa<Constant>(Inst.getOperand(i)) &&
-            !isa<GlobalValue>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
+        if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
           AllOperandsConstant = false;
           break;
         }
@@ -124,6 +138,41 @@ static unsigned CountCodeReductionForAlloca(Value *V) {
   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)) ++NumInsts;
+
+      // If there is an alloca in the body of the function, we cannot currently
+      // inline the function without the risk of exploding the stack.
+      if (isa<AllocaInst>(II) && BB != F->begin()) {
+        HasAllocas = true;
+        this->NumBlocks = this->NumInsts = 1;
+        return;
+      }
+    }
+
+    ++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.
 //
@@ -150,31 +199,14 @@ int SimpleInliner::getInlineCost(CallSite CS) {
   // Get information about the callee...
   FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
 
-  // If we haven't calculated this information yet...
-  if (CalleeFI.NumBlocks == 0) {
-    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 = Callee->begin(), E = Callee->end();
-         BB != E; ++BB) {
-      NumInsts += BB->size();
-      NumBlocks++;
-    }
-
-    CalleeFI.NumBlocks = NumBlocks;
-    CalleeFI.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.
-    std::vector<ArgInfo> &ArgWeights = CalleeFI.ArgumentWeights;
-
-    for (Function::aiterator I = Callee->abegin(), E = Callee->aend();
-         I != E; ++I)
-      ArgWeights.push_back(ArgInfo(CountCodeReductionForConstant(I),
-                                   CountCodeReductionForAlloca(I)));
-  }
+  // If we haven't calculated this information yet, do so now.
+  if (CalleeFI.NumBlocks == 0)
+    CalleeFI.analyzeFunction(Callee);
 
+  // Don't inline calls to functions with allocas that are not in the entry
+  // block of the function.
+  if (CalleeFI.HasAllocas)
+    return 2000000000;
 
   // Add to the inline quality for properties that make the call valuable to
   // inline.  This includes factors that indicate that the result of inlining
@@ -205,7 +237,7 @@ int SimpleInliner::getInlineCost(CallSite CS) {
     // 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)) {
+    } else if (isa<Constant>(I)) {
       if (ArgNo < CalleeFI.ArgumentWeights.size())
         InlineCost -= CalleeFI.ArgumentWeights[ArgNo].ConstantWeight;
     }
@@ -216,6 +248,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()/20;