[Inline][Remark][NFC] Optionally provide inline context to inline

advisor.

This patch has no functional change, and merely a preparation patch for
main functional change. The motivating use case is to annotate inline
remark pass name with context information (e.g. prelink or postlink,
CGSCC or always-inliner), see D125495 for more details.

Differential Revision: https://reviews.llvm.org/D126824
This commit is contained in:
Mingming Liu 2022-06-01 08:53:31 -07:00
parent e7b929d756
commit 8601f269f1
2 changed files with 95 additions and 7 deletions

View File

@ -40,6 +40,28 @@ struct ReplayInlinerSettings;
/// training.
enum class InliningAdvisorMode : int { Default, Release, Development };
// Each entry represents an inline driver.
enum class InlinePass : int {
AlwaysInliner,
CGSCCInliner,
EarlyInliner,
ModuleInliner,
MLInliner,
ReplayCGSCCInliner,
ReplaySampleProfileInliner,
SampleProfileInliner,
};
/// Provides context on when an inline advisor is constructed in the pipeline
/// (e.g., link phase, inline driver).
struct InlineContext {
ThinOrFullLTOPhase LTOPhase;
InlinePass Pass;
};
std::string AnnotateInlinePassName(InlineContext IC);
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 +192,19 @@ public:
OS << "Unimplemented InlineAdvisor print\n";
}
/// NOTE pass name is annotated only when inline advisor constructor provides InlineContext.
const char *getAnnotatedInlinePassName();
protected:
InlineAdvisor(Module &M, FunctionAnalysisManager &FAM);
InlineAdvisor(Module &M, FunctionAnalysisManager &FAM,
Optional<InlineContext> IC = NoneType::None);
virtual std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) = 0;
virtual std::unique_ptr<InlineAdvice> getMandatoryAdvice(CallBase &CB,
bool Advice);
Module &M;
FunctionAnalysisManager &FAM;
const Optional<InlineContext> IC;
std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
enum class MandatoryInliningKind { NotMandatory, Always, Never };

View File

@ -81,7 +81,8 @@ private:
void recordUnsuccessfulInliningImpl(const InlineResult &Result) override {
if (IsInliningRecommended)
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
return OptimizationRemarkMissed(Advisor->getAnnotatedInlinePassName(),
"NotInlined", DLoc, Block)
<< "'" << NV("Callee", Callee) << "' is not AlwaysInline into '"
<< NV("Caller", Caller)
<< "': " << NV("Reason", Result.getFailureReason());
@ -100,7 +101,8 @@ void DefaultInlineAdvice::recordUnsuccessfulInliningImpl(
llvm::setInlineRemark(*OriginalCB, std::string(Result.getFailureReason()) +
"; " + inlineCostStr(*OIC));
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
return OptimizationRemarkMissed(Advisor->getAnnotatedInlinePassName(),
"NotInlined", DLoc, Block)
<< "'" << NV("Callee", Callee) << "' is not inlined into '"
<< NV("Caller", Caller)
<< "': " << NV("Reason", Result.getFailureReason());
@ -109,12 +111,16 @@ void DefaultInlineAdvice::recordUnsuccessfulInliningImpl(
void DefaultInlineAdvice::recordInliningWithCalleeDeletedImpl() {
if (EmitRemarks)
emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC);
emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC,
/* ForProfileContext= */ false,
Advisor->getAnnotatedInlinePassName());
}
void DefaultInlineAdvice::recordInliningImpl() {
if (EmitRemarks)
emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC);
emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC,
/* ForProfileContext= */ false,
Advisor->getAnnotatedInlinePassName());
}
llvm::Optional<llvm::InlineCost> static getDefaultInlineAdvice(
@ -500,8 +506,9 @@ void llvm::emitInlinedIntoBasedOnCost(
PassName);
}
InlineAdvisor::InlineAdvisor(Module &M, FunctionAnalysisManager &FAM)
: M(M), FAM(FAM) {
InlineAdvisor::InlineAdvisor(Module &M, FunctionAnalysisManager &FAM,
Optional<InlineContext> IC)
: M(M), FAM(FAM), IC(IC) {
if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No) {
ImportedFunctionsStats =
std::make_unique<ImportedFunctionsInliningStatistics>();
@ -523,6 +530,60 @@ std::unique_ptr<InlineAdvice> InlineAdvisor::getMandatoryAdvice(CallBase &CB,
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(InlinePass IP) {
switch (IP) {
case (InlinePass::AlwaysInliner):
return "always-inline";
case (InlinePass::CGSCCInliner):
return "cgscc-inline";
case (InlinePass::EarlyInliner):
return "early-inline";
case (InlinePass::MLInliner):
return "ml-inline";
case (InlinePass::ModuleInliner):
return "module-inline";
case (InlinePass::ReplayCGSCCInliner):
return "replay-cgscc-inline";
case (InlinePass::ReplaySampleProfileInliner):
return "replay-sample-profile-inline";
case (InlinePass::SampleProfileInliner):
return "sample-profile-inline";
}
llvm_unreachable("unreachable");
}
std::string llvm::AnnotateInlinePassName(InlineContext IC) {
return std::string(getLTOPhase(IC.LTOPhase)) + "-" +
std::string(getInlineAdvisorContext(IC.Pass));
}
const char *InlineAdvisor::getAnnotatedInlinePassName() {
if (!IC.hasValue())
return DEBUG_TYPE;
// IC is constant and initialized in constructor, so compute the annotated
// name only once.
static const std::string PassName =
llvm::AnnotateInlinePassName(IC.getValue());
return PassName.c_str();
}
InlineAdvisor::MandatoryInliningKind
InlineAdvisor::getMandatoryKind(CallBase &CB, FunctionAnalysisManager &FAM,
OptimizationRemarkEmitter &ORE) {