Skip to content

Commit d3161de

Browse files
authored
[PassBuilder] VectorizerEnd Extension Points (#123494)
Added an extension point after vectorizer passes in the PassBuilder. Additionally, added extension points before and after vectorizer passes in `buildLTODefaultPipeline`. Credit goes to @mshockwave for guiding me through my first LLVM contribution (and my first open source contribution in general!) :) - Implemented `registerVectorizerEndEPCallback` - Implemented `invokeVectorizerEndEPCallbacks` - Added `VectorizerEndEPCallbacks` SmallVector - Added a command line option `passes-ep-vectorizer-end` to `NewPMDriver.cpp` - `buildModuleOptimizationPipeline` now calls `invokeVectorizerEndEPCallbacks` - `buildO0DefaultPipeline` now calls `invokeVectorizerEndEPCallbacks` - `buildLTODefaultPipeline` now calls BOTH `invokeVectorizerStartEPCallbacks` and `invokeVectorizerEndEPCallbacks` - Added LIT tests to `new-pm-defaults.ll`, `new-pm-lto-defaults.ll`, `new-pm-O0-ep-callbacks.ll`, and `pass-pipeline-parsing.ll` - Renamed `CHECK-EP-Peephole` to `CHECK-EP-PEEPHOLE` in `new-pm-lto-defaults.ll` for consistency. This code is intended for developers that wish to implement and run custom passes after the vectorizer passes in the PassBuilder pipeline. For example, in #91796, a pass was created that changed the induction variables of vectorized code. This is right after the vectorization passes.
1 parent 1822462 commit d3161de

File tree

7 files changed

+65
-4
lines changed

7 files changed

+65
-4
lines changed

llvm/include/llvm/Passes/PassBuilder.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,17 @@ class PassBuilder {
465465
VectorizerStartEPCallbacks.push_back(C);
466466
}
467467

468+
/// Register a callback for a default optimizer pipeline extension
469+
/// point
470+
///
471+
/// This extension point allows adding optimization passes after the
472+
/// vectorizer and other highly target specific optimization passes are
473+
/// executed.
474+
void registerVectorizerEndEPCallback(
475+
const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
476+
VectorizerEndEPCallbacks.push_back(C);
477+
}
478+
468479
/// Register a callback for a default optimizer pipeline extension point.
469480
///
470481
/// This extension point allows adding optimization once at the start of the
@@ -631,6 +642,8 @@ class PassBuilder {
631642
OptimizationLevel Level);
632643
void invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
633644
OptimizationLevel Level);
645+
void invokeVectorizerEndEPCallbacks(FunctionPassManager &FPM,
646+
OptimizationLevel Level);
634647
void invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
635648
OptimizationLevel Level,
636649
ThinOrFullLTOPhase Phase);
@@ -759,6 +772,8 @@ class PassBuilder {
759772
CGSCCOptimizerLateEPCallbacks;
760773
SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
761774
VectorizerStartEPCallbacks;
775+
SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
776+
VectorizerEndEPCallbacks;
762777
// Module callbacks
763778
SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
764779
ThinOrFullLTOPhase)>,

