Skip to content

Commit 86ab10c

Browse files
VijayKandiahVijay Kandiah
andauthored
[flang] Added extension point callbacks to default FIR optimizer pipeline. (#90674)
This change inserts a few extension point callbacks in the DefaultFIROptimizerPassPipeline. As an example usage of callbacks in the FIR optimizer pipeline, the FIRInlinerCallback is now used to register the default MLIR inliner pass in flang-new, tco, and bbc compilation flows. Other compilation flows can use these callbacks to add extra passes at different points of the pass pipeline. --------- Co-authored-by: Vijay Kandiah <[email protected]>
1 parent 2d4acb0 commit 86ab10c

File tree

6 files changed

+94
-11
lines changed

6 files changed

+94
-11
lines changed

flang/docs/FlangDriver.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,16 @@ to re-analyze expressions and modify scope or symbols. You can check
518518
[Semantics.md](Semantics.md) for more details on how `ParseTree` is edited
519519
e.g. during the semantic checks.
520520

521+
## FIR Optimizer Pass Pipeline Extension Points
522+
523+
The default FIR optimizer pass pipeline `createDefaultFIROptimizerPassPipeline`
524+
in `flang/include/flang/Tools/CLOptions.inc` contains extension point callback
525+
invocations `invokeFIROptEarlyEPCallbacks`, `invokeFIRInlinerCallback`, and
526+
`invokeFIROptLastEPCallbacks` for Flang drivers to be able to insert additonal
527+
passes at different points of the default pass pipeline. An example use of these
528+
extension point callbacks is shown in `registerDefaultInlinerPass` to invoke the
529+
default inliner pass in `flang-new`.
530+
521531
## LLVM Pass Plugins
522532

523533
Pass plugins are dynamic shared objects that consist of one or more LLVM IR

flang/include/flang/Tools/CLOptions.inc

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,27 @@ inline void addExternalNameConversionPass(
232232
});
233233
}
234234

