diff --git a/llvm/include/llvm/Analysis/InlineAdvisor.h b/llvm/include/llvm/Analysis/InlineAdvisor.h --- a/llvm/include/llvm/Analysis/InlineAdvisor.h +++ b/llvm/include/llvm/Analysis/InlineAdvisor.h @@ -40,6 +40,23 @@ /// training. enum class InliningAdvisorMode : int { Default, Release, Development }; +enum class InlineAdvisorContext : int { + EarlyInliner, + CGSCCInliner, + ModuleInliner, + ReplayCGSCCInliner, + ReplaySampleProfileInliner, + UnspecifiedInlinerContext, +}; + +/// Provides the context information when an instance of inline advisor is +/// constructed. +struct InlineAdvisorParams { + ThinOrFullLTOPhase LTOPhase; + + InlineAdvisorContext Context; +}; + class InlineAdvisor; /// Capture state between an inlining decision having had been made, and /// its impact being observable. When collecting model training data, this @@ -170,14 +187,28 @@ OS << "Unimplemented InlineAdvisor print\n"; } + /// IMPORTANT: + /// + /// 1. Pass name is annotated only when `--annotate-inline-phase` is true and + /// inline advisor constructor provides InlineAdvisorParams. + /// 2. When annotated, The annotated inline pass name indicates the pass + /// instance where inline decision is made; however the specific pass instance + /// may not be the accurate reason. + /// For example, a inline decision in postlink CGSCC pass could be a result + /// of applying heuristics, but could be a result of mandatory inline as + /// well. + std::string getAnnotatedInlinePassName(); + protected: - InlineAdvisor(Module &M, FunctionAnalysisManager &FAM); + InlineAdvisor(Module &M, FunctionAnalysisManager &FAM, + Optional IAP = NoneType::None); virtual std::unique_ptr getAdviceImpl(CallBase &CB) = 0; virtual std::unique_ptr getMandatoryAdvice(CallBase &CB, bool Advice); Module &M; FunctionAnalysisManager &FAM; + const Optional IAP; std::unique_ptr ImportedFunctionsStats; enum class MandatoryInliningKind { NotMandatory, Always, Never }; @@ -198,8 +229,8 @@ class DefaultInlineAdvisor : public InlineAdvisor { public: DefaultInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, - InlineParams Params) - : InlineAdvisor(M, FAM), Params(Params) {} + InlineParams Params, InlineAdvisorParams IAP) + : InlineAdvisor(M, FAM, IAP), Params(Params) {} private: std::unique_ptr getAdviceImpl(CallBase &CB) override; @@ -223,7 +254,8 @@ return !PAC.preservedWhenStateless(); } bool tryCreate(InlineParams Params, InliningAdvisorMode Mode, - const ReplayInlinerSettings &ReplaySettings); + const ReplayInlinerSettings &ReplaySettings, + InlineAdvisorParams IAP); InlineAdvisor *getAdvisor() const { return Advisor.get(); } private: diff --git a/llvm/include/llvm/Analysis/ReplayInlineAdvisor.h b/llvm/include/llvm/Analysis/ReplayInlineAdvisor.h --- a/llvm/include/llvm/Analysis/ReplayInlineAdvisor.h +++ b/llvm/include/llvm/Analysis/ReplayInlineAdvisor.h @@ -53,10 +53,12 @@ /// Get call site location as a string with the given format std::string formatCallSiteLocation(DebugLoc DLoc, const CallSiteFormat &Format); -std::unique_ptr getReplayInlineAdvisor( - Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, - std::unique_ptr OriginalAdvisor, - const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks); +std::unique_ptr +getReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, + LLVMContext &Context, + std::unique_ptr OriginalAdvisor, + const ReplayInlinerSettings &ReplaySettings, + bool EmitRemarks, InlineAdvisorParams IAP); /// Replay inline advisor that uses optimization remarks from inlining of /// previous build to guide current inlining. This is useful for inliner tuning. @@ -66,7 +68,7 @@ LLVMContext &Context, std::unique_ptr OriginalAdvisor, const ReplayInlinerSettings &ReplaySettings, - bool EmitRemarks); + bool EmitRemarks, InlineAdvisorParams IAP); std::unique_ptr getAdviceImpl(CallBase &CB) override; bool areReplayRemarksLoaded() const { return HasReplayRemarks; } diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -215,8 +215,9 @@ /// only intended for use when attempting to optimize code. If frontends /// require some transformations for semantic reasons, they should explicitly /// build them. - ModulePassManager buildModuleOptimizationPipeline(OptimizationLevel Level, - bool LTOPreLink = false); + ModulePassManager + buildModuleOptimizationPipeline(OptimizationLevel Level, + ThinOrFullLTOPhase LTOPhase); /// Build a per-module default optimization pipeline. /// @@ -609,7 +610,8 @@ void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level, bool RunProfileGen, bool IsCS, std::string ProfileFile, - std::string ProfileRemappingFile); + std::string ProfileRemappingFile, + ThinOrFullLTOPhase LTOPhase); void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel); // Extension Point callbacks diff --git a/llvm/include/llvm/Transforms/IPO/Inliner.h b/llvm/include/llvm/Transforms/IPO/Inliner.h --- a/llvm/include/llvm/Transforms/IPO/Inliner.h +++ b/llvm/include/llvm/Transforms/IPO/Inliner.h @@ -95,7 +95,9 @@ /// passes be composed to achieve the same end result. class InlinerPass : public PassInfoMixin { public: - InlinerPass(bool OnlyMandatory = false) : OnlyMandatory(OnlyMandatory) {} + InlinerPass(bool OnlyMandatory = false, + ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None) + : OnlyMandatory(OnlyMandatory), LTOPhase(LTOPhase) {} InlinerPass(InlinerPass &&Arg) = default; PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, @@ -109,6 +111,7 @@ FunctionAnalysisManager &FAM, Module &M); std::unique_ptr OwnedAdvisor; const bool OnlyMandatory; + const ThinOrFullLTOPhase LTOPhase; }; /// Module pass, wrapping the inliner pass. This works in conjunction with the @@ -121,6 +124,7 @@ public: ModuleInlinerWrapperPass( InlineParams Params = getInlineParams(), bool MandatoryFirst = true, + InlineAdvisorParams IAP = {}, InliningAdvisorMode Mode = InliningAdvisorMode::Default, unsigned MaxDevirtIterations = 0); ModuleInlinerWrapperPass(ModuleInlinerWrapperPass &&Arg) = default; @@ -146,6 +150,7 @@ private: const InlineParams Params; + const InlineAdvisorParams IAP; const InliningAdvisorMode Mode; const unsigned MaxDevirtIterations; // TODO: Clean this up so we only have one ModulePassManager. diff --git a/llvm/include/llvm/Transforms/IPO/ModuleInliner.h b/llvm/include/llvm/Transforms/IPO/ModuleInliner.h --- a/llvm/include/llvm/Transforms/IPO/ModuleInliner.h +++ b/llvm/include/llvm/Transforms/IPO/ModuleInliner.h @@ -27,8 +27,9 @@ class ModuleInlinerPass : public PassInfoMixin { public: ModuleInlinerPass(InlineParams Params = getInlineParams(), - InliningAdvisorMode Mode = InliningAdvisorMode::Default) - : Params(Params), Mode(Mode){}; + InliningAdvisorMode Mode = InliningAdvisorMode::Default, + ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None) + : Params(Params), Mode(Mode), LTOPhase(LTOPhase){}; ModuleInlinerPass(ModuleInlinerPass &&Arg) = default; PreservedAnalyses run(Module &, ModuleAnalysisManager &); @@ -39,6 +40,7 @@ std::unique_ptr OwnedAdvisor; const InlineParams Params; const InliningAdvisorMode Mode; + const ThinOrFullLTOPhase LTOPhase; }; } // end namespace llvm diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp --- a/llvm/lib/Analysis/InlineAdvisor.cpp +++ b/llvm/lib/Analysis/InlineAdvisor.cpp @@ -56,6 +56,13 @@ cl::desc("Scale to limit the cost of inline deferral"), cl::init(2), cl::Hidden); +static cl::opt AnnotateInlinePhase( + "annotate-inline-phase", cl::Hidden, cl::init(false), + cl::desc("If true, annotate inline advisor remarks " + "with LTO phase information. Relevant inline instances include " + "CGSCCInliner, ModuleInliner, ReplayInliner. Support for missed " + "inline remarks needs to be added.")); + extern cl::opt InlinerFunctionImportStats; namespace { @@ -94,6 +101,7 @@ }; } // namespace +// FIXME: Consider using getAnnotatedInlinePassName for missed inlines. void DefaultInlineAdvice::recordUnsuccessfulInliningImpl( const InlineResult &Result) { using namespace ore; @@ -109,12 +117,16 @@ void DefaultInlineAdvice::recordInliningWithCalleeDeletedImpl() { if (EmitRemarks) - emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC); + emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC, + /* ForProfileContext= */ false, + Advisor->getAnnotatedInlinePassName().c_str()); } void DefaultInlineAdvice::recordInliningImpl() { if (EmitRemarks) - emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC); + emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC, + /* ForProfileContext= */ false, + Advisor->getAnnotatedInlinePassName().c_str()); } llvm::Optional static getDefaultInlineAdvice( @@ -155,7 +167,8 @@ auto OIC = getDefaultInlineAdvice(CB, FAM, Params); return std::make_unique( this, CB, OIC, - FAM.getResult(*CB.getCaller())); + FAM.getResult(*CB.getCaller()), + /* EmitRemarks */ true); } InlineAdvice::InlineAdvice(InlineAdvisor *Advisor, CallBase &CB, @@ -186,18 +199,18 @@ bool InlineAdvisorAnalysis::Result::tryCreate( InlineParams Params, InliningAdvisorMode Mode, - const ReplayInlinerSettings &ReplaySettings) { + const ReplayInlinerSettings &ReplaySettings, InlineAdvisorParams IAP) { auto &FAM = MAM.getResult(M).getManager(); switch (Mode) { case InliningAdvisorMode::Default: LLVM_DEBUG(dbgs() << "Using default inliner heuristic.\n"); - Advisor.reset(new DefaultInlineAdvisor(M, FAM, Params)); + Advisor.reset(new DefaultInlineAdvisor(M, FAM, Params, IAP)); // Restrict replay to default advisor, ML advisors are stateful so // replay will need augmentations to interleave with them correctly. if (!ReplaySettings.ReplayFile.empty()) { Advisor = llvm::getReplayInlineAdvisor(M, FAM, M.getContext(), std::move(Advisor), ReplaySettings, - /* EmitRemarks =*/true); + /* EmitRemarks =*/true, IAP); } break; case InliningAdvisorMode::Development: @@ -500,8 +513,9 @@ PassName); } -InlineAdvisor::InlineAdvisor(Module &M, FunctionAnalysisManager &FAM) - : M(M), FAM(FAM) { +InlineAdvisor::InlineAdvisor(Module &M, FunctionAnalysisManager &FAM, + Optional IAP) + : M(M), FAM(FAM), IAP(IAP) { if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No) { ImportedFunctionsStats = std::make_unique(); @@ -523,6 +537,51 @@ Advice); } +static inline const char *getLTOPhase(ThinOrFullLTOPhase LTOPhase) { + switch (LTOPhase) { + case (ThinOrFullLTOPhase::None): + return "main"; + case (ThinOrFullLTOPhase::ThinLTOPreLink): + case (ThinOrFullLTOPhase::FullLTOPreLink): + return "prelink"; + case (ThinOrFullLTOPhase::ThinLTOPostLink): + case (ThinOrFullLTOPhase::FullLTOPostLink): + return "postlink"; + } + llvm_unreachable("unreachable"); +} + +static inline const char *getInlineAdvisorContext(InlineAdvisorContext IAC) { + switch (IAC) { + case (InlineAdvisorContext::EarlyInliner): + return "early-inline"; + case (InlineAdvisorContext::CGSCCInliner): + return "cgscc-inline"; + case (InlineAdvisorContext::ModuleInliner): + return "module-inline"; + case (InlineAdvisorContext::ReplayCGSCCInliner): + return "replay-cgscc-inline"; + case (InlineAdvisorContext::ReplaySampleProfileInliner): + return "replay-sample-profile-inline"; + case (InlineAdvisorContext::UnspecifiedInlinerContext): + return DEBUG_TYPE; + } + llvm_unreachable("unreachable"); +} + +std::string InlineAdvisor::getAnnotatedInlinePassName() { + if (!AnnotateInlinePhase || !IAP.hasValue()) + return DEBUG_TYPE; + + // IAP is constant and initialized in ctor, so compute the annotated name only + // once. + static const std::string PassName = + std::string(getLTOPhase(IAP.getValue().LTOPhase)) + "-" + + std::string(getInlineAdvisorContext(IAP.getValue().Context)); + + return PassName; +} + InlineAdvisor::MandatoryInliningKind InlineAdvisor::getMandatoryKind(CallBase &CB, FunctionAnalysisManager &FAM, OptimizationRemarkEmitter &ORE) { diff --git a/llvm/lib/Analysis/ReplayInlineAdvisor.cpp b/llvm/lib/Analysis/ReplayInlineAdvisor.cpp --- a/llvm/lib/Analysis/ReplayInlineAdvisor.cpp +++ b/llvm/lib/Analysis/ReplayInlineAdvisor.cpp @@ -26,8 +26,9 @@ ReplayInlineAdvisor::ReplayInlineAdvisor( Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, std::unique_ptr OriginalAdvisor, - const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks) - : InlineAdvisor(M, FAM), OriginalAdvisor(std::move(OriginalAdvisor)), + const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks, + InlineAdvisorParams IAP) + : InlineAdvisor(M, FAM, IAP), OriginalAdvisor(std::move(OriginalAdvisor)), ReplaySettings(ReplaySettings), EmitRemarks(EmitRemarks) { auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(ReplaySettings.ReplayFile); @@ -75,12 +76,15 @@ HasReplayRemarks = true; } -std::unique_ptr llvm::getReplayInlineAdvisor( - Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, - std::unique_ptr OriginalAdvisor, - const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks) { +std::unique_ptr +llvm::getReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, + LLVMContext &Context, + std::unique_ptr OriginalAdvisor, + const ReplayInlinerSettings &ReplaySettings, + bool EmitRemarks, InlineAdvisorParams IAP) { auto Advisor = std::make_unique( - M, FAM, Context, std::move(OriginalAdvisor), ReplaySettings, EmitRemarks); + M, FAM, Context, std::move(OriginalAdvisor), ReplaySettings, EmitRemarks, + IAP); if (!Advisor->areReplayRemarksLoaded()) Advisor.reset(); return Advisor; diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -616,7 +616,8 @@ void PassBuilder::addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level, bool RunProfileGen, bool IsCS, std::string ProfileFile, - std::string ProfileRemappingFile) { + std::string ProfileRemappingFile, + ThinOrFullLTOPhase LTOPhase) { assert(Level != OptimizationLevel::O0 && "Not expecting O0 here!"); if (!IsCS && !DisablePreInliner) { InlineParams IP; @@ -628,7 +629,9 @@ // performance testing. // FIXME: this comment is cargo culted from the old pass manager, revisit). IP.HintThreshold = Level.isOptimizingForSize() ? PreInlineThreshold : 325; - ModuleInlinerWrapperPass MIWP(IP); + ModuleInlinerWrapperPass MIWP( + IP, /* MandatoryFirst */ true, + InlineAdvisorParams{LTOPhase, InlineAdvisorContext::EarlyInliner}); CGSCCPassManager &CGPipeline = MIWP.getPM(); FunctionPassManager FPM; @@ -726,8 +729,10 @@ if (PGOOpt) IP.EnableDeferral = EnablePGOInlineDeferral; - ModuleInlinerWrapperPass MIWP(IP, PerformMandatoryInliningsFirst, - UseInlineAdvisor, MaxDevirtIterations); + ModuleInlinerWrapperPass MIWP( + IP, PerformMandatoryInliningsFirst, + InlineAdvisorParams{Phase, InlineAdvisorContext::CGSCCInliner}, + UseInlineAdvisor, MaxDevirtIterations); // Require the GlobalsAA analysis for the module so we can query it within // the CGSCC pipeline. @@ -813,7 +818,7 @@ // inline deferral logic in module inliner. IP.EnableDeferral = false; - MPM.addPass(ModuleInlinerPass(IP, UseInlineAdvisor)); + MPM.addPass(ModuleInlinerPass(IP, UseInlineAdvisor, Phase)); MPM.addPass(createModuleToFunctionPassAdaptor( buildFunctionSimplificationPipeline(Level, Phase), @@ -973,7 +978,7 @@ addPGOInstrPasses(MPM, Level, /* RunProfileGen */ PGOOpt->Action == PGOOptions::IRInstr, /* IsCS */ false, PGOOpt->ProfileFile, - PGOOpt->ProfileRemappingFile); + PGOOpt->ProfileRemappingFile, Phase); MPM.addPass(PGOIndirectCallPromotion(false, false)); } if (PGOOpt && Phase != ThinOrFullLTOPhase::ThinLTOPostLink && @@ -1127,7 +1132,9 @@ ModulePassManager PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level, - bool LTOPreLink) { + ThinOrFullLTOPhase LTOPhase) { + const bool LTOPreLink = (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink || + LTOPhase == ThinOrFullLTOPhase::FullLTOPreLink); ModulePassManager MPM; // Optimize globals now that the module is fully simplified. @@ -1167,11 +1174,11 @@ if (PGOOpt->CSAction == PGOOptions::CSIRInstr) addPGOInstrPasses(MPM, Level, /* RunProfileGen */ true, /* IsCS */ true, PGOOpt->CSProfileGenFile, - PGOOpt->ProfileRemappingFile); + PGOOpt->ProfileRemappingFile, LTOPhase); else if (PGOOpt->CSAction == PGOOptions::CSIRUse) addPGOInstrPasses(MPM, Level, /* RunProfileGen */ false, /* IsCS */ true, PGOOpt->ProfileFile, - PGOOpt->ProfileRemappingFile); + PGOOpt->ProfileRemappingFile, LTOPhase); } // Re-compute GlobalsAA here prior to function passes. This is particularly @@ -1312,13 +1319,14 @@ if (PGOOpt && PGOOpt->DebugInfoForProfiling) MPM.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); + const ThinOrFullLTOPhase LTOPhase = LTOPreLink + ? ThinOrFullLTOPhase::FullLTOPreLink + : ThinOrFullLTOPhase::None; // Add the core simplification pipeline. - MPM.addPass(buildModuleSimplificationPipeline( - Level, LTOPreLink ? ThinOrFullLTOPhase::FullLTOPreLink - : ThinOrFullLTOPhase::None)); + MPM.addPass(buildModuleSimplificationPipeline(Level, LTOPhase)); // Now add the optimization pipeline. - MPM.addPass(buildModuleOptimizationPipeline(Level, LTOPreLink)); + MPM.addPass(buildModuleOptimizationPipeline(Level, LTOPhase)); if (PGOOpt && PGOOpt->PseudoProbeForProfiling && PGOOpt->Action == PGOOptions::SampleUse) @@ -1437,7 +1445,8 @@ Level, ThinOrFullLTOPhase::ThinLTOPostLink)); // Now add the optimization pipeline. - MPM.addPass(buildModuleOptimizationPipeline(Level)); + MPM.addPass(buildModuleOptimizationPipeline( + Level, ThinOrFullLTOPhase::ThinLTOPostLink)); // Emit annotation remarks. addAnnotationRemarksPass(MPM); @@ -1600,7 +1609,11 @@ // valuable as the inliner doesn't currently care whether it is inlining an // invoke or a call. // Run the inliner now. - MPM.addPass(ModuleInlinerWrapperPass(getInlineParamsFromOptLevel(Level))); + MPM.addPass(ModuleInlinerWrapperPass( + getInlineParamsFromOptLevel(Level), + /* MandatoryFirst */ true, + InlineAdvisorParams{ThinOrFullLTOPhase::FullLTOPostLink, + InlineAdvisorContext::CGSCCInliner})); // Optimize globals again after we ran the inliner. MPM.addPass(GlobalOptPass()); @@ -1625,11 +1638,13 @@ if (PGOOpt->CSAction == PGOOptions::CSIRInstr) addPGOInstrPasses(MPM, Level, /* RunProfileGen */ true, /* IsCS */ true, PGOOpt->CSProfileGenFile, - PGOOpt->ProfileRemappingFile); + PGOOpt->ProfileRemappingFile, + ThinOrFullLTOPhase::FullLTOPostLink); else if (PGOOpt->CSAction == PGOOptions::CSIRUse) addPGOInstrPasses(MPM, Level, /* RunProfileGen */ false, /* IsCS */ true, PGOOpt->ProfileFile, - PGOOpt->ProfileRemappingFile); + PGOOpt->ProfileRemappingFile, + ThinOrFullLTOPhase::FullLTOPostLink); } // Break up allocas diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -712,8 +712,9 @@ // duration of the inliner pass, and thus the lifetime of the owned advisor. // The one we would get from the MAM can be invalidated as a result of the // inliner's activity. - OwnedAdvisor = - std::make_unique(M, FAM, getInlineParams()); + OwnedAdvisor = std::make_unique( + M, FAM, getInlineParams(), + InlineAdvisorParams{LTOPhase, InlineAdvisorContext::CGSCCInliner}); if (!CGSCCInlineReplayFile.empty()) OwnedAdvisor = getReplayInlineAdvisor( @@ -722,7 +723,9 @@ CGSCCInlineReplayScope, CGSCCInlineReplayFallback, {CGSCCInlineReplayFormat}}, - /*EmitRemarks=*/true); + /*EmitRemarks=*/true, + InlineAdvisorParams{LTOPhase, + InlineAdvisorContext::ReplayCGSCCInliner}); return *OwnedAdvisor; } @@ -1106,9 +1109,11 @@ ModuleInlinerWrapperPass::ModuleInlinerWrapperPass(InlineParams Params, bool MandatoryFirst, + InlineAdvisorParams IAP, InliningAdvisorMode Mode, unsigned MaxDevirtIterations) - : Params(Params), Mode(Mode), MaxDevirtIterations(MaxDevirtIterations) { + : Params(Params), IAP(IAP), Mode(Mode), + MaxDevirtIterations(MaxDevirtIterations) { // Run the inliner first. The theory is that we are walking bottom-up and so // the callees have already been fully optimized, and we want to inline them // into the callers so that our optimizations can reflect that. @@ -1126,7 +1131,8 @@ {CGSCCInlineReplayFile, CGSCCInlineReplayScope, CGSCCInlineReplayFallback, - {CGSCCInlineReplayFormat}})) { + {CGSCCInlineReplayFormat}}, + IAP)) { M.getContext().emitError( "Could not setup Inlining Advisor for the requested " "mode and/or options"); diff --git a/llvm/lib/Transforms/IPO/ModuleInliner.cpp b/llvm/lib/Transforms/IPO/ModuleInliner.cpp --- a/llvm/lib/Transforms/IPO/ModuleInliner.cpp +++ b/llvm/lib/Transforms/IPO/ModuleInliner.cpp @@ -84,7 +84,9 @@ // inliner pass, and thus the lifetime of the owned advisor. The one we // would get from the MAM can be invalidated as a result of the inliner's // activity. - OwnedAdvisor = std::make_unique(M, FAM, Params); + OwnedAdvisor = std::make_unique( + M, FAM, Params, + InlineAdvisorParams{LTOPhase, InlineAdvisorContext::ModuleInliner}); return *OwnedAdvisor; } @@ -109,7 +111,9 @@ LLVM_DEBUG(dbgs() << "---- Module Inliner is Running ---- \n"); auto &IAA = MAM.getResult(M); - if (!IAA.tryCreate(Params, Mode, {})) { + if (!IAA.tryCreate( + Params, Mode, {}, + InlineAdvisorParams{LTOPhase, InlineAdvisorContext::ModuleInliner})) { M.getContext().emitError( "Could not setup Inlining Advisor for the requested " "mode and/or options"); diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -95,6 +95,9 @@ using ProfileCount = Function::ProfileCount; #define DEBUG_TYPE "sample-profile" #define CSINLINE_DEBUG DEBUG_TYPE "-inline" +#define PRELINK_CSINLINE_DEBUG_TYPE "prelink-" CSINLINE_DEBUG +#define POSTLINK_CSINLINE_DEBUG_TYPE "postlink-" CSINLINE_DEBUG +#define MAIN_CSINLINE_DEBUG_TYPE "main-" CSINLINE_DEBUG STATISTIC(NumCSInlined, "Number of functions inlined with context sensitive profile"); @@ -293,6 +296,11 @@ "overwrite-existing-weights", cl::Hidden, cl::init(false), cl::desc("Ignore existing branch weights on IR and always overwrite.")); +static cl::opt AnnotateSampleProfileInlinePhase( + "annotate-sample-profile-inline-phase", cl::Hidden, cl::init(false), + cl::desc("Annotate LTO phase (prelink / postlink), or main (no LTO) for " + "sample-profile inline pass name.")); + extern cl::opt EnableExtTspBlockPlacement; namespace { @@ -580,6 +588,23 @@ TargetLibraryInfoWrapperPass *TLIWP = nullptr; }; +static inline const char *getAnnotatedRemarkPassName(ThinOrFullLTOPhase phase) { + if (!AnnotateSampleProfileInlinePhase) + return CSINLINE_DEBUG; + + switch (phase) { + case llvm::ThinOrFullLTOPhase::ThinLTOPreLink: + case llvm::ThinOrFullLTOPhase::FullLTOPreLink: + return PRELINK_CSINLINE_DEBUG_TYPE; + case llvm::ThinOrFullLTOPhase::ThinLTOPostLink: + case llvm::ThinOrFullLTOPhase::FullLTOPostLink: + return POSTLINK_CSINLINE_DEBUG_TYPE; + default: + return MAIN_CSINLINE_DEBUG_TYPE; + } + llvm_unreachable("unreachable path"); +} + } // end anonymous namespace ErrorOr SampleProfileLoader::getInstWeight(const Instruction &Inst) { @@ -1021,8 +1046,9 @@ for (auto I : Candidates) { Function *CalledFunction = I->getCalledFunction(); if (CalledFunction) { - ORE->emit(OptimizationRemarkAnalysis(CSINLINE_DEBUG, "InlineAttempt", - I->getDebugLoc(), I->getParent()) + ORE->emit(OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(LTOPhase), + "InlineAttempt", I->getDebugLoc(), + I->getParent()) << "previous inlining reattempted for " << (Hot ? "hotness: '" : "size: '") << ore::NV("Callee", CalledFunction) << "' into '" @@ -1241,7 +1267,8 @@ InlineCost Cost = shouldInlineCandidate(Candidate); if (Cost.isNever()) { - ORE->emit(OptimizationRemarkAnalysis(CSINLINE_DEBUG, "InlineFail", DLoc, BB) + ORE->emit(OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(LTOPhase), + "InlineFail", DLoc, BB) << "incompatible inlining"); return false; } @@ -1259,8 +1286,8 @@ *CalledFunction); // The call to InlineFunction erases I, so we can't pass it here. - emitInlinedIntoBasedOnCost(*ORE, DLoc, BB, *CalledFunction, - *BB->getParent(), Cost, true, CSINLINE_DEBUG); + emitInlinedIntoBasedOnCost(*ORE, DLoc, BB, *CalledFunction, *BB->getParent(), + Cost, true, getAnnotatedRemarkPassName(LTOPhase)); // Now populate the list of newly exposed call sites. if (InlinedCallSites) { @@ -1546,8 +1573,9 @@ if (!Callee || Callee->isDeclaration()) continue; - ORE->emit(OptimizationRemarkAnalysis(CSINLINE_DEBUG, "NotInline", - I->getDebugLoc(), I->getParent()) + ORE->emit(OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(LTOPhase), + "NotInline", I->getDebugLoc(), + I->getParent()) << "previous inlining not repeated: '" << ore::NV("Callee", Callee) << "' into '" << ore::NV("Caller", &F) << "'"); @@ -2000,7 +2028,9 @@ ProfileInlineReplayScope, ProfileInlineReplayFallback, {ProfileInlineReplayFormat}}, - /*EmitRemarks=*/false); + /*EmitRemarks=*/false, + InlineAdvisorParams{LTOPhase, + InlineAdvisorContext::ReplaySampleProfileInliner}); } // Apply tweaks if context-sensitive or probe-based profile is available. 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 --- a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks-with-hotness.ll +++ b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks-with-hotness.ll @@ -7,7 +7,7 @@ ; RUN: -r %t.bc,tinkywinky,p \ ; RUN: -r %t.bc,patatino,px \ ; RUN: -r %t.bc,main,px -o %t.o %t.bc -; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML +; RUN: cat %t.yaml | FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE ; Check low threshold allows remarks to emit. ; RUN: rm -f %t.t300.yaml @@ -17,7 +17,7 @@ ; RUN: -r %t.bc,tinkywinky,p \ ; RUN: -r %t.bc,patatino,px \ ; RUN: -r %t.bc,main,px -o %t.o %t.bc -; RUN: FileCheck %s -check-prefix=YAML < %t.t300.yaml +; RUN: FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE < %t.t300.yaml ; Check high threshold disallows remarks to emit. ; RUN: rm -f %t.t301.yaml @@ -52,8 +52,31 @@ ; RUN: -r %t.bc,patatino,px \ ; RUN: -r %t.bc,main,px -o %t.o %t.bc 2>&1 | count 0 +; Check that remarks are annotated with LTO phase information with `-annotate-inline-phase`. +; RUN: rm -f %t.yaml +; RUN: llvm-lto2 run -pass-remarks-output=%t.yaml \ +; RUN: -pass-remarks-with-hotness \ +; RUN: -annotate-inline-phase \ +; RUN: -r %t.bc,tinkywinky,p \ +; RUN: -r %t.bc,patatino,px \ +; RUN: -r %t.bc,main,px -o %t.o %t.bc +; RUN: cat %t.yaml | FileCheck %s -check-prefixes=YAML,YAML-ANNOTATE + +; Run again with `--annotate-inline-phase`. +; RUN: rm -f %t.t300.yaml +; RUN: llvm-lto2 run -pass-remarks-output=%t.t300.yaml \ +; RUN: -pass-remarks-with-hotness \ +; RUN: -pass-remarks-hotness-threshold=300 \ +; RUN: -annotate-inline-phase \ +; RUN: -r %t.bc,tinkywinky,p \ +; RUN: -r %t.bc,patatino,px \ +; RUN: -r %t.bc,main,px -o %t.o %t.bc +; RUN: FileCheck %s -check-prefixes=YAML,YAML-ANNOTATE < %t.t300.yaml + ; YAML: --- !Passed -; YAML-NEXT: Pass: inline +; YAML-NO-ANNOTATE-NEXT: Pass: inline +; YAML-ANNOTATE-NEXT: Pass: postlink-cgscc-inline + ; YAML-NEXT: Name: Inlined ; YAML-NEXT: Function: main ; YAML-NEXT: Hotness: 300 diff --git a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll --- a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll +++ b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll @@ -8,7 +8,7 @@ ; RUN: -r %t.bc,tinkywinky,p \ ; RUN: -r %t.bc,patatino,px \ ; RUN: -r %t.bc,main,px -o %t.o %t.bc -; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML +; RUN: cat %t.yaml | FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE ; Try again with ThinLTO ; RUN: opt -module-summary %s -o %t.bc @@ -18,10 +18,34 @@ ; RUN: -r %t.bc,tinkywinky,p \ ; RUN: -r %t.bc,patatino,px \ ; RUN: -r %t.bc,main,px -o %t.o %t.bc -; RUN: cat %t.thin.1.yaml | FileCheck %s -check-prefix=YAML +; RUN: cat %t.thin.1.yaml | FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE + +; Check that remarks are annotated with LTO phase information with `-annotate-inline-phase`. +; First try with Regular LTO +; RUN: llvm-as < %s >%t.bc +; RUN: rm -f %t.yaml +; RUN: llvm-lto2 run -pass-remarks-output=%t.yaml \ +; RUN: -pass-remarks-filter=inline \ +; RUN: -annotate-inline-phase \ +; RUN: -r %t.bc,tinkywinky,p \ +; RUN: -r %t.bc,patatino,px \ +; RUN: -r %t.bc,main,px -o %t.o %t.bc +; RUN: cat %t.yaml | FileCheck %s -check-prefixes=YAML,YAML-POSTLINK-LTO + +; Try again with ThinLTO +; RUN: opt -module-summary %s -o %t.bc +; RUN: rm -f %t.thin.1.yaml +; RUN: llvm-lto2 run -pass-remarks-output=%t \ +; RUN: -pass-remarks-filter=inline \ +; RUN: -annotate-inline-phase \ +; RUN: -r %t.bc,tinkywinky,p \ +; RUN: -r %t.bc,patatino,px \ +; RUN: -r %t.bc,main,px -o %t.o %t.bc +; RUN: cat %t.thin.1.yaml | FileCheck %s -check-prefixes=YAML,YAML-POSTLINK-LTO ; YAML: --- !Passed -; YAML-NEXT: Pass: inline +; YAML-NO-ANNOTATE: Pass: inline +; YAML-POSTLINK-LTO-NEXT: Pass: postlink-cgscc-inline ; YAML-NEXT: Name: Inlined ; YAML-NEXT: Function: main ; YAML-NEXT: Args: diff --git a/llvm/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll b/llvm/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll --- a/llvm/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll +++ b/llvm/test/LTO/X86/diagnostic-handler-remarks-with-hotness.ll @@ -6,22 +6,46 @@ ; RUN: llvm-lto -lto-pass-remarks-output=%t.yaml \ ; RUN: -lto-pass-remarks-with-hotness \ ; RUN: -exported-symbol _main -o %t.o %t.bc -; RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s +; RUN: cat %t.yaml | FileCheck -check-prefixes=YAML,YAML-NO-ANNOTATE %s ; RUN: llvm-lto -lto-pass-remarks-output=%t.t300.yaml \ ; RUN: -lto-pass-remarks-with-hotness \ ; RUN: -lto-pass-remarks-hotness-threshold=300 \ ; RUN: -exported-symbol _main -o %t.o %t.bc -; RUN: FileCheck -check-prefix=YAML %s < %t.t300.yaml +; RUN: FileCheck -check-prefixes=YAML,YAML-NO-ANNOTATE %s < %t.t300.yaml ; RUN: llvm-lto -lto-pass-remarks-output=%t.t301.yaml \ ; RUN: -lto-pass-remarks-with-hotness \ ; RUN: -lto-pass-remarks-hotness-threshold=301 \ ; RUN: -exported-symbol _main -o %t.o %t.bc -; RUN: not FileCheck -check-prefix=YAML %s < %t.t301.yaml +; RUN: not FileCheck -check-prefixes=YAML,YAML-NO-ANNOTATE %s < %t.t301.yaml + +; Check that remarks are annotated with LTO phase information with `-annotate-inline-lto-phase`. +; RUN: llvm-as < %s >%t.bc +; RUN: rm -f %t.yaml %t.t300.yaml %t.t301.yaml +; RUN: llvm-lto -lto-pass-remarks-output=%t.yaml \ +; RUN: -lto-pass-remarks-with-hotness \ +; RUN: -annotate-inline-phase \ +; RUN: -exported-symbol _main -o %t.o %t.bc +; RUN: cat %t.yaml | FileCheck -check-prefixes=YAML,YAML-ANNOTATE %s + +; RUN: llvm-lto -lto-pass-remarks-output=%t.t300.yaml \ +; RUN: -lto-pass-remarks-with-hotness \ +; RUN: -lto-pass-remarks-hotness-threshold=300 \ +; RUN: -annotate-inline-phase \ +; RUN: -exported-symbol _main -o %t.o %t.bc +; RUN: FileCheck -check-prefixes=YAML,YAML-ANNOTATE %s < %t.t300.yaml + +; RUN: llvm-lto -lto-pass-remarks-output=%t.t301.yaml \ +; RUN: -lto-pass-remarks-with-hotness \ +; RUN: -lto-pass-remarks-hotness-threshold=301 \ +; RUN: -annotate-inline-phase \ +; RUN: -exported-symbol _main -o %t.o %t.bc +; RUN: not FileCheck -check-prefixes=YAML,YAML-ANNOTATE %s < %t.t301.yaml ; YAML: --- !Passed -; YAML-NEXT: Pass: inline +; YAML-NO-ANNOTATE-NEXT: Pass: inline +; YAML-ANNOTATE-NEXT: Pass: postlink-cgscc-inline ; YAML-NEXT: Name: Inlined ; YAML-NEXT: Function: main ; YAML-NEXT: Hotness: 300 diff --git a/llvm/test/LTO/X86/diagnostic-handler-remarks.ll b/llvm/test/LTO/X86/diagnostic-handler-remarks.ll --- a/llvm/test/LTO/X86/diagnostic-handler-remarks.ll +++ b/llvm/test/LTO/X86/diagnostic-handler-remarks.ll @@ -37,7 +37,17 @@ ; RUN: -exported-symbol _func2 \ ; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \ ; RUN: FileCheck %s -allow-empty -; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML +; RUN: cat %t.yaml | FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE + +; Try again with `-annotate-inline-lto-phase`. +; RUN: rm -f %t.yaml +; RUN: llvm-lto \ +; RUN: -annotate-inline-phase \ +; RUN: -lto-pass-remarks-output=%t.yaml \ +; RUN: -exported-symbol _func2 \ +; RUN: -exported-symbol _main -o %t.o %t.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty +; RUN: cat %t.yaml | FileCheck %s -check-prefixes=YAML,YAML-ANNOTATE ; REMARKS: remark: {{.*}} 'foo' inlined into 'main' ; REMARKS: remark: {{.*}} loop not vectorized: cannot prove it is safe to reorder memory operations @@ -50,7 +60,8 @@ ; NM: main ; YAML: --- !Passed -; YAML-NEXT: Pass: inline +; YAML-NO-ANNOTATE-NEXT: Pass: inline +; YAML-ANNOTATE-NEXT: Pass: postlink-cgscc-inline ; YAML-NEXT: Name: Inlined ; YAML-NEXT: Function: main ; YAML-NEXT: Args: diff --git a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll --- a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll +++ b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks-with-hotness.ll @@ -13,12 +13,31 @@ ; CHECK-NOT: remark: ; CHECK-NOT: llvm-lto: +; Verify that bar is imported 'and' inlined into 'foo' +; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefixes=YAML1,YAML1-NO-ANNOTATE ; Verify that bar is imported 'and' inlined into 'foo' -; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefix=YAML1 +; RUN: cat %t.yaml.thin.1.yaml | FileCheck %s -check-prefixes=YAML2,YAML2-NO-ANNOTATE + +; Run again with -annotate-inline-phase + +; RUN: llvm-lto -thinlto-action=run \ +; RUN: -lto-pass-remarks-output=%t.yaml \ +; RUN: -annotate-inline-phase \ +; RUN: -lto-pass-remarks-with-hotness \ +; RUN: -exported-symbol _func2 \ +; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty +; CHECK-NOT: remark: +; CHECK-NOT: llvm-lto: + +; Verify that pass name is annotated with LTO phase information. +; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefixes=YAML1,YAML1-ANNOTATE + ; YAML1: --- !Passed ; YAML1: --- !Passed -; YAML1-NEXT: Pass: inline +; YAML1-NO-ANNOTATE-NEXT: Pass: inline +; YAML1-ANNOTATE-NEXT: Pass: postlink-cgscc-inline ; YAML1-NEXT: Name: Inlined ; YAML1-NEXT: Function: main ; YAML1-NEXT: Hotness: 50 @@ -38,9 +57,10 @@ ; Verify that bar is imported 'and' inlined into 'foo' -; RUN: cat %t.yaml.thin.1.yaml | FileCheck %s -check-prefix=YAML2 +; RUN: cat %t.yaml.thin.1.yaml | FileCheck %s -check-prefixes=YAML2,YAML2-ANNOTATE ; YAML2: --- !Passed -; YAML2-NEXT: Pass: inline +; YAML2-NO-ANNOTATE-NEXT: Pass: inline +; YAML2-ANNOTATE-NEXT: Pass: postlink-cgscc-inline ; YAML2-NEXT: Name: Inlined ; YAML2-NEXT: Function: foo ; YAML2-NEXT: Args: diff --git a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll --- a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll +++ b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll @@ -15,10 +15,34 @@ ; Verify that bar is imported 'and' inlined into 'foo' -; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefix=YAML1 +; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefixes=YAML1,YAML1-NO-ANNOTATE + +; Verify that bar is imported 'and' inlined into 'foo' +; RUN: cat %t.yaml.thin.1.yaml | FileCheck %s -check-prefixes=YAML2,YAML2-NO-ANNOTATE + +; Try again with -annotate-inline-phase +; RUN: rm -f %t.yaml.thin.0.yaml %t.yaml.thin.1.yaml +; RUN: llvm-lto -thinlto-action=run \ +; RUN: -annotate-inline-phase \ +; RUN: -lto-pass-remarks-output=%t.yaml \ +; RUN: -lto-pass-remarks-filter=inline \ +; RUN: -lto-pass-remarks-format=yaml \ +; RUN: -exported-symbol _func2 \ +; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty +; CHECK-NOT: remark: +; CHECK-NOT: llvm-lto: + +; Verify thati inline happens the same way and pass name are annotated with LTO phase information. +; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefixes=YAML1,YAML1-ANNOTATE + +; Verify that bar is imported 'and' inlined into 'foo' +; RUN: cat %t.yaml.thin.1.yaml | FileCheck %s -check-prefixes=YAML2,YAML2-ANNOTATE + ; YAML1: --- !Passed ; YAML1: --- !Passed -; YAML1-NEXT: Pass: inline +; YAML1-NO-ANNOTATE: Pass: inline +; YAML1-ANNOTATE-NEXT: Pass: postlink-cgscc-inline ; YAML1-NEXT: Name: Inlined ; YAML1-NEXT: Function: main ; YAML1-NEXT: Args: @@ -35,11 +59,9 @@ ; YAML1-NEXT: - String: ')' ; YAML1-NEXT: ... - -; Verify that bar is imported 'and' inlined into 'foo' -; RUN: cat %t.yaml.thin.1.yaml | FileCheck %s -check-prefix=YAML2 ; YAML2: --- !Passed -; YAML2-NEXT: Pass: inline +; YAML2-NO-ANNOTATE: Pass: inline +; YAML2-ANNOTATE-NEXT: Pass: postlink-cgscc-inline ; YAML2-NEXT: Name: Inlined ; YAML2-NEXT: Function: foo ; YAML2-NEXT: Args: diff --git a/llvm/test/Transforms/Inline/optimization-remarks-passed-yaml.ll b/llvm/test/Transforms/Inline/optimization-remarks-passed-yaml.ll --- a/llvm/test/Transforms/Inline/optimization-remarks-passed-yaml.ll +++ b/llvm/test/Transforms/Inline/optimization-remarks-passed-yaml.ll @@ -1,17 +1,24 @@ ; RUN: opt < %s -S -inline -pass-remarks-output=%t -pass-remarks=inline \ ; RUN: -pass-remarks-missed=inline -pass-remarks-analysis=inline \ ; RUN: -pass-remarks-with-hotness 2>&1 | FileCheck %s -; RUN: cat %t | FileCheck -check-prefix=YAML %s +; RUN: cat %t | FileCheck -check-prefixes=YAML,YAML-NO-ANNOTATE %s ; RUN: opt < %s -S -passes=inline -pass-remarks-output=%t -pass-remarks=inline \ ; RUN: -pass-remarks-missed=inline -pass-remarks-analysis=inline \ ; RUN: -pass-remarks-with-hotness 2>&1 | FileCheck %s -; RUN: cat %t | FileCheck -check-prefix=YAML %s +; RUN: cat %t | FileCheck -check-prefixes=YAML,YAML-NO-ANNOTATE %s ; RUN: opt < %s -S -passes=inliner-wrapper -pass-remarks-output=%t -pass-remarks=inline \ ; RUN: -pass-remarks-missed=inline -pass-remarks-analysis=inline \ +; RUN: -annotate-inline-phase=false \ ; RUN: -pass-remarks-with-hotness 2>&1 | FileCheck %s -; RUN: cat %t | FileCheck -check-prefix=YAML %s +; RUN: cat %t | FileCheck -check-prefixes=YAML,YAML-NO-ANNOTATE %s + +; RUN: opt < %s -S -passes=inliner-wrapper -pass-remarks-output=%t -pass-remarks=inline \ +; RUN: -pass-remarks-missed=inline -pass-remarks-analysis=inline \ +; RUN: -annotate-inline-phase \ +; RUN: -pass-remarks-with-hotness 2>&1 | FileCheck %s +; RUN: cat %t | FileCheck -check-prefixes=YAML,YAML-ANNOTATE %s ; Check the YAML file for inliner-generated passed and analysis remarks. This ; is the input: @@ -25,7 +32,8 @@ ; CHECK: remark: /tmp/s.c:4:10: 'foo' inlined into 'bar' with (cost={{[0-9\-]+}}, threshold={{[0-9]+}}) at callsite bar:1:10; (hotness: 30) ; YAML: --- !Passed -; YAML-NEXT: Pass: inline +; YAML-NO-ANNOTATE-NEXT: Pass: inline +; YAML-ANNOTATE-NEXT: Pass: main-early-inline ; YAML-NEXT: Name: Inlined ; YAML-NEXT: DebugLoc: { File: '/tmp/s.c', Line: 4, Column: 10 } ; YAML-NEXT: Function: bar diff --git a/llvm/test/Transforms/SampleProfile/remarks.ll b/llvm/test/Transforms/SampleProfile/remarks.ll --- a/llvm/test/Transforms/SampleProfile/remarks.ll +++ b/llvm/test/Transforms/SampleProfile/remarks.ll @@ -1,7 +1,12 @@ ; RUN: opt < %s -sample-profile -sample-profile-file=%S/Inputs/remarks.prof -S -pass-remarks=sample-profile -pass-remarks-output=%t.opt.yaml 2>&1 | FileCheck %s -; RUN: FileCheck %s -check-prefix=YAML < %t.opt.yaml +; RUN: FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE < %t.opt.yaml ; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/remarks.prof -S -pass-remarks=sample-profile -pass-remarks-output=%t.opt.yaml 2>&1 | FileCheck %s -; RUN: FileCheck %s -check-prefix=YAML < %t.opt.yaml +; RUN: FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE < %t.opt.yaml + +; RUN: opt < %s -sample-profile -annotate-sample-profile-inline-phase -sample-profile-file=%S/Inputs/remarks.prof -S -pass-remarks=sample-profile -pass-remarks-output=%t.opt.yaml 2>&1 | FileCheck %s +; RUN: FileCheck %s -check-prefixes=YAML,YAML-ANNOTATE < %t.opt.yaml +; RUN: opt < %s -passes=sample-profile -annotate-sample-profile-inline-phase -sample-profile-file=%S/Inputs/remarks.prof -S -pass-remarks=sample-profile -pass-remarks-output=%t.opt.yaml 2>&1 | FileCheck %s +; RUN: FileCheck %s -check-prefixes=YAML,YAML-ANNOTATE < %t.opt.yaml ; Original test case. ; @@ -32,7 +37,8 @@ ; Checking to see if YAML file is generated and contains remarks ;YAML: --- !Passed -;YAML-NEXT: Pass: sample-profile-inline +;YAML-NO-ANNOTATE-NEXT: Pass: sample-profile-inline +;YAML-ANNOTATE-NEXT: Pass: main-sample-profile-inline ;YAML-NEXT: Name: Inlined ;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 13, Column: 21 } ;YAML-NEXT: Function: main @@ -60,7 +66,8 @@ ;YAML-NEXT: - String: ';' ;YAML-NEXT: ... ;YAML: --- !Passed -;YAML-NEXT: Pass: sample-profile-inline +;YAML-NO-ANNOTATE-NEXT: Pass: sample-profile-inline +;YAML-ANNOTATE-NEXT: Pass: main-sample-profile-inline ;YAML-NEXT: Name: AlwaysInline ;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 9, Column: 19 } ;YAML-NEXT: Function: main