llvm/lib/Passes/PassBuilderPipelines.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,11 @@ void PassBuilder::invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
360360
for (auto &C : VectorizerStartEPCallbacks)
361361
C(FPM, Level);
362362
}
363+
void PassBuilder::invokeVectorizerEndEPCallbacks(FunctionPassManager &FPM,
364+
OptimizationLevel Level) {
365+
for (auto &C : VectorizerEndEPCallbacks)
366+
C(FPM, Level);
367+
}
363368
void PassBuilder::invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
364369
OptimizationLevel Level,
365370
ThinOrFullLTOPhase Phase) {
@@ -1534,6 +1539,8 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
15341539

15351540
addVectorPasses(Level, OptimizePM, /* IsFullLTO */ false);
15361541

1542+
invokeVectorizerEndEPCallbacks(OptimizePM, Level);
1543+
15371544
// LoopSink pass sinks instructions hoisted by LICM, which serves as a
15381545
// canonicalization pass that enables other optimizations. As a result,
15391546
// LoopSink pass needs to be a very late IR pass to avoid undoing LICM
@@ -2046,6 +2053,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
20462053
MainFPM.addPass(MoveAutoInitPass());
20472054
MainFPM.addPass(MergedLoadStoreMotionPass());
20482055

2056+
invokeVectorizerStartEPCallbacks(MainFPM, Level);
2057+
20492058
LoopPassManager LPM;
20502059
if (EnableLoopFlatten && Level.getSpeedupLevel() > 1)
20512060
LPM.addPass(LoopFlattenPass());
@@ -2066,6 +2075,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
20662075

20672076
addVectorPasses(Level, MainFPM, /* IsFullLTO */ true);
20682077

2078+
invokeVectorizerEndEPCallbacks(MainFPM, Level);
2079+
20692080
// Run the OpenMPOpt CGSCC pass again late.
20702081
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
20712082
OpenMPOptCGSCCPass(ThinOrFullLTOPhase::FullLTOPostLink)));
@@ -2231,6 +2242,13 @@ PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level,
22312242
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
22322243
}
22332244

2245+
if (!VectorizerEndEPCallbacks.empty()) {
2246+
FunctionPassManager FPM;
2247+
invokeVectorizerEndEPCallbacks(FPM, Level);
2248+
if (!FPM.isEmpty())
2249+
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
2250+
}
2251+
22342252
ModulePassManager CoroPM;
22352253
CoroPM.addPass(CoroEarlyPass());
22362254
CGSCCPassManager CGPM;

llvm/test/Other/new-pm-O0-ep-callbacks.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
; RUN: opt -disable-output -debug-pass-manager -passes-ep-scalar-optimizer-late=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s
44
; RUN: opt -disable-output -debug-pass-manager -passes-ep-cgscc-optimizer-late=no-op-cgscc -passes='default<O0>' 2>&1 < %s | FileCheck %s
55
; RUN: opt -disable-output -debug-pass-manager -passes-ep-vectorizer-start=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s
6+
; RUN: opt -disable-output -debug-pass-manager -passes-ep-vectorizer-end=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s
67
; RUN: opt -disable-output -debug-pass-manager -passes-ep-pipeline-start=no-op-module -passes='default<O0>' 2>&1 < %s | FileCheck %s
78
; RUN: opt -disable-output -debug-pass-manager -passes-ep-pipeline-early-simplification=no-op-module -passes='default<O0>' 2>&1 < %s | FileCheck %s
89
; RUN: opt -disable-output -debug-pass-manager -passes-ep-optimizer-early=no-op-module -passes='default<O0>' 2>&1 < %s | FileCheck %s

llvm/test/Other/new-pm-defaults.ll

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
; RUN: -passes='default<O3>' -S %s 2>&1 \
5252
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-DEFAULT,CHECK-O3,%llvmcheckext,CHECK-EP-VECTORIZER-START,CHECK-O23SZ
5353
; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
54+
; RUN: -passes-ep-vectorizer-end='no-op-function' \
55+
; RUN: -passes='default<O3>' -S %s 2>&1 \
56+
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-DEFAULT,CHECK-O3,%llvmcheckext,CHECK-EP-VECTORIZER-END,CHECK-O23SZ
57+
; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
5458
; RUN: -passes-ep-pipeline-start='no-op-module' \
5559
; RUN: -passes='default<O3>' -S %s 2>&1 \
5660
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-DEFAULT,CHECK-O3,%llvmcheckext,CHECK-EP-PIPELINE-START,CHECK-O23SZ
@@ -274,6 +278,7 @@
274278
; CHECK-O-NEXT: Running pass: LCSSAPass
275279
; CHECK-O-NEXT: Running pass: LICMPass
276280
; CHECK-O-NEXT: Running pass: AlignmentFromAssumptionsPass
281+
; CHECK-EP-VECTORIZER-END-NEXT: Running pass: NoOpFunctionPass
277282
; CHECK-O-NEXT: Running pass: LoopSinkPass
278283
; CHECK-O-NEXT: Running pass: InstSimplifyPass
279284
; CHECK-O-NEXT: Running pass: DivRemPairsPass

