diff options
Diffstat (limited to 'llvm/lib/Analysis/InlineCost.cpp')
-rw-r--r-- | llvm/lib/Analysis/InlineCost.cpp | 93 |
1 files changed, 57 insertions, 36 deletions
diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index a6cccc3b591..1d879f8aee9 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -227,7 +227,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> { 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. @@ -290,7 +291,7 @@ public: NumInstructionsSimplified(0), SROACostSavings(0), SROACostSavingsLost(0) {} - bool analyzeCall(CallSite CS); + InlineResult analyzeCall(CallSite CS); int getThreshold() { return Threshold; } int getCost() { return Cost; } @@ -1541,8 +1542,9 @@ bool CallAnalyzer::visitInstruction(Instruction &I) { /// 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, @@ -1574,16 +1576,29 @@ bool CallAnalyzer::analyzeBlock(BasicBlock *BB, 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 @@ -1591,15 +1606,15 @@ bool CallAnalyzer::analyzeBlock(BasicBlock *BB, // 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 @@ -1695,7 +1710,7 @@ void CallAnalyzer::findDeadBlocks(BasicBlock *CurrBB, BasicBlock *NextBB) { /// 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 @@ -1730,7 +1745,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) { // 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; @@ -1809,12 +1824,13 @@ bool CallAnalyzer::analyzeCall(CallSite CS) { // 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(); @@ -1867,7 +1883,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) { // 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 @@ -1961,7 +1977,7 @@ InlineCost llvm::getInlineCost( // 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 @@ -1973,54 +1989,59 @@ InlineCost llvm::getInlineCost( 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()); } |