[flang-commits] [flang] [flang] Add the MLIR pass pipelines for dumping (PR #183144)

via flang-commits flang-commits at lists.llvm.org
Thu Feb 26 06:32:43 PST 2026


https://github.com/tmjbios updated https://github.com/llvm/llvm-project/pull/183144

>From 67369883a0674e078a85136a12ea03fb8b3e2b79 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/5] [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 0c456ef1b75b8da3c880ad65a7968188485112e6 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/5] 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 5a7b0005d50d2c808caaeed1407feb1dfc1d702d 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/5] [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 18aa8d894775356a45164fe3a424425e3f42990a 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/5] [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 10c4c92be746ce0683036a198fa106b31eff4298 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/5] [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



More information about the flang-commits mailing list