From fbbb83c782d310d7bcbeec9b4397816206449107 Mon Sep 17 00:00:00 2001 From: David Bolvansky Date: Wed, 1 Aug 2018 08:02:40 +0000 Subject: [PATCH] Revert "Enrich inline messages", tests fail llvm-svn: 338496 --- llvm/include/llvm/Analysis/InlineCost.h | 35 +----- llvm/include/llvm/IR/DiagnosticInfo.h | 1 - llvm/include/llvm/Transforms/Utils/Cloning.h | 18 ++-- llvm/lib/Analysis/InlineCost.cpp | 93 +++++++--------- llvm/lib/Target/AMDGPU/AMDGPUInline.cpp | 17 ++- llvm/lib/Transforms/IPO/AlwaysInliner.cpp | 4 +- llvm/lib/Transforms/IPO/Inliner.cpp | 120 ++++++++++----------- llvm/lib/Transforms/Utils/InlineFunction.cpp | 29 +++-- .../X86/diagnostic-handler-remarks-with-hotness.ll | 7 +- .../Resolution/X86/diagnostic-handler-remarks.ll | 5 +- .../X86/diagnostic-handler-remarks-with-hotness.ll | 5 +- llvm/test/LTO/X86/diagnostic-handler-remarks.ll | 5 +- .../X86/diagnostic-handler-remarks-with-hotness.ll | 10 +- .../test/ThinLTO/X86/diagnostic-handler-remarks.ll | 10 +- llvm/test/Transforms/Inline/ARM/inline-fp.ll | 24 ++--- .../optimization-remarks-hotness-threshold.ll | 2 +- .../Inline/optimization-remarks-passed-yaml.ll | 7 +- .../Inline/optimization-remarks-with-hotness.ll | 4 +- .../test/Transforms/Inline/optimization-remarks.ll | 4 +- llvm/test/tools/gold/X86/opt-remarks.ll | 6 +- 20 files changed, 162 insertions(+), 244 deletions(-) diff --git a/llvm/include/llvm/Analysis/InlineCost.h b/llvm/include/llvm/Analysis/InlineCost.h index 529fb75..8c41205 100644 --- a/llvm/include/llvm/Analysis/InlineCost.h +++ b/llvm/include/llvm/Analysis/InlineCost.h @@ -74,15 +74,8 @@ class InlineCost { /// The adjusted threshold against which this cost was computed. const int Threshold; - /// Must be set for Always and Never instances. - const char *Reason = nullptr; - // Trivial constructor, interesting logic in the factory functions below. - InlineCost(int Cost, int Threshold, const char *Reason = nullptr) - : Cost(Cost), Threshold(Threshold), Reason(Reason) { - assert((isVariable() || Reason) && - "Reason must be provided for Never or Always"); - } + InlineCost(int Cost, int Threshold) : Cost(Cost), Threshold(Threshold) {} public: static InlineCost get(int Cost, int Threshold) { @@ -90,11 +83,11 @@ public: assert(Cost < NeverInlineCost && "Cost crosses sentinel value"); return InlineCost(Cost, Threshold); } - static InlineCost getAlways(const char *Reason) { - return InlineCost(AlwaysInlineCost, 0, Reason); + static InlineCost getAlways() { + return InlineCost(AlwaysInlineCost, 0); } - static InlineCost getNever(const char *Reason) { - return InlineCost(NeverInlineCost, 0, Reason); + static InlineCost getNever() { + return InlineCost(NeverInlineCost, 0); } /// Test whether the inline cost is low enough for inlining. @@ -119,30 +112,12 @@ public: return Threshold; } - /// Get the reason of Always or Never. - const char *getReason() const { - assert((Reason || isVariable()) && - "InlineCost reason must be set for Always or Never"); - return Reason; - } - /// Get the cost delta from the threshold for inlining. /// Only valid if the cost is of the variable kind. Returns a negative /// value if the cost is too high to inline. int getCostDelta() const { return Threshold - getCost(); } }; -/// InlineResult is basically true or false. For false results the message -/// describes a reason why it is decided not to inline. -struct InlineResult { - const char *message = nullptr; - InlineResult(bool result, const char *message = nullptr) - : message(result ? nullptr : (message ? message : "cost > threshold")) {} - InlineResult(const char *message = nullptr) : message(message) {} - operator bool() const { return !message; } - operator const char *() const { return message; } -}; - /// Thresholds to tune inline cost analysis. The inline cost analysis decides /// the condition to apply a threshold and applies it. Otherwise, /// DefaultThreshold is used. If a threshold is Optional, it is applied only diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h index b8fdae2..81d4ae8 100644 --- a/llvm/include/llvm/IR/DiagnosticInfo.h +++ b/llvm/include/llvm/IR/DiagnosticInfo.h @@ -414,7 +414,6 @@ public: Argument(StringRef Key, const Value *V); Argument(StringRef Key, const Type *T); Argument(StringRef Key, StringRef S); - Argument(StringRef Key, const char *S) : Argument(Key, StringRef(S)) {}; Argument(StringRef Key, int N); Argument(StringRef Key, float N); Argument(StringRef Key, long N); diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h index e4d6053..7531fb2 100644 --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -22,7 +22,6 @@ #include "llvm/ADT/Twine.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" -#include "llvm/Analysis/InlineCost.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Transforms/Utils/ValueMapper.h" @@ -233,16 +232,13 @@ public: /// and all varargs at the callsite will be passed to any calls to /// ForwardVarArgsTo. The caller of InlineFunction has to make sure any varargs /// are only used by ForwardVarArgsTo. -InlineResult InlineFunction(CallInst *C, InlineFunctionInfo &IFI, - AAResults *CalleeAAR = nullptr, - bool InsertLifetime = true); -InlineResult InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, - AAResults *CalleeAAR = nullptr, - bool InsertLifetime = true); -InlineResult InlineFunction(CallSite CS, InlineFunctionInfo &IFI, - AAResults *CalleeAAR = nullptr, - bool InsertLifetime = true, - Function *ForwardVarArgsTo = nullptr); +bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, + AAResults *CalleeAAR = nullptr, bool InsertLifetime = true); +bool InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, + AAResults *CalleeAAR = nullptr, bool InsertLifetime = true); +bool InlineFunction(CallSite CS, InlineFunctionInfo &IFI, + AAResults *CalleeAAR = nullptr, bool InsertLifetime = true, + Function *ForwardVarArgsTo = nullptr); /// Clones a loop \p OrigLoop. Returns the loop and the blocks in \p /// Blocks. diff --git a/llvm/lib/Analysis/InlineCost.cpp b/llvm/lib/Analysis/InlineCost.cpp index 1d879f8..a6cccc3 100644 --- a/llvm/lib/Analysis/InlineCost.cpp +++ b/llvm/lib/Analysis/InlineCost.cpp @@ -227,8 +227,7 @@ class CallAnalyzer : public InstVisitor { BlockFrequencyInfo *CallerBFI); // Custom analysis routines. - InlineResult analyzeBlock(BasicBlock *BB, - SmallPtrSetImpl &EphValues); + bool analyzeBlock(BasicBlock *BB, SmallPtrSetImpl &EphValues); // Disable several entry points to the visitor so we don't accidentally use // them by declaring but not defining them here. @@ -291,7 +290,7 @@ public: NumInstructionsSimplified(0), SROACostSavings(0), SROACostSavingsLost(0) {} - InlineResult analyzeCall(CallSite CS); + bool analyzeCall(CallSite CS); int getThreshold() { return Threshold; } int getCost() { return Cost; } @@ -1542,9 +1541,8 @@ 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. -InlineResult -CallAnalyzer::analyzeBlock(BasicBlock *BB, - SmallPtrSetImpl &EphValues) { +bool CallAnalyzer::analyzeBlock(BasicBlock *BB, + SmallPtrSetImpl &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, @@ -1576,29 +1574,16 @@ CallAnalyzer::analyzeBlock(BasicBlock *BB, using namespace ore; // If the visit this instruction detected an uninlinable pattern, abort. - 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 (IsRecursiveCall || ExposesReturnsTwice || HasDynamicAlloca || + HasIndirectBr || HasUninlineableIntrinsic || UsesVarArgs) { if (ORE) ORE->emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", CandidateCS.getInstruction()) - << NV("Callee", &F) << " has uninlinable pattern (" - << NV("InlineResult", IR.message) - << ") and cost is not fully computed"; + << NV("Callee", &F) + << " has uninlinable pattern and cost is not fully computed"; }); - return IR; + return false; } // If the caller is a recursive function then we don't want to inline @@ -1606,15 +1591,15 @@ 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 " << NV("InlineResult", IR.message) - << ". Cost is not fully computed"; + << NV("Callee", &F) + << " is recursive and allocates too much stack space. Cost is " + "not fully computed"; }); - return IR; + return false; } // Check if we've past the maximum possible threshold so we don't spin in @@ -1710,7 +1695,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. -InlineResult CallAnalyzer::analyzeCall(CallSite CS) { +bool CallAnalyzer::analyzeCall(CallSite CS) { ++NumCallsAnalyzed; // Perform some tweaks to the cost and threshold based on the direct @@ -1745,7 +1730,7 @@ InlineResult CallAnalyzer::analyzeCall(CallSite CS) { // Check if we're done. This can happen due to bonuses and penalties. if (Cost >= Threshold && !ComputeFullInlineCost) - return "high cost"; + return false; if (F.empty()) return true; @@ -1824,13 +1809,12 @@ InlineResult 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 "blockaddress"; + return false; // Analyze the cost of this block. If we blow through the threshold, this // returns false, and we can bail on out. - InlineResult IR = analyzeBlock(BB, EphValues); - if (!IR) - return IR; + if (!analyzeBlock(BB, EphValues)) + return false; TerminatorInst *TI = BB->getTerminator(); @@ -1883,7 +1867,7 @@ InlineResult 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 "noduplicate"; + return false; // We applied the maximum possible vector bonus at the beginning. Now, // subtract the excess bonus, if any, from the Threshold before @@ -1977,7 +1961,7 @@ InlineCost llvm::getInlineCost( // Cannot inline indirect calls. if (!Callee) - return llvm::InlineCost::getNever("indirect call"); + return llvm::InlineCost::getNever(); // 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 @@ -1989,59 +1973,54 @@ InlineCost llvm::getInlineCost( if (CS.isByValArgument(I)) { PointerType *PTy = cast(CS.getArgument(I)->getType()); if (PTy->getAddressSpace() != AllocaAS) - return llvm::InlineCost::getNever("byval arguments without alloca" - " address space"); + return llvm::InlineCost::getNever(); } // Calls to functions with always-inline attributes should be inlined // whenever possible. if (CS.hasFnAttr(Attribute::AlwaysInline)) { if (isInlineViable(*Callee)) - return llvm::InlineCost::getAlways("always inline attribute"); - return llvm::InlineCost::getNever("inapplicable always inline attribute"); + return llvm::InlineCost::getAlways(); + return llvm::InlineCost::getNever(); } // 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("conflicting attributes"); + return llvm::InlineCost::getNever(); // Don't inline this call if the caller has the optnone attribute. if (Caller->hasFnAttribute(Attribute::OptimizeNone)) - return llvm::InlineCost::getNever("optnone attribute"); + return llvm::InlineCost::getNever(); // 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("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"); + return llvm::InlineCost::getNever(); - // Don't inline call sites marked noinline. - if (CS.isNoInline()) - return llvm::InlineCost::getNever("noinline call site 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(); LLVM_DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName() << "... (caller:" << Caller->getName() << ")\n"); CallAnalyzer CA(CalleeTTI, GetAssumptionCache, GetBFI, PSI, ORE, *Callee, CS, Params); - InlineResult ShouldInline = CA.analyzeCall(CS); + bool 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(ShouldInline.message); + return InlineCost::getNever(); if (ShouldInline && CA.getCost() >= CA.getThreshold()) - return InlineCost::getAlways("empty function"); + return InlineCost::getAlways(); return llvm::InlineCost::get(CA.getCost(), CA.getThreshold()); } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUInline.cpp b/llvm/lib/Target/AMDGPU/AMDGPUInline.cpp index 7060ff3..35dd9eb 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUInline.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUInline.cpp @@ -174,23 +174,18 @@ InlineCost AMDGPUInliner::getInlineCost(CallSite CS) { Function *Caller = CS.getCaller(); TargetTransformInfo &TTI = TTIWP->getTTI(*Callee); - if (!Callee || Callee->isDeclaration()) - return llvm::InlineCost::getNever("undefined callee"); - - if (CS.isNoInline()) - return llvm::InlineCost::getNever("noinline"); - - if (!TTI.areInlineCompatible(Caller, Callee)) - return llvm::InlineCost::getNever("incompatible"); + if (!Callee || Callee->isDeclaration() || CS.isNoInline() || + !TTI.areInlineCompatible(Caller, Callee)) + return llvm::InlineCost::getNever(); if (CS.hasFnAttr(Attribute::AlwaysInline)) { if (isInlineViable(*Callee)) - return llvm::InlineCost::getAlways("alwaysinline viable"); - return llvm::InlineCost::getNever("alwaysinline unviable"); + return llvm::InlineCost::getAlways(); + return llvm::InlineCost::getNever(); } if (isWrapperOnlyCall(CS)) - return llvm::InlineCost::getAlways("wrapper-only call"); + return llvm::InlineCost::getAlways(); InlineParams LocalParams = Params; LocalParams.DefaultThreshold = (int)getInlineThreshold(CS); diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp index 0713871..3b735dd 100644 --- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp +++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp @@ -150,7 +150,7 @@ InlineCost AlwaysInlinerLegacyPass::getInlineCost(CallSite CS) { // declarations. if (Callee && !Callee->isDeclaration() && CS.hasFnAttr(Attribute::AlwaysInline) && isInlineViable(*Callee)) - return InlineCost::getAlways("always inliner"); + return InlineCost::getAlways(); - return InlineCost::getNever("always inliner"); + return InlineCost::getNever(); } diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index fdf47b7..3da0c2e 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -64,7 +64,6 @@ #include #include #include -#include #include #include #include @@ -276,9 +275,8 @@ static bool InlineCallIfPossible( // Try to inline the function. Get the list of static allocas that were // inlined. - InlineResult IR = InlineFunction(CS, IFI, &AAR, InsertLifetime); - if (!IR) - return IR; + if (!InlineFunction(CS, IFI, &AAR, InsertLifetime)) + return false; if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No) ImportedFunctionsStats.recordInline(*Caller, *Callee); @@ -288,7 +286,7 @@ static bool InlineCallIfPossible( if (!DisableInlinedAllocaMerging) mergeInlinedArrayAllocas(Caller, IFI, InlinedArrayAllocas, InlineHistory); - return IR; // success + return true; } /// Return true if inlining of CS can block the caller from being @@ -367,33 +365,6 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC, return false; } -static std::basic_ostream &operator<<(std::basic_ostream &R, - const ore::NV &Arg) { - return R << Arg.Val; -} - -template -RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) { - using namespace ore; - if (IC.isAlways()) { - R << "(cost=always)"; - } else if (IC.isNever()) { - R << "(cost=never)"; - } else { - R << "(cost=" << ore::NV("Cost", IC.getCost()) - << ", threshold=" << ore::NV("Threshold", IC.getThreshold()) << ")"; - } - if (const char *Reason = IC.getReason()) - R << ": " << ore::NV("Reason", Reason); - return R; -} - -static std::string inlineCostStr(const InlineCost &IC) { - std::stringstream Remark; - Remark << IC; - return Remark.str(); -} - /// Return the cost only if the inliner should attempt to inline at the given /// CallSite. If we return the cost, we will emit an optimisation remark later /// using that cost, so we won't do so from this function. @@ -408,32 +379,35 @@ shouldInline(CallSite CS, function_ref GetInlineCost, Function *Caller = CS.getCaller(); if (IC.isAlways()) { - LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC) + LLVM_DEBUG(dbgs() << " Inlining: cost=always" << ", Call: " << *CS.getInstruction() << "\n"); return IC; } if (IC.isNever()) { - LLVM_DEBUG(dbgs() << " NOT Inlining " << inlineCostStr(IC) + LLVM_DEBUG(dbgs() << " NOT Inlining: cost=never" << ", Call: " << *CS.getInstruction() << "\n"); ORE.emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call) << NV("Callee", Callee) << " not inlined into " - << NV("Caller", Caller) << " because it should never be inlined " - << IC; + << NV("Caller", Caller) + << " because it should never be inlined (cost=never)"; }); - return IC; + return None; } if (!IC) { - LLVM_DEBUG(dbgs() << " NOT Inlining " << inlineCostStr(IC) + LLVM_DEBUG(dbgs() << " NOT Inlining: cost=" << IC.getCost() + << ", thres=" << IC.getThreshold() << ", Call: " << *CS.getInstruction() << "\n"); ORE.emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "TooCostly", Call) << NV("Callee", Callee) << " not inlined into " - << NV("Caller", Caller) << " because too costly to inline " << IC; + << NV("Caller", Caller) << " because too costly to inline (cost=" + << NV("Cost", IC.getCost()) + << ", threshold=" << NV("Threshold", IC.getThreshold()) << ")"; }); - return IC; + return None; } int TotalSecondaryCost = 0; @@ -454,7 +428,8 @@ shouldInline(CallSite CS, function_ref GetInlineCost, return None; } - LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC) + LLVM_DEBUG(dbgs() << " Inlining: cost=" << IC.getCost() + << ", thres=" << IC.getThreshold() << ", Call: " << *CS.getInstruction() << '\n'); return IC; } @@ -486,18 +461,6 @@ bool LegacyInlinerBase::runOnSCC(CallGraphSCC &SCC) { return inlineCalls(SCC); } -static void emit_inlined_into(OptimizationRemarkEmitter &ORE, DebugLoc &DLoc, - const BasicBlock *Block, const Function &Callee, - const Function &Caller, const InlineCost &IC) { - ORE.emit([&]() { - bool AlwaysInline = IC.isAlways(); - StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined"; - return OptimizationRemark(DEBUG_TYPE, RemarkName, DLoc, Block) - << ore::NV("Callee", &Callee) << " inlined into " - << ore::NV("Caller", &Caller) << " with " << IC; - }); -} - static bool inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG, std::function GetAssumptionCache, @@ -622,9 +585,8 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG, Optional OIC = shouldInline(CS, GetInlineCost, ORE); // If the policy determines that we should inline this function, // delete the call instead. - if (!OIC || !*OIC) { + if (!OIC) continue; - } // If this call site is dead and it is to a readonly function, we should // just delete the call instead of trying to inline it, regardless of @@ -644,21 +606,34 @@ inlineCallsImpl(CallGraphSCC &SCC, CallGraph &CG, // Attempt to inline the function. using namespace ore; - InlineResult IR = InlineCallIfPossible( - CS, InlineInfo, InlinedArrayAllocas, InlineHistoryID, - InsertLifetime, AARGetter, ImportedFunctionsStats); - if (!IR) { + if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas, + InlineHistoryID, InsertLifetime, AARGetter, + ImportedFunctionsStats)) { ORE.emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block) << NV("Callee", Callee) << " will not be inlined into " - << NV("Caller", Caller) << ": " << NV("Reason", IR.message); + << NV("Caller", Caller); }); continue; } ++NumInlined; - emit_inlined_into(ORE, DLoc, Block, *Callee, *Caller, *OIC); + ORE.emit([&]() { + bool AlwaysInline = OIC->isAlways(); + StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined"; + OptimizationRemark R(DEBUG_TYPE, RemarkName, DLoc, Block); + R << NV("Callee", Callee) << " inlined into "; + R << NV("Caller", Caller); + if (AlwaysInline) + R << " with cost=always"; + else { + R << " with cost=" << NV("Cost", OIC->getCost()); + R << " (threshold=" << NV("Threshold", OIC->getThreshold()); + R << ")"; + } + return R; + }); // If inlining this function gave us any new call sites, throw them // onto our worklist to process. They are useful inline candidates. @@ -996,7 +971,7 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, Optional OIC = shouldInline(CS, GetInlineCost, ORE); // Check whether we want to inline this callsite. - if (!OIC || !*OIC) + if (!OIC) continue; // Setup the data structure used to plumb customization into the @@ -1012,19 +987,32 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC, using namespace ore; - InlineResult IR = InlineFunction(CS, IFI); - if (!IR) { + if (!InlineFunction(CS, IFI)) { ORE.emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block) << NV("Callee", &Callee) << " will not be inlined into " - << NV("Caller", &F) << ": " << NV("Reason", IR.message); + << NV("Caller", &F); }); continue; } DidInline = true; InlinedCallees.insert(&Callee); - emit_inlined_into(ORE, DLoc, Block, Callee, F, *OIC); + ORE.emit([&]() { + bool AlwaysInline = OIC->isAlways(); + StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined"; + OptimizationRemark R(DEBUG_TYPE, RemarkName, DLoc, Block); + R << NV("Callee", &Callee) << " inlined into "; + R << NV("Caller", &F); + if (AlwaysInline) + R << " with cost=always"; + else { + R << " with cost=" << NV("Cost", OIC->getCost()); + R << " (threshold=" << NV("Threshold", OIC->getThreshold()); + R << ")"; + } + return R; + }); // Add any new callsites to defined functions to the worklist. if (!IFI.InlinedCallSites.empty()) { diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index f8226f5..ddc6e07e 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -84,15 +84,13 @@ PreserveAlignmentAssumptions("preserve-alignment-assumptions-during-inlining", cl::init(true), cl::Hidden, cl::desc("Convert align attributes to assumptions during inlining.")); -llvm::InlineResult llvm::InlineFunction(CallInst *CI, InlineFunctionInfo &IFI, - AAResults *CalleeAAR, - bool InsertLifetime) { +bool llvm::InlineFunction(CallInst *CI, InlineFunctionInfo &IFI, + AAResults *CalleeAAR, bool InsertLifetime) { return InlineFunction(CallSite(CI), IFI, CalleeAAR, InsertLifetime); } -llvm::InlineResult llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, - AAResults *CalleeAAR, - bool InsertLifetime) { +bool llvm::InlineFunction(InvokeInst *II, InlineFunctionInfo &IFI, + AAResults *CalleeAAR, bool InsertLifetime) { return InlineFunction(CallSite(II), IFI, CalleeAAR, InsertLifetime); } @@ -1493,10 +1491,9 @@ static void updateCalleeCount(BlockFrequencyInfo *CallerBFI, BasicBlock *CallBB, /// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now /// exists in the instruction stream. Similarly this will inline a recursive /// function by one level. -llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, - AAResults *CalleeAAR, - bool InsertLifetime, - Function *ForwardVarArgsTo) { +bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, + AAResults *CalleeAAR, bool InsertLifetime, + Function *ForwardVarArgsTo) { Instruction *TheCall = CS.getInstruction(); assert(TheCall->getParent() && TheCall->getFunction() && "Instruction not in function!"); @@ -1507,7 +1504,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, Function *CalledFunc = CS.getCalledFunction(); if (!CalledFunc || // Can't inline external function or indirect CalledFunc->isDeclaration()) // call! - return "external or indirect"; + return false; // The inliner does not know how to inline through calls with operand bundles // in general ... @@ -1521,7 +1518,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, if (Tag == LLVMContext::OB_funclet) continue; - return "unsupported operand bundle"; + return false; } } @@ -1540,7 +1537,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, if (!Caller->hasGC()) Caller->setGC(CalledFunc->getGC()); else if (CalledFunc->getGC() != Caller->getGC()) - return "incompatible GC"; + return false; } // Get the personality function from the callee if it contains a landing pad. @@ -1564,7 +1561,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // TODO: This isn't 100% true. Some personality functions are proper // supersets of others and can be used in place of the other. else if (CalledPersonality != CallerPersonality) - return "incompatible personality"; + return false; } // We need to figure out which funclet the callsite was in so that we may @@ -1589,7 +1586,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // for catchpads. for (const BasicBlock &CalledBB : *CalledFunc) { if (isa(CalledBB.getFirstNonPHI())) - return "catch in cleanup funclet"; + return false; } } } else if (isAsynchronousEHPersonality(Personality)) { @@ -1597,7 +1594,7 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // funclet in the callee. for (const BasicBlock &CalledBB : *CalledFunc) { if (CalledBB.isEHPad()) - return "SEH in cleanup funclet"; + return false; } } } diff --git a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks-with-hotness.ll b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks-with-hotness.ll index 9932f52..c45dd4b 100644 --- a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks-with-hotness.ll +++ b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks-with-hotness.ll @@ -25,15 +25,14 @@ ; YAML-NEXT: - Callee: tinkywinky ; YAML-NEXT: - String: ' inlined into ' ; YAML-NEXT: - Caller: main -; YAML-NEXT: - String: ' with ' -; YAML-NEXT: - String: '(cost=' +; YAML-NEXT: - String: ' with cost=' ; YAML-NEXT: - Cost: '-15000' -; YAML-NEXT: - String: ', threshold=' +; YAML-NEXT: - String: ' (threshold=' ; YAML-NEXT: - Threshold: '337' ; YAML-NEXT: - String: ')' ; YAML-NEXT: ... -; CHECK: tinkywinky inlined into main with (cost=-15000, threshold=337) (hotness: 300) +; CHECK: tinkywinky inlined into main with cost=-15000 (threshold=337) (hotness: 300) target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-scei-ps4" diff --git a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll index 03db4a7..8a3c97a 100644 --- a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll +++ b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll @@ -26,10 +26,9 @@ ; YAML-NEXT: - Callee: tinkywinky ; YAML-NEXT: - String: ' inlined into ' ; YAML-NEXT: - Caller: main -; YAML-NEXT: - String: ' with ' -; YAML-NEXT: - String: '(cost=' +; YAML-NEXT: - String: ' with cost=' ; YAML-NEXT: - Cost: '-15000' -; YAML-NEXT: - String: ', threshold=' +; YAML-NEXT: - String: ' (threshold=' ; YAML-NEXT: - Threshold: '337' ; YAML-NEXT: - String: ')' ; YAML-NEXT: ... diff --git a/llvm/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll b/llvm/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll index d1dddf1a..8111699 100644 --- a/llvm/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll +++ b/llvm/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll @@ -17,10 +17,9 @@ ; YAML-NEXT: - Callee: foo ; YAML-NEXT: - String: ' inlined into ' ; YAML-NEXT: - Caller: main -; YAML-NEXT: - String: ' with ' -; YAML-NEXT: - String: '(cost=' +; YAML-NEXT: - String: ' with cost=' ; YAML-NEXT: - Cost: '-15000' -; YAML-NEXT: - String: ', threshold=' +; YAML-NEXT: - String: ' (threshold=' ; YAML-NEXT: - Threshold: '337' ; YAML-NEXT: - String: ')' ; YAML-NEXT: ... diff --git a/llvm/test/LTO/X86/diagnostic-handler-remarks.ll b/llvm/test/LTO/X86/diagnostic-handler-remarks.ll index 94f88ec..b6d0267 100644 --- a/llvm/test/LTO/X86/diagnostic-handler-remarks.ll +++ b/llvm/test/LTO/X86/diagnostic-handler-remarks.ll @@ -53,10 +53,9 @@ ; YAML-NEXT: - Callee: foo ; YAML-NEXT: - String: ' inlined into ' ; YAML-NEXT: - Caller: main -; YAML-NEXT: - String: ' with ' -; YAML-NEXT: - String: '(cost=' +; YAML-NEXT: - String: ' with cost=' ; YAML-NEXT: - Cost: '-15000' -; YAML-NEXT: - String: ', threshold=' +; YAML-NEXT: - String: ' (threshold=' ; YAML-NEXT: - Threshold: '337' ; YAML-NEXT: - String: ')' ; YAML-NEXT: ... diff --git a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll index 239e6ef..0f0e26e 100644 --- a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll +++ b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll @@ -25,10 +25,9 @@ ; YAML1-NEXT: - Callee: foo ; YAML1-NEXT: - String: ' inlined into ' ; YAML1-NEXT: - Caller: main -; YAML1-NEXT: - String: ' with ' -; YAML1-NEXT: - String: '(cost=' +; YAML1-NEXT: - String: ' with cost=' ; YAML1-NEXT: - Cost: '-30' -; YAML1-NEXT: - String: ', threshold=' +; YAML1-NEXT: - String: ' (threshold=' ; YAML1-NEXT: - Threshold: '337' ; YAML1-NEXT: - String: ')' ; YAML1-NEXT: ... @@ -44,10 +43,9 @@ ; YAML2-NEXT: - Callee: bar ; YAML2-NEXT: - String: ' inlined into ' ; YAML2-NEXT: - Caller: foo -; YAML2-NEXT: - String: ' with ' -; YAML2-NEXT: - String: '(cost=' +; YAML2-NEXT: - String: ' with cost=' ; YAML2-NEXT: - Cost: '-30' -; YAML2-NEXT: - String: ', threshold=' +; YAML2-NEXT: - String: ' (threshold=' ; YAML2-NEXT: - Threshold: '337' ; YAML2-NEXT: - String: ')' ; YAML2-NEXT: ... diff --git a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll index d4606ba..2fd2cf8 100644 --- a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll +++ b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll @@ -22,10 +22,9 @@ ; YAML1-NEXT: - Callee: foo ; YAML1-NEXT: - String: ' inlined into ' ; YAML1-NEXT: - Caller: main -; YAML1-NEXT: - String: ' with ' -; YAML1-NEXT: - String: '(cost=' +; YAML1-NEXT: - String: ' with cost=' ; YAML1-NEXT: - Cost: '-30' -; YAML1-NEXT: - String: ', threshold=' +; YAML1-NEXT: - String: ' (threshold=' ; YAML1-NEXT: - Threshold: '337' ; YAML1-NEXT: - String: ')' ; YAML1-NEXT: ... @@ -41,10 +40,9 @@ ; YAML2-NEXT: - Callee: bar ; YAML2-NEXT: - String: ' inlined into ' ; YAML2-NEXT: - Caller: foo -; YAML2-NEXT: - String: ' with ' -; YAML2-NEXT: - String: '(cost=' +; YAML2-NEXT: - String: ' with cost=' ; YAML2-NEXT: - Cost: '-30' -; YAML2-NEXT: - String: ', threshold=' +; YAML2-NEXT: - String: ' (threshold=' ; YAML2-NEXT: - Threshold: '337' ; YAML2-NEXT: - String: ')' ; YAML2-NEXT: ... diff --git a/llvm/test/Transforms/Inline/ARM/inline-fp.ll b/llvm/test/Transforms/Inline/ARM/inline-fp.ll index be3dd2a..b4e76df 100644 --- a/llvm/test/Transforms/Inline/ARM/inline-fp.ll +++ b/llvm/test/Transforms/Inline/ARM/inline-fp.ll @@ -6,26 +6,26 @@ ; NOFP-DAG: single not inlined into test_single because too costly to inline (cost=125, threshold=75) ; NOFP-DAG: single not inlined into test_single because too costly to inline (cost=125, threshold=75) -; NOFP-DAG: single_cheap inlined into test_single_cheap with (cost=-15, threshold=75) -; NOFP-DAG: single_cheap inlined into test_single_cheap with (cost=-15015, threshold=75) +; NOFP-DAG: single_cheap inlined into test_single_cheap with cost=-15 (threshold=75) +; NOFP-DAG: single_cheap inlined into test_single_cheap with cost=-15015 (threshold=75) ; NOFP-DAG: double not inlined into test_double because too costly to inline (cost=125, threshold=75) ; NOFP-DAG: double not inlined into test_double because too costly to inline (cost=125, threshold=75) ; NOFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75) ; NOFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75) -; FULLFP-DAG: single inlined into test_single with (cost=0, threshold=75) -; FULLFP-DAG: single inlined into test_single with (cost=-15000, threshold=75) -; FULLFP-DAG: single_cheap inlined into test_single_cheap with (cost=-15, threshold=75) -; FULLFP-DAG: single_cheap inlined into test_single_cheap with (cost=-15015, threshold=75) -; FULLFP-DAG: double inlined into test_double with (cost=0, threshold=75) -; FULLFP-DAG: double inlined into test_double with (cost=-15000, threshold=75) +; FULLFP-DAG: single inlined into test_single with cost=0 (threshold=75) +; FULLFP-DAG: single inlined into test_single with cost=-15000 (threshold=75) +; FULLFP-DAG: single_cheap inlined into test_single_cheap with cost=-15 (threshold=75) +; FULLFP-DAG: single_cheap inlined into test_single_cheap with cost=-15015 (threshold=75) +; FULLFP-DAG: double inlined into test_double with cost=0 (threshold=75) +; FULLFP-DAG: double inlined into test_double with cost=-15000 (threshold=75) ; FULLFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75) ; FULLFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75) -; SINGLEFP-DAG: single inlined into test_single with (cost=0, threshold=75) -; SINGLEFP-DAG: single inlined into test_single with (cost=-15000, threshold=75) -; SINGLEFP-DAG: single_cheap inlined into test_single_cheap with (cost=-15, threshold=75) -; SINGLEFP-DAG: single_cheap inlined into test_single_cheap with (cost=-15015, threshold=75) +; SINGLEFP-DAG: single inlined into test_single with cost=0 (threshold=75) +; SINGLEFP-DAG: single inlined into test_single with cost=-15000 (threshold=75) +; SINGLEFP-DAG: single_cheap inlined into test_single_cheap with cost=-15 (threshold=75) +; SINGLEFP-DAG: single_cheap inlined into test_single_cheap with cost=-15015 (threshold=75) ; SINGLEFP-DAG: double not inlined into test_double because too costly to inline (cost=125, threshold=75) ; SINGLEFP-DAG: double not inlined into test_double because too costly to inline (cost=125, threshold=75) ; SINGLEFP-DAG: single_force_soft not inlined into test_single_force_soft because too costly to inline (cost=125, threshold=75) diff --git a/llvm/test/Transforms/Inline/optimization-remarks-hotness-threshold.ll b/llvm/test/Transforms/Inline/optimization-remarks-hotness-threshold.ll index 16d7db3..6ae9543 100644 --- a/llvm/test/Transforms/Inline/optimization-remarks-hotness-threshold.ll +++ b/llvm/test/Transforms/Inline/optimization-remarks-hotness-threshold.ll @@ -14,7 +14,7 @@ ; 4 return foo(); ; 5 } -; CHECK: remark: /tmp/s.c:4:10: foo inlined into bar with (cost={{[0-9\-]+}}, threshold={{[0-9]+}}) +; CHECK: remark: /tmp/s.c:4:10: foo inlined into bar with cost={{[0-9\-]+}} (threshold={{[0-9]+}}) ; THRESHOLD-NOT: remark ; ModuleID = '/tmp/s.c' diff --git a/llvm/test/Transforms/Inline/optimization-remarks-passed-yaml.ll b/llvm/test/Transforms/Inline/optimization-remarks-passed-yaml.ll index 0ac7635..e0ba213 100644 --- a/llvm/test/Transforms/Inline/optimization-remarks-passed-yaml.ll +++ b/llvm/test/Transforms/Inline/optimization-remarks-passed-yaml.ll @@ -17,7 +17,7 @@ ; 4 return foo(); ; 5 } -; CHECK: remark: /tmp/s.c:4:10: foo inlined into bar with (cost={{[0-9\-]+}}, threshold={{[0-9]+}}) (hotness: 30) +; CHECK: remark: /tmp/s.c:4:10: foo inlined into bar with cost={{[0-9\-]+}} (threshold={{[0-9]+}}) (hotness: 30) ; YAML: --- !Passed ; YAML-NEXT: Pass: inline @@ -31,10 +31,9 @@ ; YAML-NEXT: - String: ' inlined into ' ; YAML-NEXT: - Caller: bar ; YAML-NEXT: DebugLoc: { File: /tmp/s.c, Line: 3, Column: 0 } -; YAML-NEXT: - String: ' with ' -; YAML-NEXT: - String: '(cost=' +; YAML-NEXT: - String: ' with cost=' ; YAML-NEXT: - Cost: '{{[0-9\-]+}}' -; YAML-NEXT: - String: ', threshold=' +; YAML-NEXT: - String: ' (threshold=' ; YAML-NEXT: - Threshold: '{{[0-9]+}}' ; YAML-NEXT: - String: ')' ; YAML-NEXT: ... diff --git a/llvm/test/Transforms/Inline/optimization-remarks-with-hotness.ll b/llvm/test/Transforms/Inline/optimization-remarks-with-hotness.ll index 1a1c0f4..3614c3b 100644 --- a/llvm/test/Transforms/Inline/optimization-remarks-with-hotness.ll +++ b/llvm/test/Transforms/Inline/optimization-remarks-with-hotness.ll @@ -5,8 +5,8 @@ ; RUN: -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 \ ; RUN: | FileCheck %s -; CHECK: foo inlined into bar with (cost=always): always inline attribute (hotness: 30) -; CHECK: foz not inlined into bar because it should never be inlined (cost=never): noinline function attribute (hotness: 30) +; CHECK: foo inlined into bar with cost=always (hotness: 30) +; CHECK: foz not inlined into bar because it should never be inlined (cost=never) (hotness: 30) ; Function Attrs: alwaysinline nounwind uwtable define i32 @foo() #0 !prof !1 { diff --git a/llvm/test/Transforms/Inline/optimization-remarks.ll b/llvm/test/Transforms/Inline/optimization-remarks.ll index 72e90ae..16f7826 100644 --- a/llvm/test/Transforms/Inline/optimization-remarks.ll +++ b/llvm/test/Transforms/Inline/optimization-remarks.ll @@ -14,8 +14,8 @@ ; HOTNESS: fox will not be inlined into bar because its definition is unavailable ; NO_HOTNESS-NOT: fox will not be inlined into bar because its definition is unavailable -; CHECK: foo inlined into bar with (cost=always): always inline attribute -; CHECK: foz not inlined into bar because it should never be inlined (cost=never): noinline function attribute +; CHECK: foo inlined into bar with cost=always +; CHECK: foz not inlined into bar because it should never be inlined (cost=never) ; Function Attrs: alwaysinline nounwind uwtable define i32 @foo(i32 %x, i32 %y) #0 !prof !1 { diff --git a/llvm/test/tools/gold/X86/opt-remarks.ll b/llvm/test/tools/gold/X86/opt-remarks.ll index 7a83df4..2cca9bf 100644 --- a/llvm/test/tools/gold/X86/opt-remarks.ll +++ b/llvm/test/tools/gold/X86/opt-remarks.ll @@ -34,8 +34,7 @@ ; YAML-NEXT: - Callee: f ; YAML-NEXT: - String: ' inlined into ' ; YAML-NEXT: - Caller: _start -; YAML-NEXT: - String: ' with ' -; YAML-NEXT: - String: 'cost=' +; YAML-NEXT: - String: ' with cost=' ; YAML-NEXT: - Cost: '0' ; YAML-NEXT: - String: ' (threshold=' ; YAML-NEXT: - Threshold: '337' @@ -52,8 +51,7 @@ ; YAML-HOT-NEXT: - Callee: f ; YAML-HOT-NEXT: - String: ' inlined into ' ; YAML-HOT-NEXT: - Caller: _start -; YAML-HOT-NEXT: - String: ' with' -; YAML-HOT-NEXT: - String: 'cost=' +; YAML-HOT-NEXT: - String: ' with cost=' ; YAML-HOT-NEXT: - Cost: '0' ; YAML-HOT-NEXT: - String: ' (threshold=' ; YAML-HOT-NEXT: - Threshold: '337' -- 2.7.4