tblah created this revision.
tblah added reviewers: awarzynski, vzakhari, jeanPerier, clementval.
Herald added a reviewer: sscalpone.
Herald added a subscriber: sunshaoce.
Herald added projects: Flang, All.
tblah requested review of this revision.
Herald added subscribers: cfe-commits, jdoerfert.
Herald added a project: clang.

In review for https://reviews.llvm.org/D146278, @vzakhari asked to
separate -emit-fir and -emit-hlfir. This will allow FIR to be easily
outputted after the HLFIR passes have been run.

The new semantics are as follows:

| Action      | -flang-experimental-hlfir? | Result                          |
| =========== | ========================== | =============================== |
| -emit-hlfir | N                          | Outputs HLFIR                   |
| -emit-hlfir | Y                          | Outputs HLFIR                   |
| -emit-fir   | N                          | Outputs FIR, using old lowering |
| -emit-fir   | Y                          | Outputs FIR, lowering via HLFIR |
|

A patch for bbc will follow.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151088

Files:
  clang/include/clang/Driver/Options.td
  flang/include/flang/Frontend/FrontendActions.h
  flang/include/flang/Frontend/FrontendOptions.h
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendActions.cpp
  flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
  flang/test/Driver/driver-help.f90
  flang/test/HLFIR/flang-experimental-hlfir-flag.f90

Index: flang/test/HLFIR/flang-experimental-hlfir-flag.f90
===================================================================
--- flang/test/HLFIR/flang-experimental-hlfir-flag.f90
+++ flang/test/HLFIR/flang-experimental-hlfir-flag.f90
@@ -1,19 +1,38 @@
-! Test -flang-experimental-hlfir flag
-! RUN: %flang_fc1 -flang-experimental-hlfir -emit-fir -o - %s | FileCheck %s
-! RUN: %flang_fc1 -emit-fir -o - %s | FileCheck %s --check-prefix NO-HLFIR
+! Test -flang-experimental-hlfir, -emit-hlfir, -emit-fir flags
+! RUN: %flang_fc1 -emit-hlfir -o - %s | FileCheck --check-prefix HLFIR --check-prefix ALL %s
+! RUN: %flang_fc1 -emit-hlfir -flang-experimental-hlfir -o - %s | FileCheck --check-prefix HLFIR --check-prefix ALL %s
+! RUN: %flang_fc1 -emit-fir -o - %s | FileCheck %s --check-prefix NO-HLFIR --check-prefix ALL
+! RUN: %flang_fc1 -emit-fir -flang-experimental-hlfir -o - %s | FileCheck --check-prefix FIR --check-prefix ALL %s
+
+! | Action      | -flang-experimental-hlfir? | Result                          |
+! | =========== | ========================== | =============================== |
+! | -emit-hlfir | N                          | Outputs HLFIR                   |
+! | -emit-hlfir | Y                          | Outputs HLFIR                   |
+! | -emit-fir   | N                          | Outputs FIR, using old lowering |
+! | -emit-fir   | Y                          | Outputs FIR, lowering via HLFIR |
 
 subroutine test(a, res)
   real :: a(:), res
   res = SUM(a)
 end subroutine
-! CHECK-LABEL: func.func @_QPtest
-! CHECK:           %[[A:.*]]: !fir.box<!fir.array<?xf32>>
-! CHECK:           %[[RES:.*]]: !fir.ref<f32>
-! CHECK-DAG:     %[[A_VAR:.*]]:2 = hlfir.declare %[[A]]
-! CHECK-DAG:     %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]]
-! CHECK-NEXT:    %[[SUM_RES:.*]] = hlfir.sum %[[A_VAR]]#0
-! CHECK-NEXT:    hlfir.assign %[[SUM_RES]] to %[[RES_VAR]]#0
-! CHECK-NEXT:    return
-! CHECK-NEXT:  }
+! ALL-LABEL: func.func @_QPtest
+! ALL:             %[[A:.*]]: !fir.box<!fir.array<?xf32>>
+! ALL:             %[[RES:.*]]: !fir.ref<f32>
+
+! HLFIR:         %[[A_VAR:.*]]:2 = hlfir.declare %[[A]]
+! fir.declare is only generated via the hlfir -> fir lowering
+! FIR:           %[[A_VAR:.*]] = fir.declare %[[A]]
+! NO-HLFIR-NOT:  fir.declare
+
+! HLFIR-DAG:     %[[RES_VAR:.*]]:2 = hlfir.declare %[[RES]]
+! FIR:           %[[RES_VAR:.*]] = fir.declare %[[RES]]
+! NO-HLFIR-NOT:  fir.declare
+
+! HLFIR-NEXT:    %[[SUM_RES:.*]] = hlfir.sum %[[A_VAR]]#0
+! HLFIR-NEXT:    hlfir.assign %[[SUM_RES]] to %[[RES_VAR]]#0
+! FIR-NOT:       hlfir.
+! NO-HLFIR-NOT:  hlfir.
+
+! ALL:           return
+! ALL-NEXT:  }
 
