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,24 @@ 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 +1047,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 +1268,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 +1287,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 +1574,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) << "'"); diff --git a/llvm/test/Transforms/SampleProfile/pseudo-probe-inline.ll b/llvm/test/Transforms/SampleProfile/pseudo-probe-inline.ll --- a/llvm/test/Transforms/SampleProfile/pseudo-probe-inline.ll +++ b/llvm/test/Transforms/SampleProfile/pseudo-probe-inline.ll @@ -1,9 +1,15 @@ -; RUN: opt < %s -passes=pseudo-probe,sample-profile -sample-profile-file=%S/Inputs/pseudo-probe-inline.prof -S -pass-remarks=sample-profile -sample-profile-prioritized-inline=0 -pass-remarks-output=%t.opt.yaml 2>&1 | FileCheck %s -; RUN: FileCheck %s -check-prefix=YAML < %t.opt.yaml +; RUN: opt < %s -passes=pseudo-probe,sample-profile -sample-profile-file=%S/Inputs/pseudo-probe-inline.prof -S -pass-remarks=sample-profile -sample-profile-prioritized-inline=0 -pass-remarks-output=%t.opt.yaml 2>&1 | FileCheck %s +; RUN: FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE < %t.opt.yaml ; RUN: llvm-profdata merge --sample --extbinary %S/Inputs/pseudo-probe-inline.prof -o %t2 -; RUN: opt < %s -passes=pseudo-probe,sample-profile -sample-profile-file=%t2 -S -pass-remarks=sample-profile -sample-profile-prioritized-inline=0 -pass-remarks-output=%t2.opt.yaml 2>&1 | FileCheck %s -; RUN: FileCheck %s -check-prefix=YAML < %t2.opt.yaml +; RUN: opt < %s -passes=pseudo-probe,sample-profile -sample-profile-file=%t2 -S -pass-remarks=sample-profile -sample-profile-prioritized-inline=0 -pass-remarks-output=%t2.opt.yaml 2>&1 | FileCheck %s +; RUN: FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE < %t2.opt.yaml + +; RUN: opt < %s -passes=pseudo-probe,sample-profile -annotate-sample-profile-inline-phase=true -sample-profile-file=%S/Inputs/pseudo-probe-inline.prof -S -pass-remarks=sample-profile -sample-profile-prioritized-inline=0 -pass-remarks-output=%t3.opt.yaml 2>&1 | FileCheck %s +; RUN: FileCheck %s -check-prefixes=YAML,YAML-ANNOTATE < %t3.opt.yaml + +; RUN: opt < %s -passes=pseudo-probe,sample-profile -annotate-sample-profile-inline-phase=true -sample-profile-file=%t2 -S -pass-remarks=sample-profile -sample-profile-prioritized-inline=0 -pass-remarks-output=%t4.opt.yaml 2>&1 | FileCheck %s +; RUN: FileCheck %s -check-prefixes=YAML,YAML-ANNOTATE < %t4.opt.yaml target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @@ -74,7 +80,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: test.cpp, Line: 10, Column: 11 } ;YAML-NEXT: Function: foo 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