Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PassBuilder] Add ThinOrFullLTOPhase to optimizer pipeline #114577

Merged
merged 1 commit into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts,

// Ensure we lower KCFI operand bundles with -O0.
PB.registerOptimizerLastEPCallback(
[&](ModulePassManager &MPM, OptimizationLevel Level) {
[&](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase) {
if (Level == OptimizationLevel::O0 &&
LangOpts.Sanitize.has(SanitizerKind::KCFI))
MPM.addPass(createModuleToFunctionPassAdaptor(KCFIPass()));
Expand All @@ -693,8 +693,8 @@ static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts,
static void addSanitizers(const Triple &TargetTriple,
const CodeGenOptions &CodeGenOpts,
const LangOptions &LangOpts, PassBuilder &PB) {
auto SanitizersCallback = [&](ModulePassManager &MPM,
OptimizationLevel Level) {
auto SanitizersCallback = [&](ModulePassManager &MPM, OptimizationLevel Level,
ThinOrFullLTOPhase) {
if (CodeGenOpts.hasSanitizeCoverage()) {
auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
MPM.addPass(SanitizerCoveragePass(
Expand Down Expand Up @@ -778,9 +778,10 @@ static void addSanitizers(const Triple &TargetTriple,
};
if (ClSanitizeOnOptimizerEarlyEP) {
PB.registerOptimizerEarlyEPCallback(
[SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level) {
[SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level,
ThinOrFullLTOPhase Phase) {
ModulePassManager NewMPM;
SanitizersCallback(NewMPM, Level);
SanitizersCallback(NewMPM, Level, Phase);
if (!NewMPM.isEmpty()) {
// Sanitizers can abandon<GlobalsAA>.
NewMPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
Expand Down Expand Up @@ -1058,11 +1059,12 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
// TODO: Consider passing the MemoryProfileOutput to the pass builder via
// the PGOOptions, and set this up there.
if (!CodeGenOpts.MemoryProfileOutput.empty()) {
PB.registerOptimizerLastEPCallback(
[](ModulePassManager &MPM, OptimizationLevel Level) {
MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
MPM.addPass(ModuleMemProfilerPass());
});
PB.registerOptimizerLastEPCallback([](ModulePassManager &MPM,
OptimizationLevel Level,
ThinOrFullLTOPhase) {
MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
MPM.addPass(ModuleMemProfilerPass());
});
}

if (CodeGenOpts.FatLTO) {
Expand Down
20 changes: 14 additions & 6 deletions llvm/include/llvm/Passes/PassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,8 @@ class PassBuilder {
/// This extension point allows adding optimizations before the function
/// optimization pipeline.
void registerOptimizerEarlyEPCallback(
const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
const std::function<void(ModulePassManager &, OptimizationLevel,
ThinOrFullLTOPhase Phase)> &C) {
OptimizerEarlyEPCallbacks.push_back(C);
}

Expand All @@ -499,7 +500,8 @@ class PassBuilder {
/// This extension point allows adding optimizations at the very end of the
/// function optimization pipeline.
void registerOptimizerLastEPCallback(
const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
const std::function<void(ModulePassManager &, OptimizationLevel,
ThinOrFullLTOPhase)> &C) {
OptimizerLastEPCallbacks.push_back(C);
}

Expand Down Expand Up @@ -630,9 +632,11 @@ class PassBuilder {
void invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
OptimizationLevel Level);
void invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
OptimizationLevel Level);
OptimizationLevel Level,
ThinOrFullLTOPhase Phase);
void invokeOptimizerLastEPCallbacks(ModulePassManager &MPM,
OptimizationLevel Level);
OptimizationLevel Level,
ThinOrFullLTOPhase Phase);
void invokeFullLinkTimeOptimizationEarlyEPCallbacks(ModulePassManager &MPM,
OptimizationLevel Level);
void invokeFullLinkTimeOptimizationLastEPCallbacks(ModulePassManager &MPM,
Expand Down Expand Up @@ -756,9 +760,13 @@ class PassBuilder {
SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
VectorizerStartEPCallbacks;
// Module callbacks
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
ThinOrFullLTOPhase)>,
2>
OptimizerEarlyEPCallbacks;
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
ThinOrFullLTOPhase)>,
2>
OptimizerLastEPCallbacks;
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
FullLinkTimeOptimizationEarlyEPCallbacks;
Expand Down
24 changes: 14 additions & 10 deletions llvm/lib/Passes/PassBuilderPipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,14 +359,16 @@ void PassBuilder::invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
C(FPM, Level);
}
void PassBuilder::invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
OptimizationLevel Level) {
OptimizationLevel Level,
ThinOrFullLTOPhase Phase) {
for (auto &C : OptimizerEarlyEPCallbacks)
C(MPM, Level);
C(MPM, Level, Phase);
}
void PassBuilder::invokeOptimizerLastEPCallbacks(ModulePassManager &MPM,
OptimizationLevel Level) {
OptimizationLevel Level,
ThinOrFullLTOPhase Phase) {
for (auto &C : OptimizerLastEPCallbacks)
C(MPM, Level);
C(MPM, Level, Phase);
}
void PassBuilder::invokeFullLinkTimeOptimizationEarlyEPCallbacks(
ModulePassManager &MPM, OptimizationLevel Level) {
Expand Down Expand Up @@ -1464,7 +1466,7 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
if (EnableGlobalAnalyses)
MPM.addPass(RecomputeGlobalsAAPass());

invokeOptimizerEarlyEPCallbacks(MPM, Level);
invokeOptimizerEarlyEPCallbacks(MPM, Level, LTOPhase);

FunctionPassManager OptimizePM;
// Scheduling LoopVersioningLICM when inlining is over, because after that
Expand Down Expand Up @@ -1559,7 +1561,7 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(OptimizePM),
PTO.EagerlyInvalidateAnalyses));

invokeOptimizerLastEPCallbacks(MPM, Level);
invokeOptimizerLastEPCallbacks(MPM, Level, LTOPhase);

// Split out cold code. Splitting is done late to avoid hiding context from
// other optimizations and inadvertently regressing performance. The tradeoff
Expand Down Expand Up @@ -1716,8 +1718,10 @@ PassBuilder::buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level) {
// Handle Optimizer{Early,Last}EPCallbacks added by clang on PreLink. Actual
// optimization is going to be done in PostLink stage, but clang can't add
// callbacks there in case of in-process ThinLTO called by linker.
invokeOptimizerEarlyEPCallbacks(MPM, Level);
invokeOptimizerLastEPCallbacks(MPM, Level);
invokeOptimizerEarlyEPCallbacks(MPM, Level,
/*Phase=*/ThinOrFullLTOPhase::ThinLTOPreLink);
invokeOptimizerLastEPCallbacks(MPM, Level,
/*Phase=*/ThinOrFullLTOPhase::ThinLTOPreLink);

// Emit annotation remarks.
addAnnotationRemarksPass(MPM);
Expand Down Expand Up @@ -2198,7 +2202,7 @@ PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level,
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
}

invokeOptimizerEarlyEPCallbacks(MPM, Level);
invokeOptimizerEarlyEPCallbacks(MPM, Level, Phase);

if (!VectorizerStartEPCallbacks.empty()) {
FunctionPassManager FPM;
Expand All @@ -2216,7 +2220,7 @@ PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level,
CoroPM.addPass(GlobalDCEPass());
MPM.addPass(CoroConditionalWrapper(std::move(CoroPM)));

invokeOptimizerLastEPCallbacks(MPM, Level);
invokeOptimizerLastEPCallbacks(MPM, Level, Phase);

if (isLTOPreLink(Phase))
addRequiredLTOPreLinkPasses(MPM);
Expand Down
23 changes: 14 additions & 9 deletions llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@ static WWMRegisterRegAlloc
createGreedyWWMRegisterAllocator);
static WWMRegisterRegAlloc fastRegAllocWWMReg("fast", "fast register allocator",
createFastWWMRegisterAllocator);

static bool isLTOPreLink(ThinOrFullLTOPhase Phase) {
return Phase == ThinOrFullLTOPhase::FullLTOPreLink ||
Phase == ThinOrFullLTOPhase::ThinLTOPreLink;
}
} // anonymous namespace

static cl::opt<bool>
Expand Down Expand Up @@ -755,9 +760,7 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
PM.addPass(AMDGPUUnifyMetadataPass());

// We don't want to run internalization at per-module stage.
bool LTOPreLink = Phase == ThinOrFullLTOPhase::FullLTOPreLink ||
Phase == ThinOrFullLTOPhase::ThinLTOPreLink;
if (InternalizeSymbols && !LTOPreLink) {
if (InternalizeSymbols && !isLTOPreLink(Phase)) {
PM.addPass(InternalizePass(mustPreserveGV));
PM.addPass(GlobalDCEPass());
}
Expand Down Expand Up @@ -809,12 +812,14 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
});

// FIXME: Why is AMDGPUAttributor not in CGSCC?
PB.registerOptimizerLastEPCallback(
[this](ModulePassManager &MPM, OptimizationLevel Level) {
if (Level != OptimizationLevel::O0) {
MPM.addPass(AMDGPUAttributorPass(*this));
}
});
PB.registerOptimizerLastEPCallback([this](ModulePassManager &MPM,
OptimizationLevel Level,
ThinOrFullLTOPhase Phase) {
if (Level != OptimizationLevel::O0) {
if (!isLTOPreLink(Phase))
MPM.addPass(AMDGPUAttributorPass(*this));
}
});

PB.registerFullLinkTimeOptimizationLastEPCallback(
[this](ModulePassManager &PM, OptimizationLevel Level) {
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
; O0-NOT: amdgpu-attributor

; PRE-NOT: internalize
; PRE-NOT: amdgpu-attributor

define amdgpu_kernel void @kernel() {
entry:
Expand Down
4 changes: 2 additions & 2 deletions llvm/tools/opt/NewPMDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,13 @@ static void registerEPCallbacks(PassBuilder &PB) {
});
if (tryParsePipelineText<ModulePassManager>(PB, OptimizerEarlyEPPipeline))
PB.registerOptimizerEarlyEPCallback(
[&PB](ModulePassManager &PM, OptimizationLevel) {
[&PB](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) {
ExitOnError Err("Unable to parse OptimizerEarlyEP pipeline: ");
Err(PB.parsePassPipeline(PM, OptimizerEarlyEPPipeline));
});
if (tryParsePipelineText<ModulePassManager>(PB, OptimizerLastEPPipeline))
PB.registerOptimizerLastEPCallback(
[&PB](ModulePassManager &PM, OptimizationLevel) {
[&PB](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) {
ExitOnError Err("Unable to parse OptimizerLastEP pipeline: ");
Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline));
});
Expand Down
Loading