-! NO-HLFIR-NOT: hlfir.
Index: flang/test/Driver/driver-help.f90
===================================================================
--- flang/test/Driver/driver-help.f90
+++ flang/test/Driver/driver-help.f90
@@ -94,9 +94,10 @@
 ! HELP-FC1-NEXT:OPTIONS:
 ! HELP-FC1-NEXT: -cpp                   Enable predefined and command line preprocessor macros
 ! HELP-FC1-NEXT: -D <macro>=<value>     Define <macro> to <value> (or 1 if <value> omitted)
+! HELP-FC1-NEXT: -emit-hlfir            Build the parse tree, then lower it to HLFIR
 ! HELP-FC1-NEXT: -emit-llvm-bc          Build ASTs then convert to LLVM, emit .bc file
 ! HELP-FC1-NEXT: -emit-llvm Use the LLVM representation for assembler and object files
-! HELP-FC1-NEXT: -emit-mlir Build the parse tree, then lower it to MLIR
+! HELP-FC1-NEXT: -emit-mlir Build the parse tree, then lower it to FIR
 ! HELP-FC1-NEXT: -emit-obj Emit native object files
 ! HELP-FC1-NEXT: -E                     Only run the preprocessor
 ! HELP-FC1-NEXT: -falternative-parameter-statement
Index: flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
===================================================================
--- flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -42,6 +42,8 @@
     return std::make_unique<ParseSyntaxOnlyAction>();
   case EmitMLIR:
     return std::make_unique<EmitMLIRAction>();
+  case EmitHLFIRToFIR:
+    return std::make_unique<EmitHLFIRToFIRAction>();
   case EmitLLVM:
     return std::make_unique<EmitLLVMAction>();
   case EmitLLVMBitcode:
Index: flang/lib/Frontend/FrontendActions.cpp
===================================================================
--- flang/lib/Frontend/FrontendActions.cpp
+++ flang/lib/Frontend/FrontendActions.cpp
@@ -647,6 +647,34 @@
   }
 }
 
+// Lower using HLFIR then run the FIR to HLFIR pipeline
+void CodeGenAction::lowerHLFIRToFIR() {
+  assert(mlirModule && "The MLIR module has not been generated yet.");
+
+  CompilerInstance &ci = this->getInstance();
+  auto opts = ci.getInvocation().getCodeGenOpts();
+  llvm::OptimizationLevel level = mapToLevel(opts);
+
+  fir::support::loadDialects(*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);
+
+  // Create the pass pipeline
+  fir::createHLFIRToFIRPassPipeline(pm, level);
+  (void)mlir::applyPassManagerCLOptions(pm);
+
+  if (!mlir::succeeded(pm.run(*mlirModule))) {
+    unsigned diagID = ci.getDiagnostics().getCustomDiagID(
+        clang::DiagnosticsEngine::Error, "Lowering to LLVM IR failed");
+    ci.getDiagnostics().Report(diagID);
+  }
+}
+
 // Lower the previously generated MLIR module into an LLVM IR module
 void CodeGenAction::generateLLVMIR() {
   assert(mlirModule && "The MLIR module has not been generated yet.");
@@ -754,6 +782,9 @@
   case BackendActionTy::Backend_EmitMLIR:
     return ci.createDefaultOutputFile(
         /*Binary=*/false, inFile, /*extension=*/"mlir");
+  case BackendActionTy::Backend_EmitFIRViaHLFIR:
+    return ci.createDefaultOutputFile(
+        /*Binary=*/false, inFile, /*extension=*/"mlir");
   case BackendActionTy::Backend_EmitBC:
     return ci.createDefaultOutputFile(
         /*Binary=*/true, inFile, /*extension=*/"bc");
@@ -919,6 +950,12 @@
     return;
   }
 
+  if (action == BackendActionTy::Backend_EmitFIRViaHLFIR) {
+    lowerHLFIRToFIR();
+    mlirModule->print(ci.isOutputStreamNull() ? *os : ci.getOutputStream());
+    return;
+  }
+
   // Generate an LLVM module if it's not already present (it will already be
   // present if the input file is an LLVM IR/BC file).
   if (!llvmModule)
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- flang/lib/Frontend/CompilerInvocation.cpp
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -304,7 +304,13 @@
     case clang::driver::options::OPT_fsyntax_only:
       opts.programAction = ParseSyntaxOnly;
       break;
