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
//===----------------------------------------------------------------------===//
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 {
#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"
"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>
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,
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);
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);
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);
! 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
! 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
// 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
--- /dev/null
+! 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.