llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: MingYan (NexMing)

<details>
<summary>Changes</summary>

This patch split `-emit-fir` and `-emit-mlir` option in Flang's frontend driver.

A new parent class for code-gen frontend actions is introduced:`CodeGenAction`.

For the `-emit-mlir` option, we aim to generate a file using the core MLIR 
dialects. Currently, FIR Dialect is directly lowered to LLVM Dialect, but in 
the future, we hope to gradually separate the pipeline into FIR → MLIR (core 
dialects) → LLVM. For now, this option temporarily generate a file using the 
LLVM dialect.

---
Full diff: https://github.com/llvm/llvm-project/pull/139857.diff


10 Files Affected:

- (modified) clang/include/clang/Driver/Options.td (+2-1) 
- (modified) flang/include/flang/Frontend/FrontendActions.h (+11) 
- (modified) flang/include/flang/Frontend/FrontendOptions.h (+3) 
- (modified) flang/lib/Frontend/CompilerInvocation.cpp (+3) 
- (modified) flang/lib/Frontend/FrontendActions.cpp (+49-1) 
- (modified) flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp (+2) 
- (added) flang/test/Driver/emit-fir.f90 (+30) 
- (modified) flang/test/Driver/emit-mlir.f90 (+17-19) 
- (modified) flang/test/Fir/non-trivial-procedure-binding-description.f90 
(+2-2) 
- (modified) flang/test/Lower/unsigned-ops.f90 (+1-1) 


``````````diff
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index bd8df8f6a749a..00cc05a2bd1a6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7193,7 +7193,8 @@ defm analyzed_objects_for_unparse : 
OptOutFC1FFlag<"analyzed-objects-for-unparse
 
 def emit_fir : Flag<["-"], "emit-fir">, Group<Action_Group>,
   HelpText<"Build the parse tree, then lower it to FIR">;
-def emit_mlir : Flag<["-"], "emit-mlir">, Alias<emit_fir>;
+def emit_mlir : Flag<["-"], "emit-mlir">, Group<Action_Group>,
+  HelpText<"Build the parse tree, then lower it to core MLIR">;
 
 def emit_hlfir : Flag<["-"], "emit-hlfir">, Group<Action_Group>,
   HelpText<"Build the parse tree, then lower it to HLFIR">;
diff --git a/flang/include/flang/Frontend/FrontendActions.h 
b/flang/include/flang/Frontend/FrontendActions.h
index f9a45bd6c0a56..b651a234b5849 100644
--- a/flang/include/flang/Frontend/FrontendActions.h
+++ b/flang/include/flang/Frontend/FrontendActions.h
@@ -179,6 +179,7 @@ enum class BackendActionTy {
   Backend_EmitBC,       ///< Emit LLVM bitcode files
   Backend_EmitLL,       ///< Emit human-readable LLVM assembly
   Backend_EmitFIR,      ///< Emit FIR files, possibly lowering via HLFIR
+  Backend_EmitMLIR,     ///< Emit MLIR files, possibly lowering via FIR
   Backend_EmitHLFIR,    ///< Emit HLFIR files before any passes run
 };
 
