Skip to content

Commit 86b44f3

Browse files
authored
[flang][openacc] Added acc::RecipeInterface for getting alloca insertion point. (#68464)
Conversion of `hlfir.assign` operations inside OpenACC recipe operations may result in `fir.alloca` insertion. FIRBuilder can only handle alloca insertion inside FuncOp's and outlineable OpenMP operations. I added a simple interface for OpenACC recipe operations that have executable code inside all their regions, and alloca may be inserted into the entry blocks of those regions always. With our current approach the OptimizedBufferization pass is supposed to lower these `hlfir.assign` operations into loops, because there should not be conflicts between lhs/rhs. The pass is currently only working on FuncOp, and this is why it does not optimize `hlfir.assign` inside the recipes. I will fix it in a separate commit. Since we run OptimizedBufferization only at >O0, these changes should still be useful. Note that the OpenACC codegen that applies the recipes should be aware of potential alloca operations and produce appropriate stack clean-ups.
1 parent 2e82696 commit 86b44f3

File tree

10 files changed

+137
-6
lines changed

10 files changed

+137
-6
lines changed

flang/include/flang/Optimizer/HLFIR/Passes.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ include "mlir/Pass/PassBase.td"
1313
def ConvertHLFIRtoFIR : Pass<"convert-hlfir-to-fir", "::mlir::ModuleOp"> {
1414
let summary = "Lower High-Level FIR to FIR";
1515
let constructor = "hlfir::createConvertHLFIRtoFIRPass()";
16+
let dependentDialects = [
17+
"mlir::func::FuncDialect",
18+
];
1619
}
1720

1821
def BufferizeHLFIR : Pass<"bufferize-hlfir", "::mlir::ModuleOp"> {

flang/lib/Optimizer/Builder/FIRBuilder.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
1919
#include "flang/Optimizer/Support/FatalError.h"
2020
#include "flang/Optimizer/Support/InternalNames.h"
21+
#include "mlir/Dialect/OpenACC/OpenACC.h"
2122
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
2223
#include "llvm/ADT/ArrayRef.h"
2324
#include "llvm/ADT/StringExtras.h"
@@ -200,9 +201,17 @@ mlir::Value fir::FirOpBuilder::allocateLocal(
200201

201202
/// Get the block for adding Allocas.
202203
mlir::Block *fir::FirOpBuilder::getAllocaBlock() {
203-
auto iface =
204-
getRegion().getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>();
205-
return iface ? iface.getAllocaBlock() : getEntryBlock();
204+
if (auto ompOutlineableIface =
205+
getRegion()
206+
.getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>()) {
207+
return ompOutlineableIface.getAllocaBlock();
208+
}
209+
if (auto accRecipeIface =
210+
getRegion().getParentOfType<mlir::acc::RecipeInterface>()) {
211+
return accRecipeIface.getAllocaBlock(getRegion());
212+
}
213+
214+
return getEntryBlock();
206215
}
207216

208217
mlir::Value fir::FirOpBuilder::createTemporaryAlloc(
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Check that hlfir.assign codegen is able to insert fir.alloca's inside
2+
// the regions of the OpenACC recipe.
3+
// RUN: fir-opt %s -convert-hlfir-to-fir | FileCheck %s
4+
5+
acc.reduction.recipe @reduction_add_box_heap_Uxi32 : !fir.box<!fir.heap<!fir.array<?xi32>>> reduction_operator <add> init {
6+
^bb0(%arg0: !fir.box<!fir.heap<!fir.array<?xi32>>>):
7+
%c0_i32 = arith.constant 0 : i32
8+
%c0 = arith.constant 0 : index
9+
%0:3 = fir.box_dims %arg0, %c0 : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
10+
%1 = fir.shape %0#1 : (index) -> !fir.shape<1>
11+
%2 = fir.allocmem !fir.array<?xi32>, %0#1 {bindc_name = ".tmp", uniq_name = ""}
12+
%3:2 = hlfir.declare %2(%1) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
13+
hlfir.assign %c0_i32 to %3#0 : i32, !fir.box<!fir.array<?xi32>>
14+
acc.yield %3#0 : !fir.box<!fir.array<?xi32>>
15+
} combiner {
16+
^bb0(%arg0: !fir.box<!fir.heap<!fir.array<?xi32>>>, %arg1: !fir.box<!fir.heap<!fir.array<?xi32>>>, %arg2: index, %arg3: index, %arg4: index):
17+
%c1 = arith.constant 1 : index
18+
%c0 = arith.constant 0 : index
19+
%0 = arith.subi %arg3, %arg2 : index
20+
%1 = arith.addi %0, %c1 : index
21+
%2 = arith.divsi %1, %arg4 : index
22+
%3 = arith.cmpi sgt, %2, %c0 : index
23+
%4 = arith.select %3, %2, %c0 : index
24+
%5 = fir.shape %4 : (index) -> !fir.shape<1>
25+
%6 = hlfir.designate %arg0 (%arg2:%arg3:%arg4) shape %5 : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
26+
%7 = hlfir.designate %arg1 (%arg2:%arg3:%arg4) shape %5 : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
27+
%8 = fir.allocmem !fir.array<?xi32>, %4 {bindc_name = ".tmp.array", uniq_name = ""}
28+
%9:2 = hlfir.declare %8(%5) {uniq_name = ".tmp.array"} : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xi32>>, !fir.heap<!fir.array<?xi32>>)
29+
%true = arith.constant true
30+
%c1_0 = arith.constant 1 : index
31+
fir.do_loop %arg5 = %c1_0 to %4 step %c1_0 unordered {
32+
%13 = hlfir.designate %6 (%arg5) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
33+
%14 = hlfir.designate %7 (%arg5) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
34+
%15 = fir.load %13 : !fir.ref<i32>
35+
%16 = fir.load %14 : !fir.ref<i32>
36+
%17 = arith.addi %15, %16 : i32
37+
%18 = hlfir.designate %9#0 (%arg5) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
38+
hlfir.assign %17 to %18 temporary_lhs : i32, !fir.ref<i32>
39+
}
40+
%10 = fir.undefined tuple<!fir.box<!fir.array<?xi32>>, i1>
41+
%11 = fir.insert_value %10, %true, [1 : index] : (tuple<!fir.box<!fir.array<?xi32>>, i1>, i1) -> tuple<!fir.box<!fir.array<?xi32>>, i1>
42+
%12 = fir.insert_value %11, %9#0, [0 : index] : (tuple<!fir.box<!fir.array<?xi32>>, i1>, !fir.box<!fir.array<?xi32>>) -> tuple<!fir.box<!fir.array<?xi32>>, i1>
43+
hlfir.assign %9#0 to %arg0 : !fir.box<!fir.array<?xi32>>, !fir.box<!fir.heap<!fir.array<?xi32>>>
44+
acc.yield %arg0 : !fir.box<!fir.heap<!fir.array<?xi32>>>
45+
}
46+
// CHECK-LABEL: acc.reduction.recipe @reduction_add_box_heap_Uxi32 : !fir.box<!fir.heap<!fir.array<?xi32>>> reduction_operator <add> init {
47+
// CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.heap<!fir.array<?xi32>>>):
48+
// CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.array<?xi32>>
49+
// CHECK-LABEL: } combiner {
50+
// CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.heap<!fir.array<?xi32>>>, %[[VAL_1:.*]]: !fir.box<!fir.heap<!fir.array<?xi32>>>, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: index, %[[VAL_4:.*]]: index):
51+
// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>

mlir/include/mlir/Dialect/OpenACC/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,5 @@ mlir_tablegen(OpenACCTypeInterfaces.h.inc -gen-type-interface-decls)
2424
mlir_tablegen(OpenACCTypeInterfaces.cpp.inc -gen-type-interface-defs)
2525
add_public_tablegen_target(MLIROpenACCTypeInterfacesIncGen)
2626
add_dependencies(mlir-headers MLIROpenACCTypeInterfacesIncGen)
27+
28+
add_mlir_interface(OpenACCOpsInterfaces)

mlir/include/mlir/Dialect/OpenACC/OpenACC.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#define GET_ATTRDEF_CLASSES
3434
#include "mlir/Dialect/OpenACC/OpenACCOpsAttributes.h.inc"
3535

36+
#include "mlir/Dialect/OpenACC/OpenACCInterfaces.h"
37+
3638
#define GET_OP_CLASSES
3739
#include "mlir/Dialect/OpenACC/OpenACCOps.h.inc"
3840

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===- OpenACCInterfaces.h - MLIR Interfaces for OpenACC --------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file declares OpenACC Interface implementations for the OpenACC dialect.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef MLIR_DIALECT_OPENACC_OPENACCINTERFACES_H_
14+
#define MLIR_DIALECT_OPENACC_OPENACCINTERFACES_H_
15+
16+
#include "mlir/IR/OpDefinition.h"
17+
18+
#include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.h.inc"
19+
20+
#endif // MLIR_DIALECT_OPENACC_OPENACCINTERFACES_H_

mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ include "mlir/IR/OpBase.td"
2121
include "mlir/IR/SymbolInterfaces.td"
2222
include "mlir/Dialect/OpenACC/OpenACCBase.td"
2323
include "mlir/Dialect/OpenACC/OpenACCOpsTypes.td"
24+
include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td"
2425
include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td"
2526
include "mlir/Dialect/OpenACCMPCommon/Interfaces/AtomicInterfaces.td"
2627

@@ -519,7 +520,7 @@ def OpenACC_UpdateHostOp : OpenACC_DataExitOp<"update_host",
519520
//===----------------------------------------------------------------------===//
520521

521522
def OpenACC_PrivateRecipeOp : OpenACC_Op<"private.recipe",
522-
[IsolatedFromAbove, Symbol]> {
523+
[IsolatedFromAbove, Symbol, RecipeInterface]> {
523524
let summary = "privatization recipe";
524525

525526
let description = [{
@@ -576,7 +577,7 @@ def OpenACC_PrivateRecipeOp : OpenACC_Op<"private.recipe",
576577
//===----------------------------------------------------------------------===//
577578

578579
def OpenACC_FirstprivateRecipeOp : OpenACC_Op<"firstprivate.recipe",
579-
[IsolatedFromAbove, Symbol]> {
580+
[IsolatedFromAbove, Symbol, RecipeInterface]> {
580581
let summary = "privatization recipe";
581582

582583
let description = [{
@@ -642,7 +643,7 @@ def OpenACC_FirstprivateRecipeOp : OpenACC_Op<"firstprivate.recipe",
642643
//===----------------------------------------------------------------------===//
643644

644645
def OpenACC_ReductionRecipeOp : OpenACC_Op<"reduction.recipe",
645-
[IsolatedFromAbove, Symbol]> {
646+
[IsolatedFromAbove, Symbol, RecipeInterface]> {
646647
let summary = "reduction recipe";
647648

648649
let description = [{
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===-- OpenACCOpsInterfaces.td - OpenACC op interfaces ----*- tablegen -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This is the OpenACC Dialect interfaces definition file.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef OPENACC_OPS_INTERFACES
14+
#define OPENACC_OPS_INTERFACES
15+
16+
include "mlir/IR/OpBase.td"
17+
18+
def RecipeInterface : OpInterface<"RecipeInterface"> {
19+
let description = [{
20+
OpenACC operations with one or more regions holding executable code.
21+
}];
22+
let cppNamespace = "::mlir::acc";
23+
let methods = [
24+
InterfaceMethod<
25+
/*description=*/[{
26+
For the given region of the operation return the block
27+
inside the region, where an alloca-like operation should be inserted.
28+
The default implementation returns the entry block of the region.
29+
}],
30+
/*retTy*/"::mlir::Block *",
31+
/*methodName=*/"getAllocaBlock",
32+
/*args=*/(ins "::mlir::Region &":$region),
33+
/*methodBody=*/"",
34+
/*defaultImplementation=*/[{
35+
return &region.front();
36+
}]
37+
>,
38+
];
39+
}
40+
41+
#endif // OPENACC_OPS_INTERFACES

mlir/lib/Dialect/OpenACC/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ add_mlir_dialect_library(MLIROpenACCDialect
88
MLIROpenACCOpsIncGen
99
MLIROpenACCEnumsIncGen
1010
MLIROpenACCAttributesIncGen
11+
MLIROpenACCOpsInterfacesIncGen
1112
MLIROpenACCTypeInterfacesIncGen
1213

1314
LINK_LIBS PUBLIC

mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ using namespace acc;
2323

2424
#include "mlir/Dialect/OpenACC/OpenACCOpsDialect.cpp.inc"
2525
#include "mlir/Dialect/OpenACC/OpenACCOpsEnums.cpp.inc"
26+
#include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.cpp.inc"
2627
#include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.cpp.inc"
2728

2829
namespace {

0 commit comments

Comments
 (0)