[flang] add -flang-experimental-hlfir flag to flang-new
authorTom Eccles <tom.eccles@arm.com>
Tue, 14 Mar 2023 13:27:30 +0000 (13:27 +0000)
committerTom Eccles <tom.eccles@arm.com>
Wed, 22 Mar 2023 13:36:54 +0000 (13:36 +0000)
This flag instructs flang-new to use the new HLFIR lowering. It is
marked as experimental and not included in --help.

This was added to make it more convenient to test the performance of
code generated by the HLFIR lowering.

Extra diffs are from running clang-format on CLOptions.inc (which was
being forced by CI).

Differential Revision: https://reviews.llvm.org/D146278

clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Flang.cpp
flang/include/flang/Tools/CLOptions.inc
flang/lib/Frontend/CompilerInvocation.cpp
flang/test/Driver/driver-help-hidden.f90
flang/test/Driver/mlir-pass-pipeline.f90
flang/test/Fir/basic-program.fir
flang/test/HLFIR/flang-experimental-hlfir-flag.f90 [new file with mode: 0644]

index a05e61ac0e92f699c573ecc7d58a7c4e4f9e7001..b50dfd6f35510996223779c71d227cdd78bc6d55 100644 (file)
@@ -5080,6 +5080,10 @@ def flang_experimental_exec : Flag<["-"], "flang-experimental-exec">,
   Flags<[FlangOption, FlangOnlyOption, NoXarchOption, HelpHidden]>,
   HelpText<"Enable support for generating executables (experimental)">;
 
+def flang_experimental_hlfir : Flag<["-"], "flang-experimental-hlfir">,
+  Flags<[FlangOption, FC1Option, FlangOnlyOption, NoXarchOption, HelpHidden]>,
+  HelpText<"Use HLFIR lowering (experimental)">;
+
 //===----------------------------------------------------------------------===//
 // FLangOption + CoreOption + NoXarchOption
 //===----------------------------------------------------------------------===//
index 0a4a0de99b89f802a61b022d44941e06ebaf85a1..23083ff3795b54b7512b5dea850520e3db9e22b9 100644 (file)
@@ -65,6 +65,9 @@ void Flang::addOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
   if (stackArrays &&
       !stackArrays->getOption().matches(options::OPT_fno_stack_arrays))
     CmdArgs.push_back("-fstack-arrays");
+
+  if (Args.hasArg(options::OPT_flang_experimental_hlfir))
+    CmdArgs.push_back("-flang-experimental-hlfir");
 }
 
 void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
index 9324686138717b925f9ef31619f62aa547747c93..30581624d0dc5aa7ede0f5bc7bcd46eec5a1b75c 100644 (file)
@@ -14,6 +14,7 @@
 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
 #include "mlir/Transforms/Passes.h"
 #include "flang/Optimizer/CodeGen/CodeGen.h"
+#include "flang/Optimizer/HLFIR/Passes.h"
 #include "flang/Optimizer/Transforms/Passes.h"
 #include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CommandLine.h"
@@ -72,7 +73,8 @@ DisableOption(BoxedProcedureRewrite, "boxed-procedure-rewrite",
     "rewrite boxed procedures");
 #endif
 
-DisableOption(ExternalNameConversion, "external-name-interop", "convert names with external convention");
+DisableOption(ExternalNameConversion, "external-name-interop",
+    "convert names with external convention");
 
 /// Generic for adding a pass to the pass manager if it is not disabled.
 template <typename F>
@@ -211,6 +213,20 @@ inline void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm,
   pm.addPass(mlir::createCSEPass());
 }
 
+/// Create a pass pipeline for lowering from HLFIR to FIR
+///
+/// \param pm - MLIR pass manager that will hold the pipeline definition
+/// \param optLevel - optimization level used for creating FIR optimization
+///   passes pipeline
+inline void createHLFIRToFIRPassPipeline(
+    mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel) {
+  if (optLevel.isOptimizingForSpeed())
+    pm.addPass(mlir::createCanonicalizerPass());
+  pm.addPass(hlfir::createLowerHLFIRIntrinsicsPass());
+  pm.addPass(hlfir::createBufferizeHLFIRPass());
+  pm.addPass(hlfir::createConvertHLFIRtoFIRPass());
+}
+
 #if !defined(FLANG_EXCLUDE_CODEGEN)
 inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
     llvm::OptimizationLevel optLevel = defaultOptLevel,
