summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/InlineSimple.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-08-12 05:45:09 +0000
committerChris Lattner <sabre@nondot.org>2004-08-12 05:45:09 +0000
commitee45f4cbe409b2e89207f3c554e9121101c9e52e (patch)
treecea602fc956fe853deed08b10792ebf2a90bd64a /lib/Transforms/IPO/InlineSimple.cpp
parenta1b6ae9d7cf39e4589192eac4ad2288ec29e2de1 (diff)
downloadllvm-ee45f4cbe409b2e89207f3c554e9121101c9e52e.tar.gz
llvm-ee45f4cbe409b2e89207f3c554e9121101c9e52e.tar.bz2
llvm-ee45f4cbe409b2e89207f3c554e9121101c9e52e.tar.xz
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15684 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/InlineSimple.cpp')
-rw-r--r--lib/Transforms/IPO/InlineSimple.cpp82
1 files changed, 57 insertions, 25 deletions
diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp
index 791b21356e..1722fe52e0 100644
--- a/lib/Transforms/IPO/InlineSimple.cpp
+++ b/lib/Transforms/IPO/InlineSimple.cpp
@@ -31,6 +31,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 +51,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 {
@@ -123,6 +137,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) {
+ ++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 @@ 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