@@ -216,6 +217,11 @@ class CodeGenAction : public FrontendAction {
   /// Runs pass pipeline to lower HLFIR into FIR
   void lowerHLFIRToFIR();
 
+  /// Runs pass pipeline to lower FIR into core MLIR
+  /// TODO: Some operations currently do not have corresponding representations
+  /// in the core MLIR dialects, so we lower them directly to the LLVM dialect.
+  void lowerFIRToMLIR();
+
   /// Generates an LLVM IR module from CodeGenAction::mlirModule and saves it
   /// in CodeGenAction::llvmModule.
   void generateLLVMIR();
@@ -232,6 +238,11 @@ class EmitFIRAction : public CodeGenAction {
   EmitFIRAction() : CodeGenAction(BackendActionTy::Backend_EmitFIR) {}
 };
 
+class EmitMLIRAction : public CodeGenAction {
+public:
+  EmitMLIRAction() : CodeGenAction(BackendActionTy::Backend_EmitMLIR) {}
+};
+
 class EmitHLFIRAction : public CodeGenAction {
 public:
   EmitHLFIRAction() : CodeGenAction(BackendActionTy::Backend_EmitHLFIR) {}
diff --git a/flang/include/flang/Frontend/FrontendOptions.h 
b/flang/include/flang/Frontend/FrontendOptions.h
index 0bd2e621813ca..69bc5691430a8 100644
--- a/flang/include/flang/Frontend/FrontendOptions.h
+++ b/flang/include/flang/Frontend/FrontendOptions.h
@@ -37,6 +37,9 @@ enum ActionKind {
   /// Emit FIR mlir file
   EmitFIR,
 
+  /// Emit core MLIR mlir file
+  EmitMLIR,
+
   /// Emit HLFIR mlir file
   EmitHLFIR,
 
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp 
b/flang/lib/Frontend/CompilerInvocation.cpp
index 238079a09ef3a..2a4b6e9d884af 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -572,6 +572,9 @@ static bool parseFrontendArgs(FrontendOptions &opts, 
llvm::opt::ArgList &args,
     case clang::driver::options::OPT_emit_fir:
       opts.programAction = EmitFIR;
       break;
+    case clang::driver::options::OPT_emit_mlir:
+      opts.programAction = EmitMLIR;
+      break;
     case clang::driver::options::OPT_emit_hlfir:
       opts.programAction = EmitHLFIR;
       break;
diff --git a/flang/lib/Frontend/FrontendActions.cpp 
b/flang/lib/Frontend/FrontendActions.cpp
index e5a15c555fa5e..9ba98873042f8 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -635,6 +635,49 @@ void CodeGenAction::lowerHLFIRToFIR() {
   }
 }
 
+void CodeGenAction::lowerFIRToMLIR() {
+  assert(mlirModule && "The MLIR module has not been generated yet.");
+
+  CompilerInstance &ci = this->getInstance();
+  CompilerInvocation &invoc = ci.getInvocation();
+  const CodeGenOptions &opts = invoc.getCodeGenOpts();
+  const auto &mathOpts = invoc.getLoweringOpts().getMathOptions();
+  llvm::OptimizationLevel level = mapToLevel(opts);
+  mlir::DefaultTimingManager &timingMgr = ci.getTimingManager();
+  mlir::TimingScope &timingScopeRoot = ci.getTimingScopeRoot();
+
+  fir::support::loadDialects(*mlirCtx);
+  mlir::DialectRegistry registry;
+  fir::support::registerNonCodegenDialects(registry);
+  fir::support::addFIRExtensions(registry);
+  mlirCtx->appendDialectRegistry(registry);
+  fir::support::registerLLVMTranslation(*mlirCtx);
+
+  // Set-up the MLIR pass manager
+  mlir::PassManager pm((*mlirModule)->getName(),
+                       mlir::OpPassManager::Nesting::Implicit);
+
+  pm.addPass(std::make_unique<Fortran::lower::VerifierPass>());
+  pm.enableVerifier(/*verifyPasses=*/true);
+
+  MLIRToLLVMPassPipelineConfig config(level, opts, mathOpts);
+  fir::registerDefaultInlinerPass(config);
+
+  // Create the pass pipeline
+  fir::createDefaultFIROptimizerPassPipeline(pm, config);
+  fir::createDefaultFIRCodeGenPassPipeline(pm, config);
+  (void)mlir::applyPassManagerCLOptions(pm);
+
+  mlir::TimingScope timingScopeMLIRPasses = timingScopeRoot.nest(
+      mlir::TimingIdentifier::get(timingIdMLIRPasses, timingMgr));
+  pm.enableTiming(timingScopeMLIRPasses);
+  if (!mlir::succeeded(pm.run(*mlirModule))) {
+    unsigned diagID = ci.getDiagnostics().getCustomDiagID(
+        clang::DiagnosticsEngine::Error, "Lowering to FIR failed");
+    ci.getDiagnostics().Report(diagID);
+  }
+}
+
 static std::optional<std::pair<unsigned, unsigned>>
 getAArch64VScaleRange(CompilerInstance &ci) {
   const auto &langOpts = ci.getInvocation().getLangOpts();
@@ -836,6 +879,7 @@ getOutputStream(CompilerInstance &ci, llvm::StringRef 
inFile,
     return ci.createDefaultOutputFile(
         /*Binary=*/false, inFile, /*extension=*/"ll");
   case BackendActionTy::Backend_EmitFIR:
+  case BackendActionTy::Backend_EmitMLIR:
   case BackendActionTy::Backend_EmitHLFIR:
     return ci.createDefaultOutputFile(
         /*Binary=*/false, inFile, /*extension=*/"mlir");
@@ -1242,10 +1286,14 @@ void CodeGenAction::executeAction() {
     }
   }
 
-  if (action == BackendActionTy::Backend_EmitFIR) {
+  if (action == BackendActionTy::Backend_EmitFIR ||
+      action == BackendActionTy::Backend_EmitMLIR) {
     if (loweringOpts.getLowerToHighLevelFIR()) {
       lowerHLFIRToFIR();
     }
+    if (action == BackendActionTy::Backend_EmitMLIR) {
+      lowerFIRToMLIR();
+    }
     mlirModule->print(ci.isOutputStreamNull() ? *os : ci.getOutputStream());
     return;
   }
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp 
b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 09ac129d3e689..0c4195ec2ac2e 100644
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -43,6 +43,8 @@ createFrontendAction(CompilerInstance &ci) {
     return std::make_unique<ParseSyntaxOnlyAction>();
   case EmitFIR:
     return std::make_unique<EmitFIRAction>();
+  case EmitMLIR:
+    return std::make_unique<EmitMLIRAction>();
   case EmitHLFIR:
     return std::make_unique<EmitHLFIRAction>();
   case EmitLLVM:
diff --git a/flang/test/Driver/emit-fir.f90 b/flang/test/Driver/emit-fir.f90
new file mode 100644
index 0000000000000..4230c4b7ab434
--- /dev/null
+++ b/flang/test/Driver/emit-fir.f90
@@ -0,0 +1,30 @@
+! Test the `-emit-fir` option
+
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+! Verify that an `.mlir` file is created when `-emit-fir` is used. Do it in a 
temporary directory, which will be cleaned up by the
+! LIT runner.
+! RUN: rm -rf %t-dir && mkdir -p %t-dir && cd %t-dir
+! RUN: cp %s .
+! RUN: %flang_fc1 -emit-fir emit-fir.f90 && ls emit-fir.mlir
+
+! CHECK: module attributes {
+! CHECK-SAME: dlti.dl_spec =
+! CHECK-SAME: llvm.data_layout =
+! CHECK-LABEL: func @_QQmain() {
+! CHECK-NEXT:  fir.dummy_scope
+! CHECK-NEXT:  return
+! CHECK-NEXT: }
+! CHECK-NEXT: func.func private @_FortranAProgramStart(i32, !llvm.ptr, 
!llvm.ptr, !llvm.ptr)
+! CHECK-NEXT: func.func private @_FortranAProgramEndStatement()
+! CHECK-NEXT: func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) 
-> i32 {
+! CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
+! CHECK-NEXT: %0 = fir.zero_bits !fir.ref<tuple<i32, 
!fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
+! CHECK-NEXT: fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) {{.*}} 
: (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, 
!fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>)
+! CHECK-NEXT: fir.call @_QQmain() fastmath<contract> : () -> ()
+! CHECK-NEXT: fir.call @_FortranAProgramEndStatement() {{.*}} : () -> ()
+! CHECK-NEXT: return %c0_i32 : i32
+! CHECK-NEXT: }
+! CHECK-NEXT: }
+
+end program
diff --git a/flang/test/Driver/emit-mlir.f90 b/flang/test/Driver/emit-mlir.f90
index de5a62d6bc7f3..cced4b0e37017 100644
--- a/flang/test/Driver/emit-mlir.f90
+++ b/flang/test/Driver/emit-mlir.f90
@@ -1,7 +1,6 @@
 ! Test the `-emit-mlir` option
 
 ! RUN: %flang_fc1 -emit-mlir %s -o - | FileCheck %s
-! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
 
 ! Verify that an `.mlir` file is created when `-emit-mlir` is used. Do it in a 
temporary directory, which will be cleaned up by the
 ! LIT runner.
@@ -9,23 +8,22 @@
 ! RUN: cp %s .
 ! RUN: %flang_fc1 -emit-mlir emit-mlir.f90 && ls emit-mlir.mlir
 
-! CHECK: module attributes {
-! CHECK-SAME: dlti.dl_spec =
-! CHECK-SAME: llvm.data_layout =
-! CHECK-LABEL: func @_QQmain() {
-! CHECK-NEXT:  fir.dummy_scope
-! CHECK-NEXT:  return
-! CHECK-NEXT: }
-! CHECK-NEXT: func.func private @_FortranAProgramStart(i32, !llvm.ptr, 
!llvm.ptr, !llvm.ptr)
-! CHECK-NEXT: func.func private @_FortranAProgramEndStatement()
-! CHECK-NEXT: func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) 
-> i32 {
-! CHECK-NEXT: %c0_i32 = arith.constant 0 : i32
-! CHECK-NEXT: %0 = fir.zero_bits !fir.ref<tuple<i32, 
!fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>
-! CHECK-NEXT: fir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) {{.*}} 
: (i32, !llvm.ptr, !llvm.ptr, !fir.ref<tuple<i32, 
!fir.ref<!fir.array<0xtuple<!fir.ref<i8>, !fir.ref<i8>>>>>>) 
-! CHECK-NEXT: fir.call @_QQmain() fastmath<contract> : () -> ()
-! CHECK-NEXT: fir.call @_FortranAProgramEndStatement() {{.*}} : () -> ()
-! CHECK-NEXT: return %c0_i32 : i32
-! CHECK-NEXT: }
-! CHECK-NEXT: }
+! CHECK-LABEL:   llvm.func @_QQmain() {
+! CHECK:           llvm.return
+! CHECK:         }
+! CHECK:         llvm.func @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, 
!llvm.ptr) attributes {sym_visibility = "private"}
+! CHECK:         llvm.func @_FortranAProgramEndStatement() attributes 
{sym_visibility = "private"}
+
+! CHECK-LABEL:   llvm.func @main(
+! CHECK-SAME:                    %[[ARG0:.*]]: i32,
+! CHECK-SAME:                    %[[ARG1:.*]]: !llvm.ptr,
+! CHECK-SAME:                    %[[ARG2:.*]]: !llvm.ptr) -> i32 {
+! CHECK:           %[[VAL_0:.*]] = llvm.mlir.constant(0 : i32) : i32
+! CHECK:           %[[VAL_1:.*]] = llvm.mlir.zero : !llvm.ptr
+! CHECK:           llvm.call @_FortranAProgramStart(%[[ARG0]], %[[ARG1]], 
%[[ARG2]], %[[VAL_1]]) {fastmathFlags = #llvm.fastmath<contract>} : (i32, 
!llvm.ptr, !llvm.ptr, !llvm.ptr) -> ()
+! CHECK:           llvm.call @_QQmain() {fastmathFlags = 
#llvm.fastmath<contract>} : () -> ()
+! CHECK:           llvm.call @_FortranAProgramEndStatement() {fastmathFlags = 
#llvm.fastmath<contract>} : () -> ()
+! CHECK:           llvm.return %[[VAL_0]] : i32
+! CHECK:         }
 
 end program
diff --git a/flang/test/Fir/non-trivial-procedure-binding-description.f90 
b/flang/test/Fir/non-trivial-procedure-binding-description.f90
index 668928600157b..79bb4dbb3521e 100644
--- a/flang/test/Fir/non-trivial-procedure-binding-description.f90
+++ b/flang/test/Fir/non-trivial-procedure-binding-description.f90
@@ -1,5 +1,5 @@
-! RUN: %flang_fc1 -emit-mlir %s -o - | FileCheck %s --check-prefix=BEFORE
-! RUN: %flang_fc1 -emit-mlir %s -o - | fir-opt --abstract-result | FileCheck 
%s --check-prefix=AFTER
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s --check-prefix=BEFORE
+! RUN: %flang_fc1 -emit-fir %s -o - | fir-opt --abstract-result | FileCheck %s 
--check-prefix=AFTER
 module a
   type f
   contains
diff --git a/flang/test/Lower/unsigned-ops.f90 
b/flang/test/Lower/unsigned-ops.f90
index f61f10656159a..fa1eb47b26b00 100644
--- a/flang/test/Lower/unsigned-ops.f90
+++ b/flang/test/Lower/unsigned-ops.f90
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -funsigned -emit-mlir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -funsigned -emit-fir %s -o - | FileCheck %s
 
 unsigned function f01(u, v)
   unsigned, intent(in) :: u, v

``````````

</details>


https://github.com/llvm/llvm-project/pull/139857
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [clang] [... via cfe-commits
    • [cla... via cfe-commits
    • [cla... Tom Eccles via cfe-commits
    • [cla... via cfe-commits
    • [cla... Tarun Prabhu via cfe-commits
    • [cla... Tarun Prabhu via cfe-commits
    • [cla... Tarun Prabhu via cfe-commits
    • [cla... Tarun Prabhu via cfe-commits
    • [cla... via cfe-commits
    • [cla... Valentin Clement バレンタイン クレメン via cfe-commits
    • [cla... via cfe-commits
    • [cla... Tom Eccles via cfe-commits

Reply via email to