llvm/test/Other/new-pm-lto-defaults.ll

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,20 @@
1818
; RUN: -passes='lto<O3>' -S %s 2>&1 \
1919
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ
2020
; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
21+
; RUN: -passes='lto<O3>' -S %s -passes-ep-vectorizer-start='no-op-function' 2>&1 \
22+
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-EP-VECTORIZER-START
23+
; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
24+
; RUN: -passes='lto<O3>' -S %s -passes-ep-vectorizer-end='no-op-function' 2>&1 \
25+
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-EP-VECTORIZER-END
26+
; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
2127
; RUN: -passes='lto<Os>' -S %s 2>&1 \
2228
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-OS,CHECK-O23SZ
2329
; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
2430
; RUN: -passes='lto<Oz>' -S %s 2>&1 \
2531
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ
2632
; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
2733
; RUN: -passes='lto<O3>' -S %s -passes-ep-peephole='no-op-function' 2>&1 \
28-
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-EP-Peephole
34+
; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-EP-PEEPHOLE
2935

3036
; CHECK-EP: Running pass: NoOpModulePass
3137
; CHECK-O: Running pass: CrossDSOCFIPass
@@ -69,7 +75,7 @@
6975
; CHECK-O23SZ-NEXT: Running pass: InstCombinePass
7076
; CHECK-O23SZ-NEXT: Running analysis: LastRunTrackingAnalysis
7177
; CHECK-O23SZ-NEXT: Running pass: AggressiveInstCombinePass
72-
; CHECK-EP-Peephole-NEXT: Running pass: NoOpFunctionPass
78+
; CHECK-EP-PEEPHOLE-NEXT: Running pass: NoOpFunctionPass
7379
; CHECK-O23SZ-NEXT: Running pass: ExpandVariadicsPass
7480
; CHECK-O23SZ-NEXT: Running pass: ModuleInlinerWrapperPass
7581
; CHECK-O23SZ-NEXT: Running analysis: InlineAdvisorAnalysis
@@ -81,7 +87,7 @@
8187
; CHECK-O23SZ-NEXT: Running pass: GlobalDCEPass
8288
; CHECK-O23SZ-NEXT: Running pass: ArgumentPromotionPass
8389
; CHECK-O23SZ-NEXT: Running pass: InstCombinePass
84-
; CHECK-EP-Peephole-NEXT: Running pass: NoOpFunctionPass
90+
; CHECK-EP-PEEPHOLE-NEXT: Running pass: NoOpFunctionPass
8591
; CHECK-O23SZ-NEXT: Running pass: ConstraintEliminationPass
8692
; CHECK-O23SZ-NEXT: Running analysis: LoopAnalysis on foo
8793
; CHECK-O23SZ-NEXT: Running analysis: ScalarEvolutionAnalysis on foo
@@ -109,6 +115,7 @@
109115
; CHECK-O23SZ-NEXT: Running pass: DSEPass on foo
110116
; CHECK-O23SZ-NEXT: Running pass: MoveAutoInitPass on foo
111117
; CHECK-O23SZ-NEXT: Running pass: MergedLoadStoreMotionPass on foo
118+
; CHECK-EP-VECTORIZER-START-NEXT: Running pass: NoOpFunctionPass on foo
112119
; CHECK-O23SZ-NEXT: Running pass: LoopSimplifyPass on foo
113120
; CHECK-O23SZ-NEXT: Running pass: LCSSAPass on foo
114121
; CHECK-O23SZ-NEXT: Running pass: IndVarSimplifyPass on loop
@@ -137,7 +144,8 @@
137144
; CHECK-O23SZ-NEXT: Running pass: LCSSAPass
138145
; CHECK-O23SZ-NEXT: Running pass: LICMPass
139146
; CHECK-O23SZ-NEXT: Running pass: AlignmentFromAssumptionsPass on foo
140-
; CHECK-EP-Peephole-NEXT: Running pass: NoOpFunctionPass on foo
147+
; CHECK-EP-VECTORIZER-END-NEXT: Running pass: NoOpFunctionPass on foo
148+
; CHECK-EP-PEEPHOLE-NEXT: Running pass: NoOpFunctionPass on foo
141149
; CHECK-O23SZ-NEXT: Running pass: JumpThreadingPass on foo
142150
; CHECK-O23SZ-NEXT: Running pass: LowerTypeTestsPass
143151
; CHECK-O-NEXT: Running pass: LowerTypeTestsPass