-    case clang::driver::options::OPT_emit_mlir:
+    case clang::driver::options::OPT_emit_mlir: // -emit-fir
+      if (args.hasArg(clang::driver::options::OPT_flang_experimental_hlfir)) {
+        opts.programAction = EmitHLFIRToFIR;
+        break;
+      }
+      LLVM_FALLTHROUGH;
+    case clang::driver::options::OPT_emit_hlfir:
       opts.programAction = EmitMLIR;
       break;
     case clang::driver::options::OPT_emit_llvm:
@@ -909,7 +915,8 @@
   }
 
   // -flang-experimental-hlfir
-  if (args.hasArg(clang::driver::options::OPT_flang_experimental_hlfir)) {
+  if (args.hasArg(clang::driver::options::OPT_flang_experimental_hlfir) ||
+      args.hasArg(clang::driver::options::OPT_emit_hlfir)) {
     res.loweringOpts.setLowerToHighLevelFIR(true);
   }
 
Index: flang/include/flang/Frontend/FrontendOptions.h
===================================================================
--- flang/include/flang/Frontend/FrontendOptions.h
+++ flang/include/flang/Frontend/FrontendOptions.h
@@ -37,6 +37,10 @@
   /// Emit a .mlir file
   EmitMLIR,
 
+  /// Lower to HLFIR, run the HLFIR pass pipeline, emit a .mlir file with the
+  /// resulting FIR
+  EmitHLFIRToFIR,
+
   /// Emit an .ll file
   EmitLLVM,
 
Index: flang/include/flang/Frontend/FrontendActions.h
===================================================================
--- flang/include/flang/Frontend/FrontendActions.h
+++ flang/include/flang/Frontend/FrontendActions.h
@@ -187,11 +187,13 @@
 /// do. The names are similar to what is used in Clang - this allows us to
 /// maintain some level of consistency/similarity between the drivers.
 enum class BackendActionTy {
-  Backend_EmitAssembly, ///< Emit native assembly files
-  Backend_EmitObj,      ///< Emit native object files
-  Backend_EmitBC,       ///< Emit LLVM bitcode files
-  Backend_EmitLL,       ///< Emit human-readable LLVM assembly
-  Backend_EmitMLIR      ///< Emit MLIR files
+  Backend_EmitAssembly,   ///< Emit native assembly files
+  Backend_EmitObj,        ///< Emit native object files
+  Backend_EmitBC,         ///< Emit LLVM bitcode files
+  Backend_EmitLL,         ///< Emit human-readable LLVM assembly
+  Backend_EmitMLIR,       ///< Emit MLIR files
+  Backend_EmitFIRViaHLFIR ///< Emit MLIR files via HLFIR lowering, after
+                          /// converting to FIR
 };
 
 /// Abstract base class for actions that generate code (MLIR, LLVM IR, assembly
@@ -224,6 +226,9 @@
   /// Embeds offload objects given with specified with -fembed-offload-object
   void embedOffloadObjects();
 
+  /// Runs pass pipeline to lower HLFIR into FIR
+  void lowerHLFIRToFIR();
+
   /// Generates an LLVM IR module from CodeGenAction::mlirModule and saves it
   /// in CodeGenAction::llvmModule.
   void generateLLVMIR();
@@ -241,6 +246,12 @@
   EmitMLIRAction() : CodeGenAction(BackendActionTy::Backend_EmitMLIR) {}
 };
 
+class EmitHLFIRToFIRAction : public CodeGenAction {
+public:
+  EmitHLFIRToFIRAction()
+      : CodeGenAction(BackendActionTy::Backend_EmitFIRViaHLFIR) {}
+};
+
 class EmitLLVMAction : public CodeGenAction {
 public:
   EmitLLVMAction() : CodeGenAction(BackendActionTy::Backend_EmitLL) {}
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -5244,9 +5244,12 @@
 defm analyzed_objects_for_unparse : OptOutFC1FFlag<"analyzed-objects-for-unparse", "", "Do not use the analyzed objects when unparsing">;
 
 def emit_mlir : Flag<["-"], "emit-mlir">, Group<Action_Group>,
-  HelpText<"Build the parse tree, then lower it to MLIR">;
+  HelpText<"Build the parse tree, then lower it to FIR">;
 def emit_fir : Flag<["-"], "emit-fir">, Alias<emit_mlir>;
 
+def emit_hlfir : Flag<["-"], "emit-hlfir">, Group<Action_Group>,
+  HelpText<"Build the parse tree, then lower it to HLFIR">;
+
 } // let Flags = [FC1Option, FlangOnlyOption]
 
 //===----------------------------------------------------------------------===//
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D151088: [flang][hlfir... Tom Eccles via Phabricator via cfe-commits

Reply via email to