235+
// Use inliner extension point callback to register the default inliner pass.
236+
inline void registerDefaultInlinerPass(MLIRToLLVMPassPipelineConfig &config) {
237+
config.registerFIRInlinerCallback(
238+
[](mlir::PassManager &pm, llvm::OptimizationLevel level) {
239+
llvm::StringMap<mlir::OpPassManager> pipelines;
240+
// The default inliner pass adds the canonicalizer pass with the default
241+
// configuration.
242+
pm.addPass(mlir::createInlinerPass(
243+
pipelines, addCanonicalizerPassWithoutRegionSimplification));
244+
});
245+
}
246+
235247
/// Create a pass pipeline for running default optimization passes for
236248
/// incremental conversion of FIR.
237249
///
238250
/// \param pm - MLIR pass manager that will hold the pipeline definition
239251
inline void createDefaultFIROptimizerPassPipeline(
240-
mlir::PassManager &pm, const MLIRToLLVMPassPipelineConfig &pc) {
252+
mlir::PassManager &pm, MLIRToLLVMPassPipelineConfig &pc) {
253+
// Early Optimizer EP Callback
254+
pc.invokeFIROptEarlyEPCallbacks(pm, pc.OptLevel);
255+
241256
// simplify the IR
242257
mlir::GreedyRewriteConfig config;
243258
config.enableRegionSimplification = false;
@@ -262,11 +277,9 @@ inline void createDefaultFIROptimizerPassPipeline(
262277
else
263278
fir::addMemoryAllocationOpt(pm);
264279

265-
// The default inliner pass adds the canonicalizer pass with the default
266-
// configuration. Create the inliner pass with tco config.
267-
llvm::StringMap<mlir::OpPassManager> pipelines;
268-
pm.addPass(mlir::createInlinerPass(
269-
pipelines, addCanonicalizerPassWithoutRegionSimplification));
280+
// FIR Inliner Callback
281+
pc.invokeFIRInlinerCallback(pm, pc.OptLevel);
282+
270283
pm.addPass(fir::createSimplifyRegionLite());
271284
pm.addPass(mlir::createCSEPass());
272285

@@ -283,6 +296,9 @@ inline void createDefaultFIROptimizerPassPipeline(
283296
pm.addPass(mlir::createCanonicalizerPass(config));
284297
pm.addPass(fir::createSimplifyRegionLite());
285298
pm.addPass(mlir::createCSEPass());
299+
300+
// Last Optimizer EP Callback
301+
pc.invokeFIROptLastEPCallbacks(pm, pc.OptLevel);
286302
}
287303

288304
/// Create a pass pipeline for lowering from HLFIR to FIR
@@ -375,8 +391,7 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
375391
/// \param optLevel - optimization level used for creating FIR optimization
376392
/// passes pipeline
377393
inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
378-
const MLIRToLLVMPassPipelineConfig &config,
379-
llvm::StringRef inputFilename = {}) {
394+
MLIRToLLVMPassPipelineConfig &config, llvm::StringRef inputFilename = {}) {
380395
fir::createHLFIRToFIRPassPipeline(pm, config.OptLevel);
381396

382397
// Add default optimizer pass pipeline.

flang/include/flang/Tools/CrossToolHelpers.h

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,66 @@
2020

2121
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
2222
#include "mlir/IR/BuiltinOps.h"
23+
#include "mlir/Pass/PassRegistry.h"
24+
#include "llvm/ADT/SmallVector.h"
2325
#include "llvm/Frontend/Debug/Options.h"
2426
#include "llvm/Passes/OptimizationLevel.h"
2527

28+
// Flang Extension Point Callbacks
29+
class FlangEPCallBacks {
30+
public:
31+
void registerFIROptEarlyEPCallbacks(
32+
const std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>
33+
&C) {
34+
FIROptEarlyEPCallbacks.push_back(C);
35+
}
36+
37+
void registerFIRInlinerCallback(
38+
const std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>
39+
&C) {
40+
FIRInlinerCallback.push_back(C);
41+
}
42+
43+
void registerFIROptLastEPCallbacks(
44+
const std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>
45+
&C) {
46+
FIROptLastEPCallbacks.push_back(C);
47+
}
48+
49+
void invokeFIROptEarlyEPCallbacks(
50+
mlir::PassManager &pm, llvm::OptimizationLevel optLevel) {
51+
for (auto &C : FIROptEarlyEPCallbacks)
52+
C(pm, optLevel);
53+
};
54+
55+
void invokeFIRInlinerCallback(
56+
mlir::PassManager &pm, llvm::OptimizationLevel optLevel) {
57+
for (auto &C : FIRInlinerCallback)
58+
C(pm, optLevel);
59+
};
60+
61+
void invokeFIROptLastEPCallbacks(
62+
mlir::PassManager &pm, llvm::OptimizationLevel optLevel) {
63+
for (auto &C : FIROptLastEPCallbacks)
64+
C(pm, optLevel);
65+
};
66+
67+
private:
68+
llvm::SmallVector<
69+
std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>, 1>
70+
FIROptEarlyEPCallbacks;
71+
72+
llvm::SmallVector<
73+
std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>, 1>
74+
FIRInlinerCallback;
75+
76+
llvm::SmallVector<
77+
std::function<void(mlir::PassManager &, llvm::OptimizationLevel)>, 1>
78+
FIROptLastEPCallbacks;
79+
};
80+
2681
/// Configuriation for the MLIR to LLVM pass pipeline.
27-
struct MLIRToLLVMPassPipelineConfig {
82+
struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks {
2883
explicit MLIRToLLVMPassPipelineConfig(llvm::OptimizationLevel level) {
2984
OptLevel = level;
3085
}

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ void CodeGenAction::generateLLVMIR() {
802802
pm.enableVerifier(/*verifyPasses=*/true);
803803

804804
MLIRToLLVMPassPipelineConfig config(level, opts, mathOpts);
805+
fir::registerDefaultInlinerPass(config);
805806

806807
if (auto vsr = getVScaleRange(ci)) {
807808
config.VScaleMin = vsr->first;

flang/tools/bbc/bbc.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,9 @@ static mlir::LogicalResult convertFortranSourceToMLIR(
427427
pm.addPass(std::make_unique<Fortran::lower::VerifierPass>());
428428

429429
// Add O2 optimizer pass pipeline.
430-
fir::createDefaultFIROptimizerPassPipeline(
431-
pm, MLIRToLLVMPassPipelineConfig(llvm::OptimizationLevel::O2));
430+
MLIRToLLVMPassPipelineConfig config(llvm::OptimizationLevel::O2);
431+
fir::registerDefaultInlinerPass(config);
432+
fir::createDefaultFIROptimizerPassPipeline(pm, config);
432433
}
433434

434435
if (mlir::succeeded(pm.run(mlirModule))) {

flang/tools/tco/tco.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
140140
fir::createDefaultFIRCodeGenPassPipeline(pm, config);
141141
} else {
142142
// Run tco with O2 by default.
143+
fir::registerDefaultInlinerPass(config);
143144
fir::createMLIRToLLVMPassPipeline(pm, config);
144145
}
145146
fir::addLLVMDialectToLLVMPass(pm, out.os());

0 commit comments

Comments
 (0)