[flang-commits] [flang] c32d2d1 - [flang] Add the MLIR pass pipelines for dumping (#183144)
via flang-commits
flang-commits at lists.llvm.org
Thu Apr 23 07:19:29 PDT 2026
Author: tedj
Date: 2026-04-23T15:19:22+01:00
New Revision: c32d2d1f2951ee21c1b675405fd8de11dd25f986
URL: https://github.com/llvm/llvm-project/commit/c32d2d1f2951ee21c1b675405fd8de11dd25f986
DIFF: https://github.com/llvm/llvm-project/commit/c32d2d1f2951ee21c1b675405fd8de11dd25f986.diff
LOG: [flang] Add the MLIR pass pipelines for dumping (#183144)
The flang driver never registered passes in the MLIR pass registry, so
--mlir-print-ir-before=<pass> always failed with `Cannot find option`.
This commit adds pass registration calls before CLI option parsing in
the -mmlir handler such that all ~30 pipeline passes are now selectable.
Added:
flang/test/Driver/mmlir-print-ir.f90
flang/test/Fir/print-ir-pass.fir
Modified:
flang/docs/Overview.md
flang/include/flang/Optimizer/Passes/Pipelines.h
flang/lib/FrontendTool/CMakeLists.txt
flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
flang/lib/Optimizer/Passes/CMakeLists.txt
flang/lib/Optimizer/Passes/Pipelines.cpp
flang/tools/fir-opt/CMakeLists.txt
flang/tools/fir-opt/fir-opt.cpp
Removed:
################################################################################
diff --git a/flang/docs/Overview.md b/flang/docs/Overview.md
index 77ed21c021f8a..64df20efd1895 100644
--- a/flang/docs/Overview.md
+++ b/flang/docs/Overview.md
@@ -180,8 +180,15 @@ perform various optimizations and transformations. The final pass creates an
LLVM IR representation of the program.
**Commands:**
- - `flang -mmlir --mlir-print-ir-after-all -S src.f90` dumps the FIR code after each pass to standard error
- `flang -fc1 -emit-llvm src.f90` dumps the LLVM IR to src.ll
+ - `flang -mmlir --mlir-print-ir-after-all -S src.f90` dumps the FIR code after each pass to standard error
+ - `flang -mmlir --mlir-print-ir-before=<pass> -S src.f90` dumps the FIR code before a specific pass to standard error
+ - `flang -mmlir --mlir-print-ir-after=<pass> -S src.f90` dumps the FIR code after a specific pass to standard error
+
+Note: The exact set of passes depends on compilation options. For example,
+`stack-arrays` only appears when `-fstack-arrays` is enabled. To see the
+complete list for a given compilation, use `--mlir-print-ir-before-all` and
+look at the `IR Dump Before` headers.
## Object code generation and linking
diff --git a/flang/include/flang/Optimizer/Passes/Pipelines.h b/flang/include/flang/Optimizer/Passes/Pipelines.h
index 04eca81daf05e..63fbdc37073b2 100644
--- a/flang/include/flang/Optimizer/Passes/Pipelines.h
+++ b/flang/include/flang/Optimizer/Passes/Pipelines.h
@@ -117,6 +117,10 @@ void addLLVMDialectToLLVMPass(mlir::PassManager &pm, llvm::raw_ostream &output);
/// Use inliner extension point callback to register the default inliner pass.
void registerDefaultInlinerPass(MLIRToLLVMPassPipelineConfig &config);
+/// Register the passes used in Flang's MLIR pass pipeline
+/// e.g. --mlir-print-ir-before=<pass> and similar.
+void registerFlangPipelinePasses();
+
/// Create a pass pipeline for running default optimization passes for
/// incremental conversion of FIR.
///
diff --git a/flang/lib/FrontendTool/CMakeLists.txt b/flang/lib/FrontendTool/CMakeLists.txt
index 666fab1a6e2c0..323d2e73e9a36 100644
--- a/flang/lib/FrontendTool/CMakeLists.txt
+++ b/flang/lib/FrontendTool/CMakeLists.txt
@@ -8,6 +8,7 @@ add_flang_library(flangFrontendTool
LINK_LIBS
flangFrontend
+ flangPasses
LINK_COMPONENTS
Option
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 429a98416daf1..a807b86eaaa63 100644
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -18,6 +18,7 @@
#include "flang/Frontend/CompilerInstance.h"
#include "flang/Frontend/FrontendActions.h"
#include "flang/Frontend/FrontendPluginRegistry.h"
+#include "flang/Optimizer/Passes/Pipelines.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/MLIRContext.h"
@@ -207,6 +208,8 @@ bool executeCompilerInvocation(CompilerInstance *flang) {
// Honor -mmlir. This should happen AFTER plugins have been loaded!
if (!flang->getFrontendOpts().mlirArgs.empty()) {
+ fir::registerFlangPipelinePasses(); // Must be called before
+ // mlir::registerPassManagerCLOptions()
mlir::registerMLIRContextCLOptions();
mlir::registerPassManagerCLOptions();
mlir::registerAsmPrinterCLOptions();
diff --git a/flang/lib/Optimizer/Passes/CMakeLists.txt b/flang/lib/Optimizer/Passes/CMakeLists.txt
index 1c19a5765aff1..8d3c4f5cd05a8 100644
--- a/flang/lib/Optimizer/Passes/CMakeLists.txt
+++ b/flang/lib/Optimizer/Passes/CMakeLists.txt
@@ -7,6 +7,7 @@ add_flang_library(flangPasses
LINK_LIBS
FIRCodeGen
+ FIROpenACCTransforms
FIRTransforms
FlangOpenMPTransforms
FortranSupport
@@ -18,6 +19,10 @@ add_flang_library(flangPasses
MLIR_LIBS
${dialect_libs}
${extension_libs}
+ MLIRComplexToStandard
+ MLIRLLVMIRTransforms
+ MLIRMathToFuncs
+ MLIRMathToLLVM
MLIRPass
MLIRReconcileUnrealizedCasts
MLIRSCFToControlFlow
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 4c48b7a75d83d..54a8ba5dde0cb 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -10,6 +10,9 @@
/// common to flang and the test tools.
#include "flang/Optimizer/Passes/Pipelines.h"
+#include "flang/Optimizer/OpenACC/Passes.h"
+#include "mlir/Conversion/Passes.h"
+#include "mlir/Dialect/LLVMIR/Transforms/Passes.h"
#include "llvm/Support/CommandLine.h"
/// Force setting the no-alias attribute on fuction arguments when possible.
@@ -459,4 +462,31 @@ void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
});
}
+/// Register the passes used in flang's MLIR pass pipeline so that
+/// --mlir-print-ir-before=<pass> and --mlir-print-ir-after=<pass> work.
+/// Must be called BEFORE mlir::registerPassManagerCLOptions() because
+/// that function creates the PassNameCLParser which snapshots the pass
+/// registry during initialization.
+void registerFlangPipelinePasses() {
+ // MLIR core passes used in the pipeline.
+ mlir::registerCSEPass();
+ mlir::registerCanonicalizerPass();
+ mlir::registerInlinerPass();
+
+ // MLIR conversion passes used in the pipeline.
+ mlir::registerSCFToControlFlowPass();
+ mlir::registerConvertMathToFuncs();
+ mlir::registerConvertComplexToStandardPass();
+ mlir::registerConvertMathToLLVMPass();
+ mlir::LLVM::registerLLVMAddComdats();
+ mlir::registerReconcileUnrealizedCastsPass();
+
+ // FIR, HLFIR, and OpenMP passes.
+ fir::registerOptCodeGenPasses();
+ fir::registerOptTransformPasses();
+ hlfir::registerHLFIRPasses();
+ flangomp::registerFlangOpenMPPasses();
+ fir::acc::registerFIROpenACCPasses();
+}
+
} // namespace fir
diff --git a/flang/test/Driver/mmlir-print-ir.f90 b/flang/test/Driver/mmlir-print-ir.f90
new file mode 100644
index 0000000000000..140fef10710cf
--- /dev/null
+++ b/flang/test/Driver/mmlir-print-ir.f90
@@ -0,0 +1,13 @@
+! Verify that --mlir-print-ir-before=<pass> and --mlir-print-ir-after=<pass>
+! work for registered passes.
+
+! RUN: %flang_fc1 -emit-llvm -mmlir --mlir-print-ir-before=cse -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=BEFORE
+! RUN: %flang_fc1 -emit-llvm -mmlir --mlir-print-ir-after=cse -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=AFTER
+
+! BEFORE: IR Dump Before CSE
+! BEFORE: func.func @_QQmain
+
+! AFTER: IR Dump After CSE
+! AFTER: func.func @_QQmain
+
+end program
diff --git a/flang/test/Fir/print-ir-pass.fir b/flang/test/Fir/print-ir-pass.fir
new file mode 100644
index 0000000000000..6c308570a2935
--- /dev/null
+++ b/flang/test/Fir/print-ir-pass.fir
@@ -0,0 +1,15 @@
+// Verify that --mlir-print-ir-before and --mlir-print-ir-after work in fir-opt
+// for FIR/HLFIR-specific passes registered by registerFlangPipelinePasses().
+
+// RUN: fir-opt --convert-hlfir-to-fir --mlir-print-ir-before=convert-hlfir-to-fir %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=BEFORE
+// RUN: fir-opt --convert-hlfir-to-fir --mlir-print-ir-after=convert-hlfir-to-fir %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=AFTER
+
+// BEFORE: IR Dump Before ConvertHLFIRtoFIR
+// BEFORE: func.func @dummy()
+
+// AFTER: IR Dump After ConvertHLFIRtoFIR
+// AFTER: func.func @dummy()
+
+func.func @dummy() {
+ return
+}
diff --git a/flang/tools/fir-opt/CMakeLists.txt b/flang/tools/fir-opt/CMakeLists.txt
index e735c2c2ff1a3..2697f74c2f0b8 100644
--- a/flang/tools/fir-opt/CMakeLists.txt
+++ b/flang/tools/fir-opt/CMakeLists.txt
@@ -28,6 +28,7 @@ target_link_libraries(fir-opt PRIVATE
FlangOpenMPTransforms
FIRAnalysis
MIFDialect
+ flangPasses
${test_libs}
)
diff --git a/flang/tools/fir-opt/fir-opt.cpp b/flang/tools/fir-opt/fir-opt.cpp
index 67d07eee1f4fc..7789d396f6e5c 100644
--- a/flang/tools/fir-opt/fir-opt.cpp
+++ b/flang/tools/fir-opt/fir-opt.cpp
@@ -16,6 +16,7 @@
#include "flang/Optimizer/HLFIR/Passes.h"
#include "flang/Optimizer/OpenACC/Passes.h"
#include "flang/Optimizer/OpenMP/Passes.h"
+#include "flang/Optimizer/Passes/Pipelines.h"
#include "flang/Optimizer/Support/InitFIR.h"
#include "flang/Optimizer/Transforms/Passes.h"
@@ -37,11 +38,7 @@ void registerTestOpenACC();
int main(int argc, char **argv) {
fir::support::registerMLIRPassesForFortranTools();
- fir::registerOptCodeGenPasses();
- fir::registerOptTransformPasses();
- hlfir::registerHLFIRPasses();
- flangomp::registerFlangOpenMPPasses();
- fir::acc::registerFIROpenACCPasses();
+ fir::registerFlangPipelinePasses();
#ifdef FLANG_INCLUDE_TESTS
fir::test::registerTestFIRAliasAnalysisPass();
fir::test::registerTestFIROpenACCInterfacesPass();
@@ -52,6 +49,6 @@ int main(int argc, char **argv) {
fir::support::registerDialects(registry);
registry.insert<mlir::memref::MemRefDialect>();
fir::support::addFIRExtensions(registry);
- return failed(MlirOptMain(argc, argv, "FIR modular optimizer driver\n",
- registry));
+ return failed(
+ MlirOptMain(argc, argv, "FIR modular optimizer driver\n", registry));
}
More information about the flang-commits
mailing list