// CountCodeReductionForConstant - Figure out an approximation for how many
// instructions will be constant folded if the specified value is constant.
//
-unsigned InlineCostAnalyzer::RegionInfo::
- CountCodeReductionForConstant(Value *V) {
+unsigned InlineCostAnalyzer::FunctionInfo::
+CountCodeReductionForConstant(Value *V) {
unsigned Reduction = 0;
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
- if (isa<BranchInst>(*UI))
- Reduction += 40; // Eliminating a conditional branch is a big win
- else if (SwitchInst *SI = dyn_cast<SwitchInst>(*UI))
- // Eliminating a switch is a big win, proportional to the number of edges
- // deleted.
- Reduction += (SI->getNumSuccessors()-1) * 40;
- else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
+ if (isa<BranchInst>(*UI) || isa<SwitchInst>(*UI)) {
+ // We will be able to eliminate all but one of the successors.
+ const TerminatorInst &TI = cast<TerminatorInst>(**UI);
+ const unsigned NumSucc = TI.getNumSuccessors();
+ unsigned Instrs = 0;
+ for (unsigned I = 0; I != NumSucc; ++I)
+ Instrs += Metrics.NumBBInsts[TI.getSuccessor(I)];
+ // We don't know which blocks will be eliminated, so use the average size.
+ Reduction += InlineConstants::InstrCost*Instrs*(NumSucc-1)/NumSucc;
+ } else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
// Turning an indirect call into a direct call is a BIG win
- Reduction += CI->getCalledValue() == V ? 500 : 0;
+ if (CI->getCalledValue() == V)
+ Reduction += InlineConstants::IndirectCallBonus;
} else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
// Turning an indirect call into a direct call is a BIG win
- Reduction += II->getCalledValue() == V ? 500 : 0;
+ if (II->getCalledValue() == V)
+ Reduction += InlineConstants::IndirectCallBonus;
} else {
// Figure out if this instruction will be removed due to simple constant
// propagation.
Instruction &Inst = cast<Instruction>(**UI);
-
+
// We can't constant propagate instructions which have effects or
// read memory.
//
// Unfortunately, we don't know the pointer that may get propagated here,
// so we can't make this decision.
if (Inst.mayReadFromMemory() || Inst.mayHaveSideEffects() ||
- isa<AllocationInst>(Inst))
+ isa<AllocaInst>(Inst))
continue;
bool AllOperandsConstant = true;
if (AllOperandsConstant) {
// We will get to remove this instruction...
- Reduction += 7;
+ Reduction += InlineConstants::InstrCost;
// And any other instructions that use it which become constants
// themselves.
// the function will be if it is inlined into a context where an argument
// becomes an alloca.
//
-unsigned InlineCostAnalyzer::RegionInfo::
+unsigned InlineCostAnalyzer::FunctionInfo::
CountCodeReductionForAlloca(Value *V) {
- if (!isa<PointerType>(V->getType())) return 0; // Not a pointer
+ if (!V->getType()->isPointerTy()) 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;
+ Reduction += InlineConstants::InstrCost;
else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) {
// If the GEP has variable indices, we won't be able to do much with it.
- if (!GEP->hasAllConstantIndices())
- Reduction += CountCodeReductionForAlloca(GEP)+15;
+ if (GEP->hasAllConstantIndices())
+ Reduction += CountCodeReductionForAlloca(GEP);
+ } else if (BitCastInst *BCI = dyn_cast<BitCastInst>(I)) {
+ // Track pointer through bitcasts.
+ Reduction += CountCodeReductionForAlloca(BCI);
} else {
// If there is some other strange instruction, we're not going to be able
// to do much if we inline this.
return Reduction;
}
+// callIsSmall - If a call is likely to lower to a single target instruction, or
+// is otherwise deemed small return true.
+// TODO: Perhaps calls like memcpy, strcpy, etc?
+static bool callIsSmall(const Function *F) {
+ if (!F) return false;
+
+ if (F->hasLocalLinkage()) return false;
+
+ if (!F->hasName()) return false;
+
+ StringRef Name = F->getName();
+
+ // These will all likely lower to a single selection DAG node.
+ if (Name == "copysign" || Name == "copysignf" ||
+ Name == "fabs" || Name == "fabsf" || Name == "fabsl" ||
+ Name == "sin" || Name == "sinf" || Name == "sinl" ||
+ Name == "cos" || Name == "cosf" || Name == "cosl" ||
+ Name == "sqrt" || Name == "sqrtf" || Name == "sqrtl" )
+ return true;
+
+ // These are all likely to be optimized into something smaller.
+ if (Name == "pow" || Name == "powf" || Name == "powl" ||
+ Name == "exp2" || Name == "exp2l" || Name == "exp2f" ||
+ Name == "floor" || Name == "floorf" || Name == "ceil" ||
+ Name == "round" || Name == "ffs" || Name == "ffsl" ||
+ Name == "abs" || Name == "labs" || Name == "llabs")
+ return true;
+
+ return false;
+}
+
/// analyzeBasicBlock - Fill in the current structure with information gleaned
/// from the specified block.
-void InlineCostAnalyzer::RegionInfo::analyzeBasicBlock(const BasicBlock *BB) {
+void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
++NumBlocks;
-
+ unsigned NumInstsInThisBB = 0;
for (BasicBlock::const_iterator II = BB->begin(), E = BB->end();
II != E; ++II) {
if (isa<PHINode>(II)) continue; // PHI nodes don't count.
// probably won't do this in callers.
if (Function *F = CS.getCalledFunction())
if (F->isDeclaration() &&
- (F->getName() == "setjmp" || F->getName() == "_setjmp")) {
+ (F->getName() == "setjmp" || F->getName() == "_setjmp"))
NeverInline = true;
- return;
- }
- // Calls often compile into many machine instructions. Bump up their
- // cost to reflect this.
- if (!isa<IntrinsicInst>(II))
- NumInsts += InlineConstants::CallPenalty;
+ if (!isa<IntrinsicInst>(II) && !callIsSmall(CS.getCalledFunction())) {
+ // Each argument to a call takes on average one instruction to set up.
+ NumInsts += CS.arg_size();
+ ++NumCalls;
+ }
}
- // These, too, are calls.
- if (isa<MallocInst>(II) || isa<FreeInst>(II))
- NumInsts += InlineConstants::CallPenalty;
-
if (const AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
if (!AI->isStaticAlloca())
this->usesDynamicAlloca = true;
}
- if (isa<ExtractElementInst>(II) || isa<VectorType>(II->getType()))
+ if (isa<ExtractElementInst>(II) || II->getType()->isVectorTy())
++NumVectorInsts;
- // Noop casts, including ptr <-> int, don't count.
if (const CastInst *CI = dyn_cast<CastInst>(II)) {
+ // Noop casts, including ptr <-> int, don't count.
if (CI->isLosslessCast() || isa<IntToPtrInst>(CI) ||
isa<PtrToIntInst>(CI))
continue;
- } else if (const GetElementPtrInst *GEPI =
- dyn_cast<GetElementPtrInst>(II)) {
+ // Result of a cmp instruction is often extended (to be used by other
+ // cmp instructions, logical or return instructions). These are usually
+ // nop on most sane targets.
+ if (isa<CmpInst>(CI->getOperand(0)))
+ continue;
+ } else if (const GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(II)){
// If a GEP has all constant indices, it will probably be folded with
// a load/store.
if (GEPI->hasAllConstantIndices())
continue;
}
- if (isa<ReturnInst>(II))
- ++NumRets;
-
++NumInsts;
+ ++NumInstsInThisBB;
}
+
+ if (isa<ReturnInst>(BB->getTerminator()))
+ ++NumRets;
+
+ // We never want to inline functions that contain an indirectbr. This is
+ // incorrect because all the blockaddress's (in static global initializers
+ // for example) would be referring to the original function, and this indirect
+ // jump would jump from the inlined copy of the function into the original
+ // function which is extremely undefined behavior.
+ if (isa<IndirectBrInst>(BB->getTerminator()))
+ NeverInline = true;
+
+ // Remember NumInsts for this BB.
+ NumBBInsts[BB] = NumInstsInThisBB;
}
/// analyzeFunction - Fill in the current structure with information gleaned
/// from the specified function.
-void InlineCostAnalyzer::RegionInfo::analyzeFunction(Function *F) {
- // Look at the size of the callee. Each basic block counts as 20 units, and
- // each instruction counts as 5.
+void CodeMetrics::analyzeFunction(Function *F) {
+ // Look at the size of the callee.
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
analyzeBasicBlock(&*BB);
+}
+
+/// analyzeFunction - Fill in the current structure with information gleaned
+/// from the specified function.
+void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
+ Metrics.analyzeFunction(F);
// A function with exactly one return has it removed during the inlining
// process (see InlineFunction), so don't count it.
- // FIXME: This knowledge should really be encoded outside of RegionInfo.
- if (NumRets==1)
- --NumInsts;
+ // FIXME: This knowledge should really be encoded outside of FunctionInfo.
+ if (Metrics.NumRets==1)
+ --Metrics.NumInsts;
+
+ // Don't bother calculating argument weights if we are never going to inline
+ // the function anyway.
+ if (Metrics.NeverInline)
+ return;
// 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.
+ ArgumentWeights.reserve(F->arg_size());
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.
//
InlineCost += InlineConstants::NoreturnPenalty;
// Get information about the callee...
- RegionInfo &CalleeFI = CachedFunctionInfo[Callee];
+ FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
// If we haven't calculated this information yet, do so now.
- if (CalleeFI.NumBlocks == 0)
+ if (CalleeFI.Metrics.NumBlocks == 0)
CalleeFI.analyzeFunction(Callee);
// If we should never inline this, return a huge cost.
- if (CalleeFI.NeverInline)
+ if (CalleeFI.Metrics.NeverInline)
return InlineCost::getNever();
// FIXME: It would be nice to kill off CalleeFI.NeverInline. Then we
- // could move this up and avoid computing the RegionInfo for
+ // could move this up and avoid computing the FunctionInfo for
// things we are going to just return always inline for. This
// requires handling setjmp somewhere else, however.
if (!Callee->isDeclaration() && Callee->hasFnAttr(Attribute::AlwaysInline))
return InlineCost::getAlways();
- if (CalleeFI.usesDynamicAlloca) {
+ if (CalleeFI.Metrics.usesDynamicAlloca) {
// Get infomation about the caller...
- RegionInfo &CallerFI = CachedFunctionInfo[Caller];
+ FunctionInfo &CallerFI = CachedFunctionInfo[Caller];
// If we haven't calculated this information yet, do so now.
- if (CallerFI.NumBlocks == 0)
+ if (CallerFI.Metrics.NumBlocks == 0)
CallerFI.analyzeFunction(Caller);
// Don't inline a callee with dynamic alloca into a caller without them.
// Functions containing dynamic alloca's are inefficient in various ways;
// don't create more inefficiency.
- if (!CallerFI.usesDynamicAlloca)
+ if (!CallerFI.Metrics.usesDynamicAlloca)
return InlineCost::getNever();
}
for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
I != E; ++I, ++ArgNo) {
// Each argument passed in has a cost at both the caller and the callee
- // sides. This favors functions that take many arguments over functions
- // that take few arguments.
- InlineCost -= 20;
-
- // If this is a function being passed in, it is very likely that we will be
- // able to turn an indirect function call into a direct function call.
- if (isa<Function>(I))
- InlineCost -= 100;
-
+ // sides. Measurements show that each argument costs about the same as an
+ // instruction.
+ InlineCost -= InlineConstants::InstrCost;
+
// If an alloca is passed in, inlining this function is likely to allow
// significant future optimization possibilities (like scalar promotion, and
// scalarization), so encourage the inlining of the function.
//
- else if (isa<AllocaInst>(I)) {
+ if (isa<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.
// Now that we have considered all of the factors that make the call site more
// likely to be inlined, look at factors that make us not want to inline it.
-
- // Don't inline into something too big, which would make it bigger.
- // "size" here is the number of basic blocks, not instructions.
- //
- InlineCost += Caller->size()/15;
-
+
+ // Calls usually take a long time, so they make the inlining gain smaller.
+ InlineCost += CalleeFI.Metrics.NumCalls * InlineConstants::CallPenalty;
+
// Look at the size of the callee. Each instruction counts as 5.
- InlineCost += CalleeFI.NumInsts*5;
+ InlineCost += CalleeFI.Metrics.NumInsts*InlineConstants::InstrCost;
return llvm::InlineCost::get(InlineCost);
}
Function *Callee = CS.getCalledFunction();
// Get information about the callee...
- RegionInfo &CalleeFI = CachedFunctionInfo[Callee];
+ FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
// If we haven't calculated this information yet, do so now.
- if (CalleeFI.NumBlocks == 0)
+ if (CalleeFI.Metrics.NumBlocks == 0)
CalleeFI.analyzeFunction(Callee);
float Factor = 1.0f;
// Single BB functions are often written to be inlined.
- if (CalleeFI.NumBlocks == 1)
+ if (CalleeFI.Metrics.NumBlocks == 1)
Factor += 0.5f;
// Be more aggressive if the function contains a good chunk (if it mades up
// at least 10% of the instructions) of vector instructions.
- if (CalleeFI.NumVectorInsts > CalleeFI.NumInsts/2)
+ if (CalleeFI.Metrics.NumVectorInsts > CalleeFI.Metrics.NumInsts/2)
Factor += 2.0f;
- else if (CalleeFI.NumVectorInsts > CalleeFI.NumInsts/10)
+ else if (CalleeFI.Metrics.NumVectorInsts > CalleeFI.Metrics.NumInsts/10)
Factor += 1.5f;
return Factor;
}
+
+/// growCachedCostInfo - update the cached cost info for Caller after Callee has
+/// been inlined.
+void
+InlineCostAnalyzer::growCachedCostInfo(Function* Caller, Function* Callee) {
+ FunctionInfo &CallerFI = CachedFunctionInfo[Caller];
+
+ // For small functions we prefer to recalculate the cost for better accuracy.
+ if (CallerFI.Metrics.NumBlocks < 10 || CallerFI.Metrics.NumInsts < 1000) {
+ resetCachedCostInfo(Caller);
+ return;
+ }
+
+ // For large functions, we can save a lot of computation time by skipping
+ // recalculations.
+ if (CallerFI.Metrics.NumCalls > 0)
+ --CallerFI.Metrics.NumCalls;
+
+ if (Callee) {
+ FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
+ if (!CalleeFI.Metrics.NumBlocks) {
+ resetCachedCostInfo(Caller);
+ return;
+ }
+ CallerFI.Metrics.NeverInline |= CalleeFI.Metrics.NeverInline;
+ CallerFI.Metrics.usesDynamicAlloca |= CalleeFI.Metrics.usesDynamicAlloca;
+
+ CallerFI.Metrics.NumInsts += CalleeFI.Metrics.NumInsts;
+ CallerFI.Metrics.NumBlocks += CalleeFI.Metrics.NumBlocks;
+ CallerFI.Metrics.NumCalls += CalleeFI.Metrics.NumCalls;
+ CallerFI.Metrics.NumVectorInsts += CalleeFI.Metrics.NumVectorInsts;
+ CallerFI.Metrics.NumRets += CalleeFI.Metrics.NumRets;
+
+ // analyzeBasicBlock counts each function argument as an inst.
+ if (CallerFI.Metrics.NumInsts >= Callee->arg_size())
+ CallerFI.Metrics.NumInsts -= Callee->arg_size();
+ else
+ CallerFI.Metrics.NumInsts = 0;
+ }
+ // We are not updating the argumentweights. We have already determined that
+ // Caller is a fairly large function, so we accept the loss of precision.
+}