[llvm-commits] CVS: llvm/lib/Transforms/IPO/InlineSimple.cpp

Chris Lattner lattner at cs.uiuc.edu
Wed Aug 11 22:45:19 PDT 2004



Changes in directory llvm/lib/Transforms/IPO:

InlineSimple.cpp updated: 1.63 -> 1.64
---
Log message:

This patch makes the inliner refuse to inline functions that have alloca 
instructions in the body of the function (not the entry block).  This fixes
test/Programs/SingleSource/Regression/C/2004-08-12-InlinerAndAllocas.c
and test/Programs/External/SPEC/CINT2000/176.gcc on zion.

This should obviously be pulled into 1.3.



---
Diffs of the changes:  (+58 -26)

Index: llvm/lib/Transforms/IPO/InlineSimple.cpp
diff -u llvm/lib/Transforms/IPO/InlineSimple.cpp:1.63 llvm/lib/Transforms/IPO/InlineSimple.cpp:1.64
--- llvm/lib/Transforms/IPO/InlineSimple.cpp:1.63	Sat Jul 17 19:27:06 2004
+++ llvm/lib/Transforms/IPO/InlineSimple.cpp	Thu Aug 12 00:45:09 2004
@@ -31,6 +31,16 @@
   // 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 +51,11 @@
     // 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 {
@@ -123,6 +137,41 @@
   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) {
+      ++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::aiterator I = F->abegin(), E = F->aend(); 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.
 //
@@ -149,31 +198,14 @@
   // 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






More information about the llvm-commits mailing list