llvm/test/Other/pass-pipeline-parsing.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@
264264
; RUN: opt -passes-ep-vectorizer-start=bad -passes=no-op-function \
265265
; RUN: /dev/null -disable-output 2>&1 | FileCheck %s -check-prefix=PASSES-EP-VECTORIZERSTART-ERR
266266
; PASSES-EP-VECTORIZERSTART-ERR: Could not parse -passes-ep-vectorizer-start pipeline: unknown function pass 'bad'
267+
; RUN: opt -passes-ep-vectorizer-end=bad -passes=no-op-function \
268+
; RUN: /dev/null -disable-output 2>&1 | FileCheck %s -check-prefix=PASSES-EP-VECTORIZEREND-ERR
269+
; PASSES-EP-VECTORIZEREND-ERR: Could not parse -passes-ep-vectorizer-end pipeline: unknown function pass 'bad'
267270
; RUN: opt -passes-ep-pipeline-start=bad -passes=no-op-function \
268271
; RUN: /dev/null -disable-output 2>&1 | FileCheck %s -check-prefix=PASSES-EP-PIPELINESTART-ERR
269272
; PASSES-EP-PIPELINESTART-ERR: Could not parse -passes-ep-pipeline-start pipeline: unknown pass name 'bad'

llvm/tools/opt/NewPMDriver.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ static cl::opt<std::string> VectorizerStartEPPipeline(
122122
cl::desc("A textual description of the function pass pipeline inserted at "
123123
"the VectorizerStart extension point into default pipelines"),
124124
cl::Hidden);
125+
static cl::opt<std::string> VectorizerEndEPPipeline(
126+
"passes-ep-vectorizer-end",
127+
cl::desc("A textual description of the function pass pipeline inserted at "
128+
"the VectorizerEnd extension point into default pipelines"),
129+
cl::Hidden);
125130
static cl::opt<std::string> PipelineStartEPPipeline(
126131
"passes-ep-pipeline-start",
127132
cl::desc("A textual description of the module pass pipeline inserted at "
@@ -285,6 +290,12 @@ static void registerEPCallbacks(PassBuilder &PB) {
285290
ExitOnError Err("Unable to parse VectorizerStartEP pipeline: ");
286291
Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline));
287292
});
293+
if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerEndEPPipeline))
294+
PB.registerVectorizerEndEPCallback(
295+
[&PB](FunctionPassManager &PM, OptimizationLevel Level) {
296+
ExitOnError Err("Unable to parse VectorizerEndEP pipeline: ");
297+
Err(PB.parsePassPipeline(PM, VectorizerEndEPPipeline));
298+
});
288299
if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline))
289300
PB.registerPipelineStartEPCallback(
290301
[&PB](ModulePassManager &PM, OptimizationLevel) {

0 commit comments

Comments
 (0)