diff --git a/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td b/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td --- a/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td +++ b/flang/include/flang/Optimizer/Dialect/FortranVariableInterface.td @@ -115,6 +115,13 @@ fir::FortranVariableFlagsEnum::allocatable); } + /// Is this variable a Fortran optional ? + bool isOptional() { + auto attrs = getFortranAttrs(); + return attrs && bitEnumContainsAny(*attrs, + fir::FortranVariableFlagsEnum::optional); + } + /// Is this a Fortran character variable ? bool isCharacter() { return getElementType().isa(); diff --git a/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt b/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt --- a/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt +++ b/flang/include/flang/Optimizer/HLFIR/CMakeLists.txt @@ -10,4 +10,7 @@ mlir_tablegen(HLFIROps.h.inc -gen-op-decls) mlir_tablegen(HLFIROps.cpp.inc -gen-op-defs) +set(LLVM_TARGET_DEFINITIONS Passes.td) +mlir_tablegen(Passes.h.inc -gen-pass-decls -name HLFIR) + add_public_tablegen_target(HLFIROpsIncGen) diff --git a/flang/include/flang/Optimizer/HLFIR/Passes.h b/flang/include/flang/Optimizer/HLFIR/Passes.h new file mode 100644 --- /dev/null +++ b/flang/include/flang/Optimizer/HLFIR/Passes.h @@ -0,0 +1,30 @@ +//===- Passes.h - HLFIR pass entry points ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This header declares HLFIR pass entry points. +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_OPTIMIZER_HLFIR_PASSES_H +#define FORTRAN_OPTIMIZER_HLFIR_PASSES_H + +#include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassRegistry.h" +#include + +namespace hlfir { +#define GEN_PASS_DECL +#include "flang/Optimizer/HLFIR/Passes.h.inc" + +std::unique_ptr createConvertHLFIRtoFIRPass(); + +#define GEN_PASS_REGISTRATION +#include "flang/Optimizer/HLFIR/Passes.h.inc" +} // namespace hlfir + +#endif // FORTRAN_OPTIMIZER_HLFIR_PASSES_H diff --git a/flang/include/flang/Optimizer/HLFIR/Passes.td b/flang/include/flang/Optimizer/HLFIR/Passes.td new file mode 100644 --- /dev/null +++ b/flang/include/flang/Optimizer/HLFIR/Passes.td @@ -0,0 +1,18 @@ +//===-- Passes.td - HLFIR pass definition file -------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_DIALECT_HLFIR_PASSES +#define FORTRAN_DIALECT_HLFIR_PASSES + +include "mlir/Pass/PassBase.td" +def ConvertHLFIRtoFIR : Pass<"convert-hlfir-to-fir", "::mlir::func::FuncOp"> { + let summary = "Lower High-Level FIR to FIR"; + let constructor = "hlfir::createConvertHLFIRtoFIRPass()"; +} + +#endif //FORTRAN_DIALECT_HLFIR_PASSES diff --git a/flang/lib/Frontend/CMakeLists.txt b/flang/lib/Frontend/CMakeLists.txt --- a/flang/lib/Frontend/CMakeLists.txt +++ b/flang/lib/Frontend/CMakeLists.txt @@ -33,6 +33,7 @@ FIRCodeGen FIRTransforms HLFIRDialect + HLFIRTransforms MLIRTransforms MLIRLLVMToLLVMIRTranslation MLIRSCFToControlFlow diff --git a/flang/lib/Optimizer/HLFIR/CMakeLists.txt b/flang/lib/Optimizer/HLFIR/CMakeLists.txt --- a/flang/lib/Optimizer/HLFIR/CMakeLists.txt +++ b/flang/lib/Optimizer/HLFIR/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(IR) +add_subdirectory(Transforms) diff --git a/flang/lib/Optimizer/HLFIR/Transforms/CMakeLists.txt b/flang/lib/Optimizer/HLFIR/Transforms/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/flang/lib/Optimizer/HLFIR/Transforms/CMakeLists.txt @@ -0,0 +1,23 @@ +get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) + +add_flang_library(HLFIRTransforms + ConvertToFIR.cpp + + DEPENDS + FIRDialect + HLFIROpsIncGen + ${dialect_libs} + + LINK_LIBS + FIRDialect + FIRBuilder + FIRSupport + HLFIRDialect + MLIRIR + ${dialect_libs} + + LINK_COMPONENTS + AsmParser + AsmPrinter + Remarks +) diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp new file mode 100644 --- /dev/null +++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp @@ -0,0 +1,119 @@ +//===- ConvertToFIR.cpp - Convert HLFIR to FIR ----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// This file defines a pass to lower HLFIR to FIR +//===----------------------------------------------------------------------===// + +#include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/HLFIRTools.h" +#include "flang/Optimizer/Builder/MutableBox.h" +#include "flang/Optimizer/Builder/Runtime/Assign.h" +#include "flang/Optimizer/Builder/Todo.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Optimizer/HLFIR/HLFIROps.h" +#include "flang/Optimizer/HLFIR/Passes.h" +#include "flang/Optimizer/Support/FIRContext.h" +#include "mlir/Transforms/DialectConversion.h" + +namespace hlfir { +#define GEN_PASS_DEF_CONVERTHLFIRTOFIR +#include "flang/Optimizer/HLFIR/Passes.h.inc" +} // namespace hlfir + +using namespace mlir; + +namespace { +class DeclareOpConversion : public mlir::OpRewritePattern { +public: + explicit DeclareOpConversion(mlir::MLIRContext *ctx) + : OpRewritePattern{ctx} {} + + mlir::LogicalResult + matchAndRewrite(hlfir::DeclareOp declareOp, + mlir::PatternRewriter &rewriter) const override { + mlir::Location loc = declareOp->getLoc(); + mlir::Value memref = declareOp.getMemref(); + fir::FortranVariableFlagsAttr fortranAttrs; + if (auto attrs = declareOp.getFortranAttrs()) + fortranAttrs = + fir::FortranVariableFlagsAttr::get(rewriter.getContext(), *attrs); + auto firBase = rewriter + .create( + loc, memref.getType(), memref, declareOp.getShape(), + declareOp.getTypeparams(), declareOp.getUniqName(), + fortranAttrs) + .getResult(); + mlir::Value hlfirBase; + mlir::Type hlfirBaseType = declareOp.getBase().getType(); + if (hlfirBaseType.isa()) { + // Need to conditionally rebox/embox for optional. + if (mlir::cast(declareOp.getOperation()) + .isOptional()) + TODO(loc, "converting hlfir declare of optional box to fir"); + if (!firBase.getType().isa()) { + llvm::SmallVector typeParams; + auto maybeCharType = + fir::unwrapSequenceType(fir::unwrapPassByRefType(hlfirBaseType)) + .dyn_cast(); + if (!maybeCharType || maybeCharType.hasDynamicLen()) + typeParams.append(declareOp.getTypeparams().begin(), + declareOp.getTypeparams().end()); + hlfirBase = rewriter.create( + loc, hlfirBaseType, firBase, declareOp.getShape(), + /*slice=*/mlir::Value{}, typeParams); + } else { + // Rebox so that lower bounds are correct. + hlfirBase = rewriter.create(loc, hlfirBaseType, firBase, + declareOp.getShape(), + /*slice=*/mlir::Value{}); + } + } else if (hlfirBaseType.isa()) { + assert(declareOp.getTypeparams().size() == 1 && + "must contain character length"); + hlfirBase = rewriter.create( + loc, hlfirBaseType, firBase, declareOp.getTypeparams()[0]); + } else { + if (hlfirBaseType != firBase.getType()) { + declareOp.emitOpError() + << "unhandled HLFIR variable type '" << hlfirBaseType << "'\n"; + return mlir::failure(); + } + hlfirBase = firBase; + } + rewriter.replaceOp(declareOp, {hlfirBase, firBase}); + return mlir::success(); + } +}; + +class ConvertHLFIRtoFIR + : public hlfir::impl::ConvertHLFIRtoFIRBase { +public: + void runOnOperation() override { + auto func = this->getOperation(); + auto *context = &getContext(); + mlir::RewritePatternSet patterns(context); + patterns.insert(context); + mlir::ConversionTarget target(*context); + target.addIllegalDialect(); + target.markUnknownOpDynamicallyLegal( + [](mlir::Operation *) { return true; }); + if (mlir::failed( + mlir::applyPartialConversion(func, target, std::move(patterns)))) { + mlir::emitError(mlir::UnknownLoc::get(context), + "failure in HLFIR to FIR conversion pass"); + signalPassFailure(); + } + } +}; + +} // namespace + +std::unique_ptr hlfir::createConvertHLFIRtoFIRPass() { + return std::make_unique(); +} diff --git a/flang/test/HLFIR/declare-codegen.fir b/flang/test/HLFIR/declare-codegen.fir new file mode 100644 --- /dev/null +++ b/flang/test/HLFIR/declare-codegen.fir @@ -0,0 +1,180 @@ +// Test hlfir.declare operation code generation to FIR + +// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s + +func.func @numeric_declare(%arg0: !fir.ref) { + %0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.ref) -> (!fir.ref, !fir.ref) + return +} +// CHECK-LABEL: func.func @numeric_declare( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref) { +// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.ref) -> !fir.ref + + +func.func @char_declare(%arg0: !fir.boxchar<1> ) { + %0:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref>, index) + %1:2 = hlfir.declare %0#0 typeparams %0#1 {uniq_name = "c"} : (!fir.ref>, index) -> (!fir.boxchar<1>, !fir.ref>) + return +} +// CHECK-LABEL: func.func @char_declare( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>) { +// CHECK: %[[VAL_1:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) +// CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_1]]#0 typeparams %[[VAL_1]]#1 {uniq_name = "c"} : (!fir.ref>, index) -> !fir.ref> +// CHECK: %[[VAL_3:.*]] = fir.emboxchar %[[VAL_2]], %[[VAL_1]]#1 : (!fir.ref>, index) -> !fir.boxchar<1> + + +func.func @derived_declare(%arg0: !fir.ref>) { + %0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) + return +} +// CHECK-LABEL: func.func @derived_declare( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>) { +// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.ref>) -> !fir.ref> + + +func.func @pdt_declare(%arg0: !fir.ref>) { + %c1 = arith.constant 1 : index + %0:2 = hlfir.declare %arg0 typeparams %c1 {uniq_name = "x"} : (!fir.ref>, index) -> (!fir.box>, !fir.ref>) + return +} +// CHECK-LABEL: func.func @pdt_declare( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "x"} : (!fir.ref>, index) -> !fir.ref> +// CHECK: %[[VAL_3:.*]] = fir.embox %[[VAL_2]] typeparams %[[VAL_1]] : (!fir.ref>, index) -> !fir.box> + + +func.func @array_declare(%arg0: !fir.ref>) { + %c1 = arith.constant 1 : index + %c2 = arith.constant 2 : index + %shape = fir.shape %c1, %c2 : (index, index) -> !fir.shape<2> + %0:2 = hlfir.declare %arg0(%shape) {uniq_name = "x"} : (!fir.ref>, !fir.shape<2>) -> (!fir.box>, !fir.ref>) + return +} +// CHECK-LABEL: func.func @array_declare( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_4:.*]] = fir.declare %[[VAL_0]](%[[VAL_3]]) {uniq_name = "x"} : (!fir.ref>, !fir.shape<2>) -> !fir.ref> +// CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_4]](%[[VAL_3]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> + + +func.func @array_declare_2(%arg0: !fir.ref>) { + %c1 = arith.constant 1 : index + %c2 = arith.constant 2 : index + %c3 = arith.constant 3 : index + %c4 = arith.constant 4 : index + %shape = fir.shape_shift %c1, %c2, %c3, %c4 : (index, index, index, index) -> !fir.shapeshift<2> + %0:2 = hlfir.declare %arg0(%shape) {uniq_name = "x"} : (!fir.ref>, !fir.shapeshift<2>) -> (!fir.box>, !fir.ref>) + return +} +// CHECK-LABEL: func.func @array_declare_2( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_4:.*]] = arith.constant 4 : index +// CHECK: %[[VAL_5:.*]] = fir.shape_shift %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]] : (index, index, index, index) -> !fir.shapeshift<2> +// CHECK: %[[VAL_6:.*]] = fir.declare %[[VAL_0]](%[[VAL_5]]) {uniq_name = "x"} : (!fir.ref>, !fir.shapeshift<2>) -> !fir.ref> +// CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]](%[[VAL_5]]) : (!fir.ref>, !fir.shapeshift<2>) -> !fir.box> + +func.func @array_declare_constant_extents_with_lower_bounds(%arg0: !fir.ref>) { + %c1 = arith.constant 1 : index + %c2 = arith.constant 2 : index + %c3 = arith.constant 3 : index + %c4 = arith.constant 4 : index + %shape = fir.shape_shift %c1, %c2, %c3, %c4 : (index, index, index, index) -> !fir.shapeshift<2> + %0:2 = hlfir.declare %arg0(%shape) {uniq_name = "x"} : (!fir.ref>, !fir.shapeshift<2>) -> (!fir.box>, !fir.ref>) + return +} +// CHECK-LABEL: func.func @array_declare_constant_extents_with_lower_bounds( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_4:.*]] = arith.constant 4 : index +// CHECK: %[[VAL_5:.*]] = fir.shape_shift %[[VAL_1]], %[[VAL_2]], %[[VAL_3]], %[[VAL_4]] : (index, index, index, index) -> !fir.shapeshift<2> +// CHECK: %[[VAL_6:.*]] = fir.declare %[[VAL_0]](%[[VAL_5]]) {uniq_name = "x"} : (!fir.ref>, !fir.shapeshift<2>) -> !fir.ref> +// CHECK: %[[VAL_7:.*]] = fir.embox %[[VAL_6]](%[[VAL_5]]) : (!fir.ref>, !fir.shapeshift<2>) -> !fir.box> + + +func.func @array_declare_box(%arg0: !fir.box>) { + %c1 = arith.constant 1 : index + %c2 = arith.constant 2 : index + %shape = fir.shift %c1, %c2 : (index, index) -> !fir.shift<2> + %0:2 = hlfir.declare %arg0(%shape) {uniq_name = "x"} : (!fir.box>, !fir.shift<2>) -> (!fir.box>, !fir.box>) + return +} +// CHECK-LABEL: func.func @array_declare_box( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = fir.shift %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shift<2> +// CHECK: %[[VAL_4:.*]] = fir.declare %[[VAL_0]](%[[VAL_3]]) {uniq_name = "x"} : (!fir.box>, !fir.shift<2>) -> !fir.box> +// CHECK: %[[VAL_5:.*]] = fir.rebox %[[VAL_4]](%[[VAL_3]]) : (!fir.box>, !fir.shift<2>) -> !fir.box> + + +func.func @array_declare_box_2(%arg0: !fir.box>) { + %0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box>) -> (!fir.box>, !fir.box>) + return +} +// CHECK-LABEL: func.func @array_declare_box_2( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>) { +// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_2:.*]] = fir.rebox %[[VAL_1]] : (!fir.box>) -> !fir.box> + +func.func @array_declare_char_box(%arg0: !fir.box>>) { + %0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.box>>) -> (!fir.box>>, !fir.box>>) + return +} +// CHECK-LABEL: func.func @array_declare_char_box( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>>) { +// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.box>>) -> !fir.box>> +// CHECK: %[[VAL_2:.*]] = fir.rebox %[[VAL_1]] : (!fir.box>>) -> !fir.box>> + + +func.func @array_declare_char_box_2(%arg0: !fir.box>>) { + %c1 = arith.constant 1 : index + %c2 = arith.constant 2 : index + %c3 = arith.constant 3 : index + %shape = fir.shift %c1, %c2 : (index, index) -> !fir.shift<2> + %0:2 = hlfir.declare %arg0(%shape) typeparams %c3 {uniq_name = "x"} : (!fir.box>>, !fir.shift<2>, index) -> (!fir.box>>, !fir.box>>) + return +} +// CHECK-LABEL: func.func @array_declare_char_box_2( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_4:.*]] = fir.shift %[[VAL_1]], %[[VAL_2]] : (index, index) -> !fir.shift<2> +// CHECK: %[[VAL_5:.*]] = fir.declare %[[VAL_0]](%[[VAL_4]]) typeparams %[[VAL_3]] {uniq_name = "x"} : (!fir.box>>, !fir.shift<2>, index) -> !fir.box>> +// CHECK: %[[VAL_6:.*]] = fir.rebox %[[VAL_5]](%[[VAL_4]]) : (!fir.box>>, !fir.shift<2>) -> !fir.box>> + + +func.func @array_declare_char_boxaddr(%arg0: !fir.ref>>>>) { + %0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) + return +} +// CHECK-LABEL: func.func @array_declare_char_boxaddr( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>>) { +// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.ref>>>>) -> !fir.ref>>>> + + +func.func @array_declare_char_boxaddr_2(%arg0: !fir.ref>>>>) { + %c3 = arith.constant 3 : index + %0:2 = hlfir.declare %arg0 typeparams %c3 {uniq_name = "x"} : (!fir.ref>>>>, index) -> (!fir.ref>>>>, !fir.ref>>>>) + return +} +// CHECK-LABEL: func.func @array_declare_char_boxaddr_2( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>>) { +// CHECK: %[[VAL_1:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_2:.*]] = fir.declare %[[VAL_0]] typeparams %[[VAL_1]] {uniq_name = "x"} : (!fir.ref>>>>, index) -> !fir.ref>>>> + +func.func @array_declare_unlimited_polymorphic_boxaddr(%arg0: !fir.ref>>>) { + %0:2 = hlfir.declare %arg0 {uniq_name = "x"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) + return +} +// CHECK-LABEL: func.func @array_declare_unlimited_polymorphic_boxaddr( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>) { +// CHECK: %[[VAL_1:.*]] = fir.declare %[[VAL_0]] {uniq_name = "x"} : (!fir.ref>>>) -> !fir.ref>>> diff --git a/flang/tools/bbc/CMakeLists.txt b/flang/tools/bbc/CMakeLists.txt --- a/flang/tools/bbc/CMakeLists.txt +++ b/flang/tools/bbc/CMakeLists.txt @@ -15,6 +15,7 @@ FIRTransforms FIRBuilder HLFIRDialect +HLFIRTransforms ${dialect_libs} MLIRAffineToStandard MLIRSCFToControlFlow diff --git a/flang/tools/fir-opt/CMakeLists.txt b/flang/tools/fir-opt/CMakeLists.txt --- a/flang/tools/fir-opt/CMakeLists.txt +++ b/flang/tools/fir-opt/CMakeLists.txt @@ -14,6 +14,7 @@ FIRTransforms FIRCodeGen HLFIRDialect + HLFIRTransforms FIRAnalysis ${test_libs} ${dialect_libs} diff --git a/flang/tools/fir-opt/fir-opt.cpp b/flang/tools/fir-opt/fir-opt.cpp --- a/flang/tools/fir-opt/fir-opt.cpp +++ b/flang/tools/fir-opt/fir-opt.cpp @@ -13,6 +13,7 @@ #include "mlir/Tools/mlir-opt/MlirOptMain.h" #include "flang/Optimizer/CodeGen/CodeGen.h" +#include "flang/Optimizer/HLFIR/Passes.h" #include "flang/Optimizer/Support/InitFIR.h" #include "flang/Optimizer/Transforms/Passes.h" @@ -27,6 +28,7 @@ fir::support::registerMLIRPassesForFortranTools(); fir::registerOptCodeGenPasses(); fir::registerOptTransformPasses(); + hlfir::registerHLFIRPasses(); #ifdef FLANG_INCLUDE_TESTS fir::test::registerTestFIRAliasAnalysisPass(); #endif diff --git a/flang/tools/tco/CMakeLists.txt b/flang/tools/tco/CMakeLists.txt --- a/flang/tools/tco/CMakeLists.txt +++ b/flang/tools/tco/CMakeLists.txt @@ -12,6 +12,7 @@ FIRTransforms FIRBuilder HLFIRDialect + HLFIRTransforms ${dialect_libs} MLIRIR MLIRLLVMDialect