[flang-commits] [flang] [flang] Add the MLIR pass pipelines for dumping (PR #183144)
via flang-commits
flang-commits at lists.llvm.org
Fri Apr 17 06:00:35 PDT 2026
https://github.com/tmjbios updated https://github.com/llvm/llvm-project/pull/183144
>From 50a6975a6e0d99323f2bc83d95ac7d19937c7feb Mon Sep 17 00:00:00 2001
From: Ted Johnson <tedmjohnson at protonmail.com>
Date: Tue, 24 Feb 2026 13:32:41 -0600
Subject: [PATCH 1/7] [flang] Add the MLIR pipelines for dumping
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.
---
flang/docs/Overview.md | 47 +++++++++++++++++++
flang/lib/FrontendTool/CMakeLists.txt | 11 +++++
.../ExecuteCompilerInvocation.cpp | 24 ++++++++++
3 files changed, 82 insertions(+)
diff --git a/flang/docs/Overview.md b/flang/docs/Overview.md
index 77ed21c021f8a..3a92a2cb1faff 100644
--- a/flang/docs/Overview.md
+++ b/flang/docs/Overview.md
@@ -182,6 +182,53 @@ 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-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
+
+The following pass names are valid arguments to `--mlir-print-ir-before=` and
+`--mlir-print-ir-after=` (listed in pipeline order):
+
+| Pass name | Description |
+|---|---|
+| `inline-elementals` | Inline elemental functions |
+| `lower-hlfir-ordered-assignments` | Lower HLFIR ordered assignments |
+| `lower-hlfir-intrinsics` | Lower HLFIR intrinsics |
+| `bufferize-hlfir` | Bufferize HLFIR |
+| `convert-hlfir-to-fir` | Convert HLFIR to FIR |
+| `cse` | Common subexpression elimination |
+| `array-value-copy` | Array value copy |
+| `character-conversion` | Character conversion |
+| `canonicalize` | Canonicalize |
+| `simplify-region-lite` | Simplify region (lite) |
+| `stack-arrays` | Convert heap allocations to stack allocations (requires `-fstack-arrays`) |
+| `inline` | Inliner |
+| `fir-polymorphic-op` | Polymorphic operation conversion |
+| `fir-assumed-rank-op` | Assumed rank operation conversion |
+| `lower-repack-arrays` | Lower repack arrays |
+| `simplify-fir-operations` | Simplify FIR operations |
+| `stack-reclaim` | Stack reclaim |
+| `cfg-conversion` | CFG conversion |
+| `convert-scf-to-cf` | Convert SCF to control flow |
+| `convert-complex-pow` | Convert complex power operations |
+| `mif-convert` | MIF conversion |
+| `boxed-procedure` | Boxed procedure conversion |
+| `abstract-result` | Abstract result optimization |
+| `cg-rewrite` | Code generation rewrite |
+| `external-name-interop` | External name interop conversion |
+| `target-rewrite` | Target rewrite |
+| `compiler-generated-names` | Compiler generated names conversion |
+| `function-attr` | Function attributes |
+| `fir-to-llvm-ir` | FIR to LLVM IR lowering |
+| `convert-math-to-funcs` | Convert math operations to function calls |
+| `convert-complex-to-standard` | Convert complex operations to standard |
+| `convert-math-to-llvm` | Convert math operations to LLVM |
+| `llvm-add-comdats` | Add COMDAT sections |
+| `reconcile-unrealized-casts` | Reconcile unrealized casts |
+
+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/lib/FrontendTool/CMakeLists.txt b/flang/lib/FrontendTool/CMakeLists.txt
index 666fab1a6e2c0..05c740f46e564 100644
--- a/flang/lib/FrontendTool/CMakeLists.txt
+++ b/flang/lib/FrontendTool/CMakeLists.txt
@@ -8,6 +8,10 @@ add_flang_library(flangFrontendTool
LINK_LIBS
flangFrontend
+ FIRCodeGen
+ FIRTransforms
+ HLFIRTransforms
+ FlangOpenMPTransforms
LINK_COMPONENTS
Option
@@ -15,7 +19,14 @@ add_flang_library(flangFrontendTool
Support
MLIR_LIBS
+ MLIRComplexToStandard
+ MLIRLLVMIRTransforms
+ MLIRMathToFuncs
+ MLIRMathToLLVM
MLIRPass
+ MLIRReconcileUnrealizedCasts
+ MLIRSCFToControlFlow
+ MLIRTransforms
CLANG_LIBS
clangBasic
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 429a98416daf1..e0c19a95e16a3 100644
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -18,10 +18,17 @@
#include "flang/Frontend/CompilerInstance.h"
#include "flang/Frontend/FrontendActions.h"
#include "flang/Frontend/FrontendPluginRegistry.h"
+#include "flang/Optimizer/CodeGen/CodeGen.h"
+#include "flang/Optimizer/HLFIR/Passes.h"
+#include "flang/Optimizer/OpenMP/Passes.h"
+#include "flang/Optimizer/Transforms/Passes.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/Pass/PassManager.h"
+#include "mlir/Conversion/Passes.h"
+#include "mlir/Dialect/LLVMIR/Transforms/Passes.h"
+#include "mlir/Transforms/Passes.h"
#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/Options/Options.h"
#include "llvm/Option/OptTable.h"
@@ -207,6 +214,23 @@ bool executeCompilerInvocation(CompilerInstance *flang) {
// Honor -mmlir. This should happen AFTER plugins have been loaded!
if (!flang->getFrontendOpts().mlirArgs.empty()) {
+ // Register MLIR and FIR passes so that --mlir-print-ir-before=<pass> works.
+ // This must happen BEFORE registerPassManagerCLOptions() because that
+ // function creates the PassNameCLParser which snapshots the pass registry
+ // during initialization.
+ mlir::registerCSEPass();
+ mlir::registerCanonicalizerPass();
+ mlir::registerInlinerPass();
+ mlir::registerSCFToControlFlowPass();
+ mlir::registerConvertMathToFuncs();
+ mlir::registerConvertComplexToStandardPass();
+ mlir::registerConvertMathToLLVMPass();
+ mlir::LLVM::registerLLVMAddComdats();
+ mlir::registerReconcileUnrealizedCastsPass();
+ fir::registerOptCodeGenPasses();
+ fir::registerOptTransformPasses();
+ hlfir::registerHLFIRPasses();
+ flangomp::registerFlangOpenMPPasses();
mlir::registerMLIRContextCLOptions();
mlir::registerPassManagerCLOptions();
mlir::registerAsmPrinterCLOptions();
>From 15e2afef82a74099a4639f23f68a6753b7470519 Mon Sep 17 00:00:00 2001
From: tedj <tedmjohnson at protonmail.com>
Date: Tue, 24 Feb 2026 12:42:29 -0700
Subject: [PATCH 2/7] Update ExecuteCompilerInvocation.cpp
clang-format fix
---
flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index e0c19a95e16a3..7b6279f6f2629 100644
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -23,11 +23,11 @@
#include "flang/Optimizer/OpenMP/Passes.h"
#include "flang/Optimizer/Transforms/Passes.h"
+#include "mlir/Conversion/Passes.h"
+#include "mlir/Dialect/LLVMIR/Transforms/Passes.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/Pass/PassManager.h"
-#include "mlir/Conversion/Passes.h"
-#include "mlir/Dialect/LLVMIR/Transforms/Passes.h"
#include "mlir/Transforms/Passes.h"
#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/Options/Options.h"
>From 0142586be73b29ac0a962cdf53ae909631e324f9 Mon Sep 17 00:00:00 2001
From: Ted Johnson <tedmjohnson at protonmail.com>
Date: Tue, 24 Feb 2026 16:58:14 -0600
Subject: [PATCH 3/7] [flang] Add test for new pass dumper(s)
---
flang/test/Driver/mmlir-print-ir-before.f90 | 8 ++++++++
1 file changed, 8 insertions(+)
create mode 100644 flang/test/Driver/mmlir-print-ir-before.f90
diff --git a/flang/test/Driver/mmlir-print-ir-before.f90 b/flang/test/Driver/mmlir-print-ir-before.f90
new file mode 100644
index 0000000000000..3914a4c7e2ef7
--- /dev/null
+++ b/flang/test/Driver/mmlir-print-ir-before.f90
@@ -0,0 +1,8 @@
+! Verify that --mlir-print-ir-before=<pass> works for registered passes.
+
+! RUN: %flang_fc1 -emit-llvm -mmlir --mlir-print-ir-before=cse -o /dev/null %s 2>&1 | FileCheck %s
+
+! CHECK: IR Dump Before CSE
+! CHECK: func.func @_QQmain
+
+end program
>From c15571dd8c33c3cb6567007a16a982bfc405b4ea Mon Sep 17 00:00:00 2001
From: "Ted M. Johnson" <tedmjohnson at protonmail.com>
Date: Wed, 25 Feb 2026 20:21:13 -0700
Subject: [PATCH 4/7] [flang] Remove pass description table from Overview
---
flang/docs/Overview.md | 42 +-----------------------------------------
1 file changed, 1 insertion(+), 41 deletions(-)
diff --git a/flang/docs/Overview.md b/flang/docs/Overview.md
index 3a92a2cb1faff..64df20efd1895 100644
--- a/flang/docs/Overview.md
+++ b/flang/docs/Overview.md
@@ -180,51 +180,11 @@ 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
-The following pass names are valid arguments to `--mlir-print-ir-before=` and
-`--mlir-print-ir-after=` (listed in pipeline order):
-
-| Pass name | Description |
-|---|---|
-| `inline-elementals` | Inline elemental functions |
-| `lower-hlfir-ordered-assignments` | Lower HLFIR ordered assignments |
-| `lower-hlfir-intrinsics` | Lower HLFIR intrinsics |
-| `bufferize-hlfir` | Bufferize HLFIR |
-| `convert-hlfir-to-fir` | Convert HLFIR to FIR |
-| `cse` | Common subexpression elimination |
-| `array-value-copy` | Array value copy |
-| `character-conversion` | Character conversion |
-| `canonicalize` | Canonicalize |
-| `simplify-region-lite` | Simplify region (lite) |
-| `stack-arrays` | Convert heap allocations to stack allocations (requires `-fstack-arrays`) |
-| `inline` | Inliner |
-| `fir-polymorphic-op` | Polymorphic operation conversion |
-| `fir-assumed-rank-op` | Assumed rank operation conversion |
-| `lower-repack-arrays` | Lower repack arrays |
-| `simplify-fir-operations` | Simplify FIR operations |
-| `stack-reclaim` | Stack reclaim |
-| `cfg-conversion` | CFG conversion |
-| `convert-scf-to-cf` | Convert SCF to control flow |
-| `convert-complex-pow` | Convert complex power operations |
-| `mif-convert` | MIF conversion |
-| `boxed-procedure` | Boxed procedure conversion |
-| `abstract-result` | Abstract result optimization |
-| `cg-rewrite` | Code generation rewrite |
-| `external-name-interop` | External name interop conversion |
-| `target-rewrite` | Target rewrite |
-| `compiler-generated-names` | Compiler generated names conversion |
-| `function-attr` | Function attributes |
-| `fir-to-llvm-ir` | FIR to LLVM IR lowering |
-| `convert-math-to-funcs` | Convert math operations to function calls |
-| `convert-complex-to-standard` | Convert complex operations to standard |
-| `convert-math-to-llvm` | Convert math operations to LLVM |
-| `llvm-add-comdats` | Add COMDAT sections |
-| `reconcile-unrealized-casts` | Reconcile unrealized casts |
-
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
>From 60e867b9d11e07b56ccf23f02f0285ce7a3e9114 Mon Sep 17 00:00:00 2001
From: Ted Johnson <tedmjohnson at protonmail.com>
Date: Thu, 26 Feb 2026 08:31:47 -0600
Subject: [PATCH 5/7] [flang] Expand test to cover both -before and -after
---
flang/test/Driver/mmlir-print-ir-before.f90 | 8 --------
flang/test/Driver/mmlir-print-ir.f90 | 13 +++++++++++++
2 files changed, 13 insertions(+), 8 deletions(-)
delete mode 100644 flang/test/Driver/mmlir-print-ir-before.f90
create mode 100644 flang/test/Driver/mmlir-print-ir.f90
diff --git a/flang/test/Driver/mmlir-print-ir-before.f90 b/flang/test/Driver/mmlir-print-ir-before.f90
deleted file mode 100644
index 3914a4c7e2ef7..0000000000000
--- a/flang/test/Driver/mmlir-print-ir-before.f90
+++ /dev/null
@@ -1,8 +0,0 @@
-! Verify that --mlir-print-ir-before=<pass> works for registered passes.
-
-! RUN: %flang_fc1 -emit-llvm -mmlir --mlir-print-ir-before=cse -o /dev/null %s 2>&1 | FileCheck %s
-
-! CHECK: IR Dump Before CSE
-! CHECK: func.func @_QQmain
-
-end program
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
>From 5e5997b528ca734fcec4347a980d29709e5ac40f Mon Sep 17 00:00:00 2001
From: "Ted M. Johnson" <tedmjohnson at protonmail.com>
Date: Fri, 27 Feb 2026 13:46:50 -0700
Subject: [PATCH 6/7] [flang] Commonize the mmlir dump pass additions with
fir-opt
Move the setup of the MLIR pipeline passes to initFIR
and share them with fir-opt.
---
.../include/flang/Optimizer/Support/InitFIR.h | 31 +++++++++++++++++++
.../ExecuteCompilerInvocation.cpp | 22 ++-----------
flang/tools/fir-opt/CMakeLists.txt | 5 +++
flang/tools/fir-opt/fir-opt.cpp | 5 +--
4 files changed, 39 insertions(+), 24 deletions(-)
diff --git a/flang/include/flang/Optimizer/Support/InitFIR.h b/flang/include/flang/Optimizer/Support/InitFIR.h
index d77d82feddd84..45cf86bdf494f 100644
--- a/flang/include/flang/Optimizer/Support/InitFIR.h
+++ b/flang/include/flang/Optimizer/Support/InitFIR.h
@@ -13,13 +13,17 @@
#ifndef FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
#define FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
+#include "flang/Optimizer/CodeGen/CodeGen.h"
#include "flang/Optimizer/Dialect/CUF/CUFDialect.h"
#include "flang/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
+#include "flang/Optimizer/HLFIR/Passes.h"
#include "flang/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.h"
+#include "flang/Optimizer/OpenMP/Passes.h"
#include "flang/Optimizer/OpenMP/Support/RegisterOpenMPExtensions.h"
+#include "flang/Optimizer/Transforms/Passes.h"
#include "mlir/Conversion/Passes.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Affine/Transforms/Passes.h"
@@ -31,6 +35,7 @@
#include "mlir/Dialect/Index/IR/IndexDialect.h"
#include "mlir/Dialect/LLVMIR/NVVMDialect.h"
#include "mlir/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.h"
+#include "mlir/Dialect/LLVMIR/Transforms/Passes.h"
#include "mlir/Dialect/Math/IR/Math.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/Dialect/OpenACC/Transforms/Passes.h"
@@ -133,6 +138,32 @@ inline void registerMLIRPassesForFortranTools() {
mlir::registerLowerAffinePass();
}
+/// Register the passes used in flang's MLIR pass pipeline so that
+/// --mlir-print-ir-before=<pass> and --mlir-print-ir-after=<pass> work.
+/// This must be called BEFORE mlir::registerPassManagerCLOptions() because
+/// that function creates the PassNameCLParser which snapshots the pass
+/// registry during initialization.
+inline 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();
+}
+
/// Register the interfaces needed to lower to LLVM IR.
void registerLLVMTranslation(mlir::MLIRContext &context);
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 7b6279f6f2629..a73b27b9ff9a6 100644
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -18,17 +18,11 @@
#include "flang/Frontend/CompilerInstance.h"
#include "flang/Frontend/FrontendActions.h"
#include "flang/Frontend/FrontendPluginRegistry.h"
-#include "flang/Optimizer/CodeGen/CodeGen.h"
-#include "flang/Optimizer/HLFIR/Passes.h"
-#include "flang/Optimizer/OpenMP/Passes.h"
-#include "flang/Optimizer/Transforms/Passes.h"
+#include "flang/Optimizer/Support/InitFIR.h"
-#include "mlir/Conversion/Passes.h"
-#include "mlir/Dialect/LLVMIR/Transforms/Passes.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/Pass/PassManager.h"
-#include "mlir/Transforms/Passes.h"
#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/Options/Options.h"
#include "llvm/Option/OptTable.h"
@@ -218,19 +212,7 @@ bool executeCompilerInvocation(CompilerInstance *flang) {
// This must happen BEFORE registerPassManagerCLOptions() because that
// function creates the PassNameCLParser which snapshots the pass registry
// during initialization.
- mlir::registerCSEPass();
- mlir::registerCanonicalizerPass();
- mlir::registerInlinerPass();
- mlir::registerSCFToControlFlowPass();
- mlir::registerConvertMathToFuncs();
- mlir::registerConvertComplexToStandardPass();
- mlir::registerConvertMathToLLVMPass();
- mlir::LLVM::registerLLVMAddComdats();
- mlir::registerReconcileUnrealizedCastsPass();
- fir::registerOptCodeGenPasses();
- fir::registerOptTransformPasses();
- hlfir::registerHLFIRPasses();
- flangomp::registerFlangOpenMPPasses();
+ fir::support::registerFlangPipelinePasses();
mlir::registerMLIRContextCLOptions();
mlir::registerPassManagerCLOptions();
mlir::registerAsmPrinterCLOptions();
diff --git a/flang/tools/fir-opt/CMakeLists.txt b/flang/tools/fir-opt/CMakeLists.txt
index e735c2c2ff1a3..e76f4ba3aed1a 100644
--- a/flang/tools/fir-opt/CMakeLists.txt
+++ b/flang/tools/fir-opt/CMakeLists.txt
@@ -49,4 +49,9 @@ mlir_target_link_libraries(fir-opt PRIVATE
MLIRSupport
MLIRVectorToLLVM
MLIROptLib
+ MLIRComplexToStandard
+ MLIRLLVMIRTransforms
+ MLIRMathToFuncs
+ MLIRMathToLLVM
+ MLIRReconcileUnrealizedCasts
)
diff --git a/flang/tools/fir-opt/fir-opt.cpp b/flang/tools/fir-opt/fir-opt.cpp
index 67d07eee1f4fc..be55bac9d787f 100644
--- a/flang/tools/fir-opt/fir-opt.cpp
+++ b/flang/tools/fir-opt/fir-opt.cpp
@@ -37,10 +37,7 @@ void registerTestOpenACC();
int main(int argc, char **argv) {
fir::support::registerMLIRPassesForFortranTools();
- fir::registerOptCodeGenPasses();
- fir::registerOptTransformPasses();
- hlfir::registerHLFIRPasses();
- flangomp::registerFlangOpenMPPasses();
+ fir::support::registerFlangPipelinePasses();
fir::acc::registerFIROpenACCPasses();
#ifdef FLANG_INCLUDE_TESTS
fir::test::registerTestFIRAliasAnalysisPass();
>From 977be051b54fc06108d3daff46682f7b326f20a5 Mon Sep 17 00:00:00 2001
From: "Ted M. Johnson" <tedmjohnson at protonmail.com>
Date: Tue, 14 Apr 2026 06:47:52 -0600
Subject: [PATCH 7/7] [flang] Move registerFlangPipelinePasses to flangPasses
library
Address PR comment: move registerFlangPipelinePasses() from InitFIR.h
to flangPasses.
Add a fir-opt LIT test to verify FIR/HLFIR-specific passes are
recognized by --mlir-print-ir-before/after.
---
.../flang/Optimizer/Passes/Pipelines.h | 4 +++
.../include/flang/Optimizer/Support/InitFIR.h | 31 -------------------
flang/lib/FrontendTool/CMakeLists.txt | 12 +------
.../ExecuteCompilerInvocation.cpp | 9 ++----
flang/lib/Optimizer/Passes/CMakeLists.txt | 4 +++
flang/lib/Optimizer/Passes/Pipelines.cpp | 28 +++++++++++++++++
flang/test/Fir/print-ir-pass.fir | 15 +++++++++
flang/tools/fir-opt/CMakeLists.txt | 6 +---
flang/tools/fir-opt/fir-opt.cpp | 3 +-
9 files changed, 58 insertions(+), 54 deletions(-)
create mode 100644 flang/test/Fir/print-ir-pass.fir
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/include/flang/Optimizer/Support/InitFIR.h b/flang/include/flang/Optimizer/Support/InitFIR.h
index 45cf86bdf494f..d77d82feddd84 100644
--- a/flang/include/flang/Optimizer/Support/InitFIR.h
+++ b/flang/include/flang/Optimizer/Support/InitFIR.h
@@ -13,17 +13,13 @@
#ifndef FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
#define FORTRAN_OPTIMIZER_SUPPORT_INITFIR_H
-#include "flang/Optimizer/CodeGen/CodeGen.h"
#include "flang/Optimizer/Dialect/CUF/CUFDialect.h"
#include "flang/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"
#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
-#include "flang/Optimizer/HLFIR/Passes.h"
#include "flang/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.h"
-#include "flang/Optimizer/OpenMP/Passes.h"
#include "flang/Optimizer/OpenMP/Support/RegisterOpenMPExtensions.h"
-#include "flang/Optimizer/Transforms/Passes.h"
#include "mlir/Conversion/Passes.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Affine/Transforms/Passes.h"
@@ -35,7 +31,6 @@
#include "mlir/Dialect/Index/IR/IndexDialect.h"
#include "mlir/Dialect/LLVMIR/NVVMDialect.h"
#include "mlir/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.h"
-#include "mlir/Dialect/LLVMIR/Transforms/Passes.h"
#include "mlir/Dialect/Math/IR/Math.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/Dialect/OpenACC/Transforms/Passes.h"
@@ -138,32 +133,6 @@ inline void registerMLIRPassesForFortranTools() {
mlir::registerLowerAffinePass();
}
-/// Register the passes used in flang's MLIR pass pipeline so that
-/// --mlir-print-ir-before=<pass> and --mlir-print-ir-after=<pass> work.
-/// This must be called BEFORE mlir::registerPassManagerCLOptions() because
-/// that function creates the PassNameCLParser which snapshots the pass
-/// registry during initialization.
-inline 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();
-}
-
/// Register the interfaces needed to lower to LLVM IR.
void registerLLVMTranslation(mlir::MLIRContext &context);
diff --git a/flang/lib/FrontendTool/CMakeLists.txt b/flang/lib/FrontendTool/CMakeLists.txt
index 05c740f46e564..323d2e73e9a36 100644
--- a/flang/lib/FrontendTool/CMakeLists.txt
+++ b/flang/lib/FrontendTool/CMakeLists.txt
@@ -8,10 +8,7 @@ add_flang_library(flangFrontendTool
LINK_LIBS
flangFrontend
- FIRCodeGen
- FIRTransforms
- HLFIRTransforms
- FlangOpenMPTransforms
+ flangPasses
LINK_COMPONENTS
Option
@@ -19,14 +16,7 @@ add_flang_library(flangFrontendTool
Support
MLIR_LIBS
- MLIRComplexToStandard
- MLIRLLVMIRTransforms
- MLIRMathToFuncs
- MLIRMathToLLVM
MLIRPass
- MLIRReconcileUnrealizedCasts
- MLIRSCFToControlFlow
- MLIRTransforms
CLANG_LIBS
clangBasic
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index a73b27b9ff9a6..a807b86eaaa63 100644
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -18,7 +18,7 @@
#include "flang/Frontend/CompilerInstance.h"
#include "flang/Frontend/FrontendActions.h"
#include "flang/Frontend/FrontendPluginRegistry.h"
-#include "flang/Optimizer/Support/InitFIR.h"
+#include "flang/Optimizer/Passes/Pipelines.h"
#include "mlir/IR/AsmState.h"
#include "mlir/IR/MLIRContext.h"
@@ -208,11 +208,8 @@ bool executeCompilerInvocation(CompilerInstance *flang) {
// Honor -mmlir. This should happen AFTER plugins have been loaded!
if (!flang->getFrontendOpts().mlirArgs.empty()) {
- // Register MLIR and FIR passes so that --mlir-print-ir-before=<pass> works.
- // This must happen BEFORE registerPassManagerCLOptions() because that
- // function creates the PassNameCLParser which snapshots the pass registry
- // during initialization.
- fir::support::registerFlangPipelinePasses();
+ 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..3b0cbf99fb61f 100644
--- a/flang/lib/Optimizer/Passes/CMakeLists.txt
+++ b/flang/lib/Optimizer/Passes/CMakeLists.txt
@@ -18,6 +18,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 73e647a1c3956..7d4fb1ed77f93 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -10,6 +10,8 @@
/// common to flang and the test tools.
#include "flang/Optimizer/Passes/Pipelines.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 +461,30 @@ 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();
+}
+
} // namespace fir
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 e76f4ba3aed1a..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}
)
@@ -49,9 +50,4 @@ mlir_target_link_libraries(fir-opt PRIVATE
MLIRSupport
MLIRVectorToLLVM
MLIROptLib
- MLIRComplexToStandard
- MLIRLLVMIRTransforms
- MLIRMathToFuncs
- MLIRMathToLLVM
- MLIRReconcileUnrealizedCasts
)
diff --git a/flang/tools/fir-opt/fir-opt.cpp b/flang/tools/fir-opt/fir-opt.cpp
index be55bac9d787f..de959142a5e13 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,7 +38,7 @@ void registerTestOpenACC();
int main(int argc, char **argv) {
fir::support::registerMLIRPassesForFortranTools();
- fir::support::registerFlangPipelinePasses();
+ fir::registerFlangPipelinePasses();
fir::acc::registerFIROpenACCPasses();
#ifdef FLANG_INCLUDE_TESTS
fir::test::registerTestFIRAliasAnalysisPass();
More information about the flang-commits
mailing list