BlockFrequencyInfo *CallerBFI);
// Custom analysis routines.
- bool analyzeBlock(BasicBlock *BB, SmallPtrSetImpl<const Value *> &EphValues);
+ InlineResult analyzeBlock(BasicBlock *BB,
+ SmallPtrSetImpl<const Value *> &EphValues);
// Disable several entry points to the visitor so we don't accidentally use
// them by declaring but not defining them here.
NumInstructionsSimplified(0), SROACostSavings(0),
SROACostSavingsLost(0) {}
- bool analyzeCall(CallSite CS);
+ InlineResult analyzeCall(CallSite CS);
int getThreshold() { return Threshold; }
int getCost() { return Cost; }
/// aborts early if the threshold has been exceeded or an impossible to inline
/// construct has been detected. It returns false if inlining is no longer
/// viable, and true if inlining remains viable.
-bool CallAnalyzer::analyzeBlock(BasicBlock *BB,
- SmallPtrSetImpl<const Value *> &EphValues) {
+InlineResult
+CallAnalyzer::analyzeBlock(BasicBlock *BB,
+ SmallPtrSetImpl<const Value *> &EphValues) {
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
// FIXME: Currently, the number of instructions in a function regardless of
// our ability to simplify them during inline to constants or dead code,
using namespace ore;
// If the visit this instruction detected an uninlinable pattern, abort.
- if (IsRecursiveCall || ExposesReturnsTwice || HasDynamicAlloca ||
- HasIndirectBr || HasUninlineableIntrinsic || UsesVarArgs) {
+ InlineResult IR;
+ if (IsRecursiveCall)
+ IR = "recursive";
+ else if (ExposesReturnsTwice)
+ IR = "exposes returns twice";
+ else if (HasDynamicAlloca)
+ IR = "dynamic alloca";
+ else if (HasIndirectBr)
+ IR = "indirect branch";
+ else if (HasUninlineableIntrinsic)
+ IR = "uninlinable intrinsic";
+ else if (UsesVarArgs)
+ IR = "varargs";
+ if (!IR) {
if (ORE)
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline",
CandidateCS.getInstruction())
- << NV("Callee", &F)
- << " has uninlinable pattern and cost is not fully computed";
+ << NV("Callee", &F) << " has uninlinable pattern ("
+ << NV("InlineResult", IR.message)
+ << ") and cost is not fully computed";
});
- return false;
+ return IR;
}
// If the caller is a recursive function then we don't want to inline
// the caller stack usage dramatically.
if (IsCallerRecursive &&
AllocatedSize > InlineConstants::TotalAllocaSizeRecursiveCaller) {
+ InlineResult IR = "recursive and allocates too much stack space";
if (ORE)
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline",
CandidateCS.getInstruction())
- << NV("Callee", &F)
- << " is recursive and allocates too much stack space. Cost is "
- "not fully computed";
+ << NV("Callee", &F) << " is " << NV("InlineResult", IR.message)
+ << ". Cost is not fully computed";
});
- return false;
+ return IR;
}
// Check if we've past the maximum possible threshold so we don't spin in
/// factors and heuristics. If this method returns false but the computed cost
/// is below the computed threshold, then inlining was forcibly disabled by
/// some artifact of the routine.
-bool CallAnalyzer::analyzeCall(CallSite CS) {
+InlineResult CallAnalyzer::analyzeCall(CallSite CS) {
++NumCallsAnalyzed;
// Perform some tweaks to the cost and threshold based on the direct
// Check if we're done. This can happen due to bonuses and penalties.
if (Cost >= Threshold && !ComputeFullInlineCost)
- return false;
+ return "high cost";
if (F.empty())
return true;
// site. If the blockaddress escapes the function, e.g., via a global
// variable, inlining may lead to an invalid cross-function reference.
if (BB->hasAddressTaken())
- return false;
+ return "blockaddress";
// Analyze the cost of this block. If we blow through the threshold, this
// returns false, and we can bail on out.
- if (!analyzeBlock(BB, EphValues))
- return false;
+ InlineResult IR = analyzeBlock(BB, EphValues);
+ if (!IR)
+ return IR;
TerminatorInst *TI = BB->getTerminator();
// inlining this would cause the removal of the caller (so the instruction
// is not actually duplicated, just moved).
if (!OnlyOneCallAndLocalLinkage && ContainsNoDuplicateCall)
- return false;
+ return "noduplicate";
// We applied the maximum possible vector bonus at the beginning. Now,
// subtract the excess bonus, if any, from the Threshold before
// Cannot inline indirect calls.
if (!Callee)
- return llvm::InlineCost::getNever();
+ return llvm::InlineCost::getNever("indirect call");
// Never inline calls with byval arguments that does not have the alloca
// address space. Since byval arguments can be replaced with a copy to an
if (CS.isByValArgument(I)) {
PointerType *PTy = cast<PointerType>(CS.getArgument(I)->getType());
if (PTy->getAddressSpace() != AllocaAS)
- return llvm::InlineCost::getNever();
+ return llvm::InlineCost::getNever("byval arguments without alloca"
+ " address space");
}
// Calls to functions with always-inline attributes should be inlined
// whenever possible.
if (CS.hasFnAttr(Attribute::AlwaysInline)) {
if (isInlineViable(*Callee))
- return llvm::InlineCost::getAlways();
- return llvm::InlineCost::getNever();
+ return llvm::InlineCost::getAlways("always inline attribute");
+ return llvm::InlineCost::getNever("inapplicable always inline attribute");
}
// Never inline functions with conflicting attributes (unless callee has
// always-inline attribute).
Function *Caller = CS.getCaller();
if (!functionsHaveCompatibleAttributes(Caller, Callee, CalleeTTI))
- return llvm::InlineCost::getNever();
+ return llvm::InlineCost::getNever("conflicting attributes");
// Don't inline this call if the caller has the optnone attribute.
if (Caller->hasFnAttribute(Attribute::OptimizeNone))
- return llvm::InlineCost::getNever();
+ return llvm::InlineCost::getNever("optnone attribute");
// Don't inline a function that treats null pointer as valid into a caller
// that does not have this attribute.
if (!Caller->nullPointerIsDefined() && Callee->nullPointerIsDefined())
- return llvm::InlineCost::getNever();
+ return llvm::InlineCost::getNever("nullptr definitions incompatible");
+
+ // Don't inline functions which can be interposed at link-time.
+ if (Callee->isInterposable())
+ return llvm::InlineCost::getNever("interposable");
+
+ // Don't inline functions marked noinline.
+ if (Callee->hasFnAttribute(Attribute::NoInline))
+ return llvm::InlineCost::getNever("noinline function attribute");
- // Don't inline functions which can be interposed at link-time. Don't inline
- // functions marked noinline or call sites marked noinline.
- // Note: inlining non-exact non-interposable functions is fine, since we know
- // we have *a* correct implementation of the source level function.
- if (Callee->isInterposable() || Callee->hasFnAttribute(Attribute::NoInline) ||
- CS.isNoInline())
- return llvm::InlineCost::getNever();
+ // Don't inline call sites marked noinline.
+ if (CS.isNoInline())
+ return llvm::InlineCost::getNever("noinline call site attribute");
LLVM_DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName()
<< "... (caller:" << Caller->getName() << ")\n");
CallAnalyzer CA(CalleeTTI, GetAssumptionCache, GetBFI, PSI, ORE, *Callee, CS,
Params);
- bool ShouldInline = CA.analyzeCall(CS);
+ InlineResult ShouldInline = CA.analyzeCall(CS);
LLVM_DEBUG(CA.dump());
// Check if there was a reason to force inlining or no inlining.
if (!ShouldInline && CA.getCost() < CA.getThreshold())
- return InlineCost::getNever();
+ return InlineCost::getNever(ShouldInline.message);
if (ShouldInline && CA.getCost() >= CA.getThreshold())
- return InlineCost::getAlways();
+ return InlineCost::getAlways("empty function");
return llvm::InlineCost::get(CA.getCost(), CA.getThreshold());
}