diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5080,6 +5080,10 @@ 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 //===----------------------------------------------------------------------===// diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -65,6 +65,9 @@ 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 { diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc --- a/flang/include/flang/Tools/CLOptions.inc +++ b/flang/include/flang/Tools/CLOptions.inc @@ -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" @@ -226,6 +227,19 @@ fir::addFIRToLLVMPass(pm, optLevel); } +/// 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) { + pm.addPass(mlir::createCanonicalizerPass()); + pm.addPass(hlfir::createLowerHLFIRIntrinsicsPass()); + pm.addPass(hlfir::createBufferizeHLFIRPass()); + pm.addPass(hlfir::createConvertHLFIRtoFIRPass()); +} + /// Create a pass pipeline for lowering from MLIR to LLVM IR /// /// \param pm - MLIR pass manager that will hold the pipeline definition @@ -233,7 +247,10 @@ /// passes pipeline inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel, - bool stackArrays = false, bool underscoring = true) { + bool stackArrays = false, bool underscoring = true, bool useHLFIR = false) { + if (useHLFIR) + fir::createHLFIRToFIRPassPipeline(pm, optLevel); + // Add default optimizer pass pipeline. fir::createDefaultFIROptimizerPassPipeline(pm, optLevel, stackArrays); diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -818,6 +818,11 @@ 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); diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -539,6 +539,7 @@ CompilerInstance &ci = this->getInstance(); auto opts = ci.getInvocation().getCodeGenOpts(); + auto loweringOpts = ci.getInvocation().getLoweringOpts(); llvm::OptimizationLevel level = mapToLevel(opts); fir::support::loadDialects(*mlirCtx); @@ -553,7 +554,8 @@ // Create the pass pipeline fir::createMLIRToLLVMPassPipeline(pm, level, opts.StackArrays, - opts.Underscoring); + opts.Underscoring, + loweringOpts.getLowerToHighLevelFIR()); mlir::applyPassManagerCLOptions(pm); // run the pass manager diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 --- a/flang/test/Driver/driver-help-hidden.f90 +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -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= Set LTO mode