diff --git a/flang/include/flang/Optimizer/HLFIR/Passes.td b/flang/include/flang/Optimizer/HLFIR/Passes.td index c6e503c3a2760..dae96b3f767ea 100644 --- a/flang/include/flang/Optimizer/HLFIR/Passes.td +++ b/flang/include/flang/Optimizer/HLFIR/Passes.td @@ -13,6 +13,9 @@ include "mlir/Pass/PassBase.td" def ConvertHLFIRtoFIR : Pass<"convert-hlfir-to-fir", "::mlir::ModuleOp"> { let summary = "Lower High-Level FIR to FIR"; let constructor = "hlfir::createConvertHLFIRtoFIRPass()"; + let dependentDialects = [ + "mlir::func::FuncDialect", + ]; } def BufferizeHLFIR : Pass<"bufferize-hlfir", "::mlir::ModuleOp"> { diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp index a14f3106a7232..d058186758a95 100644 --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -18,6 +18,7 @@ #include "flang/Optimizer/Dialect/FIROpsSupport.h" #include "flang/Optimizer/Support/FatalError.h" #include "flang/Optimizer/Support/InternalNames.h" +#include "mlir/Dialect/OpenACC/OpenACC.h" #include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringExtras.h" @@ -200,9 +201,17 @@ mlir::Value fir::FirOpBuilder::allocateLocal( /// Get the block for adding Allocas. mlir::Block *fir::FirOpBuilder::getAllocaBlock() { - auto iface = - getRegion().getParentOfType(); - return iface ? iface.getAllocaBlock() : getEntryBlock(); + if (auto ompOutlineableIface = + getRegion() + .getParentOfType()) { + return ompOutlineableIface.getAllocaBlock(); + } + if (auto accRecipeIface = + getRegion().getParentOfType()) { + return accRecipeIface.getAllocaBlock(getRegion()); + } + + return getEntryBlock(); } mlir::Value fir::FirOpBuilder::createTemporaryAlloc( diff --git a/flang/test/HLFIR/convert-assign-inside-openacc-recipe.fir b/flang/test/HLFIR/convert-assign-inside-openacc-recipe.fir new file mode 100644 index 0000000000000..5a272bb95cc27 --- /dev/null +++ b/flang/test/HLFIR/convert-assign-inside-openacc-recipe.fir @@ -0,0 +1,51 @@ +// Check that hlfir.assign codegen is able to insert fir.alloca's inside +// the regions of the OpenACC recipe. +// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s + +acc.reduction.recipe @reduction_add_box_heap_Uxi32 : !fir.box>> reduction_operator init { +^bb0(%arg0: !fir.box>>): + %c0_i32 = arith.constant 0 : i32 + %c0 = arith.constant 0 : index + %0:3 = fir.box_dims %arg0, %c0 : (!fir.box>>, index) -> (index, index, index) + %1 = fir.shape %0#1 : (index) -> !fir.shape<1> + %2 = fir.allocmem !fir.array, %0#1 {bindc_name = ".tmp", uniq_name = ""} + %3:2 = hlfir.declare %2(%1) {uniq_name = ".tmp"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) + hlfir.assign %c0_i32 to %3#0 : i32, !fir.box> + acc.yield %3#0 : !fir.box> +} combiner { +^bb0(%arg0: !fir.box>>, %arg1: !fir.box>>, %arg2: index, %arg3: index, %arg4: index): + %c1 = arith.constant 1 : index + %c0 = arith.constant 0 : index + %0 = arith.subi %arg3, %arg2 : index + %1 = arith.addi %0, %c1 : index + %2 = arith.divsi %1, %arg4 : index + %3 = arith.cmpi sgt, %2, %c0 : index + %4 = arith.select %3, %2, %c0 : index + %5 = fir.shape %4 : (index) -> !fir.shape<1> + %6 = hlfir.designate %arg0 (%arg2:%arg3:%arg4) shape %5 : (!fir.box>>, index, index, index, !fir.shape<1>) -> !fir.box>> + %7 = hlfir.designate %arg1 (%arg2:%arg3:%arg4) shape %5 : (!fir.box>>, index, index, index, !fir.shape<1>) -> !fir.box>> + %8 = fir.allocmem !fir.array, %4 {bindc_name = ".tmp.array", uniq_name = ""} + %9:2 = hlfir.declare %8(%5) {uniq_name = ".tmp.array"} : (!fir.heap>, !fir.shape<1>) -> (!fir.box>, !fir.heap>) + %true = arith.constant true + %c1_0 = arith.constant 1 : index + fir.do_loop %arg5 = %c1_0 to %4 step %c1_0 unordered { + %13 = hlfir.designate %6 (%arg5) : (!fir.box>>, index) -> !fir.ref + %14 = hlfir.designate %7 (%arg5) : (!fir.box>>, index) -> !fir.ref + %15 = fir.load %13 : !fir.ref + %16 = fir.load %14 : !fir.ref + %17 = arith.addi %15, %16 : i32 + %18 = hlfir.designate %9#0 (%arg5) : (!fir.box>, index) -> !fir.ref + hlfir.assign %17 to %18 temporary_lhs : i32, !fir.ref + } + %10 = fir.undefined tuple>, i1> + %11 = fir.insert_value %10, %true, [1 : index] : (tuple>, i1>, i1) -> tuple>, i1> + %12 = fir.insert_value %11, %9#0, [0 : index] : (tuple>, i1>, !fir.box>) -> tuple>, i1> + hlfir.assign %9#0 to %arg0 : !fir.box>, !fir.box>> + acc.yield %arg0 : !fir.box>> +} +// CHECK-LABEL: acc.reduction.recipe @reduction_add_box_heap_Uxi32 : !fir.box>> reduction_operator init { +// CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>>): +// CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box> +// CHECK-LABEL: } combiner { +// CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box>>, %[[VAL_1:.*]]: !fir.box>>, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: index, %[[VAL_4:.*]]: index): +// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box>> diff --git a/mlir/include/mlir/Dialect/OpenACC/CMakeLists.txt b/mlir/include/mlir/Dialect/OpenACC/CMakeLists.txt index 02e903da90d09..9dee1280db3ec 100644 --- a/mlir/include/mlir/Dialect/OpenACC/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/OpenACC/CMakeLists.txt @@ -24,3 +24,5 @@ mlir_tablegen(OpenACCTypeInterfaces.h.inc -gen-type-interface-decls) mlir_tablegen(OpenACCTypeInterfaces.cpp.inc -gen-type-interface-defs) add_public_tablegen_target(MLIROpenACCTypeInterfacesIncGen) add_dependencies(mlir-headers MLIROpenACCTypeInterfacesIncGen) + +add_mlir_interface(OpenACCOpsInterfaces) diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h index ca5876fba6745..bc4680656d4cf 100644 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h @@ -33,6 +33,8 @@ #define GET_ATTRDEF_CLASSES #include "mlir/Dialect/OpenACC/OpenACCOpsAttributes.h.inc" +#include "mlir/Dialect/OpenACC/OpenACCInterfaces.h" + #define GET_OP_CLASSES #include "mlir/Dialect/OpenACC/OpenACCOps.h.inc" diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCInterfaces.h b/mlir/include/mlir/Dialect/OpenACC/OpenACCInterfaces.h new file mode 100644 index 0000000000000..5ce094969728f --- /dev/null +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCInterfaces.h @@ -0,0 +1,20 @@ +//===- OpenACCInterfaces.h - MLIR Interfaces for OpenACC --------*- 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 file declares OpenACC Interface implementations for the OpenACC dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_DIALECT_OPENACC_OPENACCINTERFACES_H_ +#define MLIR_DIALECT_OPENACC_OPENACCINTERFACES_H_ + +#include "mlir/IR/OpDefinition.h" + +#include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.h.inc" + +#endif // MLIR_DIALECT_OPENACC_OPENACCINTERFACES_H_ diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td index 60156cc334c72..10018c9fc7e27 100644 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -21,6 +21,7 @@ include "mlir/IR/OpBase.td" include "mlir/IR/SymbolInterfaces.td" include "mlir/Dialect/OpenACC/OpenACCBase.td" include "mlir/Dialect/OpenACC/OpenACCOpsTypes.td" +include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td" include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td" include "mlir/Dialect/OpenACCMPCommon/Interfaces/AtomicInterfaces.td" @@ -519,7 +520,7 @@ def OpenACC_UpdateHostOp : OpenACC_DataExitOp<"update_host", //===----------------------------------------------------------------------===// def OpenACC_PrivateRecipeOp : OpenACC_Op<"private.recipe", - [IsolatedFromAbove, Symbol]> { + [IsolatedFromAbove, Symbol, RecipeInterface]> { let summary = "privatization recipe"; let description = [{ @@ -576,7 +577,7 @@ def OpenACC_PrivateRecipeOp : OpenACC_Op<"private.recipe", //===----------------------------------------------------------------------===// def OpenACC_FirstprivateRecipeOp : OpenACC_Op<"firstprivate.recipe", - [IsolatedFromAbove, Symbol]> { + [IsolatedFromAbove, Symbol, RecipeInterface]> { let summary = "privatization recipe"; let description = [{ @@ -642,7 +643,7 @@ def OpenACC_FirstprivateRecipeOp : OpenACC_Op<"firstprivate.recipe", //===----------------------------------------------------------------------===// def OpenACC_ReductionRecipeOp : OpenACC_Op<"reduction.recipe", - [IsolatedFromAbove, Symbol]> { + [IsolatedFromAbove, Symbol, RecipeInterface]> { let summary = "reduction recipe"; let description = [{ diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td new file mode 100644 index 0000000000000..4c721a328bce7 --- /dev/null +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td @@ -0,0 +1,41 @@ +//===-- OpenACCOpsInterfaces.td - OpenACC op interfaces ----*- 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 +// +//===----------------------------------------------------------------------===// +// +// This is the OpenACC Dialect interfaces definition file. +// +//===----------------------------------------------------------------------===// + +#ifndef OPENACC_OPS_INTERFACES +#define OPENACC_OPS_INTERFACES + +include "mlir/IR/OpBase.td" + +def RecipeInterface : OpInterface<"RecipeInterface"> { + let description = [{ + OpenACC operations with one or more regions holding executable code. + }]; + let cppNamespace = "::mlir::acc"; + let methods = [ + InterfaceMethod< + /*description=*/[{ + For the given region of the operation return the block + inside the region, where an alloca-like operation should be inserted. + The default implementation returns the entry block of the region. + }], + /*retTy*/"::mlir::Block *", + /*methodName=*/"getAllocaBlock", + /*args=*/(ins "::mlir::Region &":$region), + /*methodBody=*/"", + /*defaultImplementation=*/[{ + return ®ion.front(); + }] + >, + ]; +} + +#endif // OPENACC_OPS_INTERFACES diff --git a/mlir/lib/Dialect/OpenACC/CMakeLists.txt b/mlir/lib/Dialect/OpenACC/CMakeLists.txt index 49a1e216b9381..27285246ef997 100644 --- a/mlir/lib/Dialect/OpenACC/CMakeLists.txt +++ b/mlir/lib/Dialect/OpenACC/CMakeLists.txt @@ -8,6 +8,7 @@ add_mlir_dialect_library(MLIROpenACCDialect MLIROpenACCOpsIncGen MLIROpenACCEnumsIncGen MLIROpenACCAttributesIncGen + MLIROpenACCOpsInterfacesIncGen MLIROpenACCTypeInterfacesIncGen LINK_LIBS PUBLIC diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp index 4cb758623093b..98dd53f41ffed 100644 --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -23,6 +23,7 @@ using namespace acc; #include "mlir/Dialect/OpenACC/OpenACCOpsDialect.cpp.inc" #include "mlir/Dialect/OpenACC/OpenACCOpsEnums.cpp.inc" +#include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.cpp.inc" #include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.cpp.inc" namespace {