Skip to content

Commit 390300d

Browse files
authored
[PassBuilder] Add ThinOrFullLTOPhase to optimizer pipeline (#114577)
1 parent dc45ff1 commit 390300d

File tree

6 files changed

+57
-37
lines changed

6 files changed

+57
-37
lines changed

Diff for: clang/lib/CodeGen/BackendUtil.cpp

+12-10
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts,
674674

675675
// Ensure we lower KCFI operand bundles with -O0.
676676
PB.registerOptimizerLastEPCallback(
677-
[&](ModulePassManager &MPM, OptimizationLevel Level) {
677+
[&](ModulePassManager &MPM, OptimizationLevel Level, ThinOrFullLTOPhase) {
678678
if (Level == OptimizationLevel::O0 &&
679679
LangOpts.Sanitize.has(SanitizerKind::KCFI))
680680
MPM.addPass(createModuleToFunctionPassAdaptor(KCFIPass()));
@@ -693,8 +693,8 @@ static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts,
693693
static void addSanitizers(const Triple &TargetTriple,
694694
const CodeGenOptions &CodeGenOpts,
695695
const LangOptions &LangOpts, PassBuilder &PB) {
696-
auto SanitizersCallback = [&](ModulePassManager &MPM,
697-
OptimizationLevel Level) {
696+
auto SanitizersCallback = [&](ModulePassManager &MPM, OptimizationLevel Level,
697+
ThinOrFullLTOPhase) {
698698
if (CodeGenOpts.hasSanitizeCoverage()) {
699699
auto SancovOpts = getSancovOptsFromCGOpts(CodeGenOpts);
700700
MPM.addPass(SanitizerCoveragePass(
@@ -778,9 +778,10 @@ static void addSanitizers(const Triple &TargetTriple,
778778
};
779779
if (ClSanitizeOnOptimizerEarlyEP) {
780780
PB.registerOptimizerEarlyEPCallback(
781-
[SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level) {
781+
[SanitizersCallback](ModulePassManager &MPM, OptimizationLevel Level,
782+
ThinOrFullLTOPhase Phase) {
782783
ModulePassManager NewMPM;
783-
SanitizersCallback(NewMPM, Level);
784+
SanitizersCallback(NewMPM, Level, Phase);
784785
if (!NewMPM.isEmpty()) {
785786
// Sanitizers can abandon<GlobalsAA>.
786787
NewMPM.addPass(RequireAnalysisPass<GlobalsAA, llvm::Module>());
@@ -1058,11 +1059,12 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
10581059
// TODO: Consider passing the MemoryProfileOutput to the pass builder via
10591060
// the PGOOptions, and set this up there.
10601061
if (!CodeGenOpts.MemoryProfileOutput.empty()) {
1061-
PB.registerOptimizerLastEPCallback(
1062-
[](ModulePassManager &MPM, OptimizationLevel Level) {
1063-
MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
1064-
MPM.addPass(ModuleMemProfilerPass());
1065-
});
1062+
PB.registerOptimizerLastEPCallback([](ModulePassManager &MPM,
1063+
OptimizationLevel Level,
1064+
ThinOrFullLTOPhase) {
1065+
MPM.addPass(createModuleToFunctionPassAdaptor(MemProfilerPass()));
1066+
MPM.addPass(ModuleMemProfilerPass());
1067+
});
10661068
}
10671069

10681070
if (CodeGenOpts.FatLTO) {

Diff for: llvm/include/llvm/Passes/PassBuilder.h

+14-6
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,8 @@ class PassBuilder {
490490
/// This extension point allows adding optimizations before the function
491491
/// optimization pipeline.
492492
void registerOptimizerEarlyEPCallback(
493-
const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
493+
const std::function<void(ModulePassManager &, OptimizationLevel,
494+
ThinOrFullLTOPhase Phase)> &C) {
494495
OptimizerEarlyEPCallbacks.push_back(C);
495496
}
496497

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

@@ -630,9 +632,11 @@ class PassBuilder {
630632
void invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
631633
OptimizationLevel Level);
632634
void invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
633-
OptimizationLevel Level);
635+
OptimizationLevel Level,
636+
ThinOrFullLTOPhase Phase);
634637
void invokeOptimizerLastEPCallbacks(ModulePassManager &MPM,
635-
OptimizationLevel Level);
638+
OptimizationLevel Level,
639+
ThinOrFullLTOPhase Phase);
636640
void invokeFullLinkTimeOptimizationEarlyEPCallbacks(ModulePassManager &MPM,
637641
OptimizationLevel Level);
638642
void invokeFullLinkTimeOptimizationLastEPCallbacks(ModulePassManager &MPM,
@@ -756,9 +760,13 @@ class PassBuilder {
756760
SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
757761
VectorizerStartEPCallbacks;
758762
// Module callbacks
759-
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
763+
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
764+
ThinOrFullLTOPhase)>,
765+
2>
760766
OptimizerEarlyEPCallbacks;
761-
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
767+
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
768+
ThinOrFullLTOPhase)>,
769+
2>
762770
OptimizerLastEPCallbacks;
763771
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
764772
FullLinkTimeOptimizationEarlyEPCallbacks;

Diff for: llvm/lib/Passes/PassBuilderPipelines.cpp

+14-10
Original file line numberDiff line numberDiff line change
@@ -359,14 +359,16 @@ void PassBuilder::invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
359359
C(FPM, Level);
360360
}
361361
void PassBuilder::invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
362-
OptimizationLevel Level) {
362+
OptimizationLevel Level,
363+
ThinOrFullLTOPhase Phase) {
363364
for (auto &C : OptimizerEarlyEPCallbacks)
364-
C(MPM, Level);
365+
C(MPM, Level, Phase);
365366
}
366367
void PassBuilder::invokeOptimizerLastEPCallbacks(ModulePassManager &MPM,
367-
OptimizationLevel Level) {
368+
OptimizationLevel Level,
369+
ThinOrFullLTOPhase Phase) {
368370
for (auto &C : OptimizerLastEPCallbacks)
369-
C(MPM, Level);
371+
C(MPM, Level, Phase);
370372
}
371373
void PassBuilder::invokeFullLinkTimeOptimizationEarlyEPCallbacks(
372374
ModulePassManager &MPM, OptimizationLevel Level) {
@@ -1464,7 +1466,7 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
14641466
if (EnableGlobalAnalyses)
14651467
MPM.addPass(RecomputeGlobalsAAPass());
14661468

1467-
invokeOptimizerEarlyEPCallbacks(MPM, Level);
1469+
invokeOptimizerEarlyEPCallbacks(MPM, Level, LTOPhase);
14681470

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

1562-
invokeOptimizerLastEPCallbacks(MPM, Level);
1564+
invokeOptimizerLastEPCallbacks(MPM, Level, LTOPhase);
15631565

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

17221726
// Emit annotation remarks.
17231727
addAnnotationRemarksPass(MPM);
@@ -2198,7 +2202,7 @@ PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level,
21982202
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
21992203
}
22002204

2201-
invokeOptimizerEarlyEPCallbacks(MPM, Level);
2205+
invokeOptimizerEarlyEPCallbacks(MPM, Level, Phase);
22022206

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

2219-
invokeOptimizerLastEPCallbacks(MPM, Level);
2223+
invokeOptimizerLastEPCallbacks(MPM, Level, Phase);
22202224

22212225
if (isLTOPreLink(Phase))
22222226
addRequiredLTOPreLinkPasses(MPM);

Diff for: llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp

+14-9
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,11 @@ static WWMRegisterRegAlloc
258258
createGreedyWWMRegisterAllocator);
259259
static WWMRegisterRegAlloc fastRegAllocWWMReg("fast", "fast register allocator",
260260
createFastWWMRegisterAllocator);
261+
262+
static bool isLTOPreLink(ThinOrFullLTOPhase Phase) {
263+
return Phase == ThinOrFullLTOPhase::FullLTOPreLink ||
264+
Phase == ThinOrFullLTOPhase::ThinLTOPreLink;
265+
}
261266
} // anonymous namespace
262267

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

757762
// We don't want to run internalization at per-module stage.
758-
bool LTOPreLink = Phase == ThinOrFullLTOPhase::FullLTOPreLink ||
759-
Phase == ThinOrFullLTOPhase::ThinLTOPreLink;
760-
if (InternalizeSymbols && !LTOPreLink) {
763+
if (InternalizeSymbols && !isLTOPreLink(Phase)) {
761764
PM.addPass(InternalizePass(mustPreserveGV));
762765
PM.addPass(GlobalDCEPass());
763766
}
@@ -809,12 +812,14 @@ void AMDGPUTargetMachine::registerPassBuilderCallbacks(PassBuilder &PB) {
809812
});
810813

811814
// FIXME: Why is AMDGPUAttributor not in CGSCC?
812-
PB.registerOptimizerLastEPCallback(
813-
[this](ModulePassManager &MPM, OptimizationLevel Level) {
814-
if (Level != OptimizationLevel::O0) {
815-
MPM.addPass(AMDGPUAttributorPass(*this));
816-
}
817-
});
815+
PB.registerOptimizerLastEPCallback([this](ModulePassManager &MPM,
816+
OptimizationLevel Level,
817+
ThinOrFullLTOPhase Phase) {
818+
if (Level != OptimizationLevel::O0) {
819+
if (!isLTOPreLink(Phase))
820+
MPM.addPass(AMDGPUAttributorPass(*this));
821+
}
822+
});
818823

819824
PB.registerFullLinkTimeOptimizationLastEPCallback(
820825
[this](ModulePassManager &PM, OptimizationLevel Level) {

Diff for: llvm/test/CodeGen/AMDGPU/print-pipeline-passes.ll

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
; O0-NOT: amdgpu-attributor
1414

1515
; PRE-NOT: internalize
16+
; PRE-NOT: amdgpu-attributor
1617

1718
define amdgpu_kernel void @kernel() {
1819
entry:

Diff for: llvm/tools/opt/NewPMDriver.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,13 @@ static void registerEPCallbacks(PassBuilder &PB) {
300300
});
301301
if (tryParsePipelineText<ModulePassManager>(PB, OptimizerEarlyEPPipeline))
302302
PB.registerOptimizerEarlyEPCallback(
303-
[&PB](ModulePassManager &PM, OptimizationLevel) {
303+
[&PB](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) {
304304
ExitOnError Err("Unable to parse OptimizerEarlyEP pipeline: ");
305305
Err(PB.parsePassPipeline(PM, OptimizerEarlyEPPipeline));
306306
});
307307
if (tryParsePipelineText<ModulePassManager>(PB, OptimizerLastEPPipeline))
308308
PB.registerOptimizerLastEPCallback(
309-
[&PB](ModulePassManager &PM, OptimizationLevel) {
309+
[&PB](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) {
310310
ExitOnError Err("Unable to parse OptimizerLastEP pipeline: ");
311311
Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline));
312312
});

0 commit comments

Comments
 (0)