aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/IPO
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-03-13 23:15:45 +0000
committerChris Lattner <sabre@nondot.org>2004-03-13 23:15:45 +0000
commit619d3544b19dfdc0006bb0f036253d76488fc212 (patch)
tree828eaf8ec4737c97e623243293239bb7a6c3f625 /lib/Transforms/IPO
parent786c5646e9cd15f18a6a7938673f74b02a05adb8 (diff)
downloadexternal_llvm-619d3544b19dfdc0006bb0f036253d76488fc212.zip
external_llvm-619d3544b19dfdc0006bb0f036253d76488fc212.tar.gz
external_llvm-619d3544b19dfdc0006bb0f036253d76488fc212.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12363 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO')
-rw-r--r--lib/Transforms/IPO/InlineSimple.cpp60
1 files changed, 49 insertions, 11 deletions
diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp
index eec2ebd..d28fcbf 100644
--- a/lib/Transforms/IPO/InlineSimple.cpp
+++ b/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