#include "Inliner.h"
#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Function.h"
#include "llvm/Type.h"
#include "llvm/Support/CallSite.h"
// 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;
// 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 {
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.
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;
}
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.
//
// 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
// 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;
}
// 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;