@@ -218,8 +234,7 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
   fir::addBoxedProcedurePass(pm);
   pm.addNestedPass<mlir::func::FuncOp>(
       fir::createAbstractResultOnFuncOptPass());
-  pm.addNestedPass<fir::GlobalOp>(
-      fir::createAbstractResultOnGlobalOptPass());
+  pm.addNestedPass<fir::GlobalOp>(fir::createAbstractResultOnGlobalOptPass());
   fir::addCodeGenRewritePass(pm);
   fir::addTargetRewritePass(pm);
   fir::addExternalNameConversionPass(pm, underscoring);
@@ -234,6 +249,8 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
 inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm,
     llvm::OptimizationLevel optLevel = defaultOptLevel,
     bool stackArrays = false, bool underscoring = true) {
+  fir::createHLFIRToFIRPassPipeline(pm, optLevel);
+
   // Add default optimizer pass pipeline.
   fir::createDefaultFIROptimizerPassPipeline(pm, optLevel, stackArrays);
 
index 6e963e252810186b70ae7bf71e22f7b1b9a0c83e..a4183a52115b6b86c01d7424247976c6c17cd013 100644 (file)
@@ -818,6 +818,11 @@ bool CompilerInvocation::createFromArgs(
     success = false;
   }
 
+  // -flang-experimental-hlfir
+  if (args.hasArg(clang::driver::options::OPT_flang_experimental_hlfir)) {
+    res.loweringOpts.setLowerToHighLevelFIR(true);
+  }
+
   success &= parseFrontendArgs(res.getFrontendOpts(), args, diags);
   parseTargetArgs(res.getTargetOpts(), args);
   parsePreprocessorArgs(res.getPreprocessorOpts(), args);
index bcb77c9f8bccbe71caf1f59a7bb3686a4806ef16..535bb82b023c638385a5e4f9b113049e94e93270 100644 (file)
@@ -41,6 +41,8 @@
 ! CHECK-NEXT:                        Specify where to find the compiled intrinsic modules
 ! CHECK-NEXT: -flang-experimental-exec
 ! CHECK-NEXT:                        Enable support for generating executables (experimental)
+! CHECK-NEXT: -flang-experimental-hlfir
+! CHECK-NEXT:                        Use HLFIR lowering (experimental)
 ! CHECK-NEXT: -flarge-sizes          Use INTEGER(KIND=8) for the result type in size-related intrinsics
 ! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations
 ! CHECK-NEXT: -flto=<value> Set LTO mode
index f569ddac8a397fdfe372ed8a03cec55ba90db0e4..3e8df1615adaad24b9032981526f66c34c7f15f9 100644 (file)
@@ -12,6 +12,10 @@ end program
 ! ALL: Pass statistics report
 
 ! ALL: Fortran::lower::VerifierPass
+! O2-NEXT: Canonicalizer
+! ALL-NEXT: LowerHLFIRIntrinsics
+! ALL-NEXT: BufferizeHLFIR
+! ALL-NEXT: ConvertHLFIRtoFIR
 ! ALL-NEXT: CSE
 ! Ideally, we need an output with only the pass names, but
 ! there is currently no way to get that, so in order to
index 78c1ab080db1111d0a701ec2763c3b957bed85f1..e096fb62591e59a922c0fedfa7c3d0d3236b2423 100644 (file)
@@ -16,7 +16,11 @@ func.func @_QQmain() {
 
 // PASSES: Pass statistics report
 
-// PASSES:      CSE
+// PASSES:        Canonicalizer
+// PASSES-NEXT:   LowerHLFIRIntrinsics
+// PASSES-NEXT:   BufferizeHLFIR
+// PASSES-NEXT:   ConvertHLFIRtoFIR
+// PASSES-NEXT:   CSE
 // PASSES-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
 // PASSES-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
 
diff --git a/flang/test/HLFIR/flang-experimental-hlfir-flag.f90 b/flang/test/HLFIR/flang-experimental-hlfir-flag.f90
new file mode 100644 (file)
index 0000000..a375d27
--- /dev/null
@@ -0,0 +1,20 @@
+! 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
+
+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:    hlfir.destroy %[[SUM_RES]]
+! CHECK-NEXT:    return
+! CHECK-NEXT:  }
+
+! NO-HLFIR-NOT: hlfir.