Skip to content

Commit

Permalink
[flang][openacc] Added acc::RecipeInterface for getting alloca insert…
Browse files Browse the repository at this point in the history
…ion 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.
  • Loading branch information
vzakhari committed Oct 9, 2023
1 parent 2e82696 commit 86b44f3
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 6 deletions.
3 changes: 3 additions & 0 deletions flang/include/flang/Optimizer/HLFIR/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -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"> {
Expand Down
15 changes: 12 additions & 3 deletions flang/lib/Optimizer/Builder/FIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -200,9 +201,17 @@ mlir::Value fir::FirOpBuilder::allocateLocal(

/// Get the block for adding Allocas.
mlir::Block *fir::FirOpBuilder::getAllocaBlock() {
auto iface =
getRegion().getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>();
return iface ? iface.getAllocaBlock() : getEntryBlock();
if (auto ompOutlineableIface =
getRegion()
.getParentOfType<mlir::omp::OutlineableOpenMPOpInterface>()) {
return ompOutlineableIface.getAllocaBlock();
}
if (auto accRecipeIface =
getRegion().getParentOfType<mlir::acc::RecipeInterface>()) {
return accRecipeIface.getAllocaBlock(getRegion());
}

return getEntryBlock();
}

mlir::Value fir::FirOpBuilder::createTemporaryAlloc(
Expand Down
51 changes: 51 additions & 0 deletions flang/test/HLFIR/convert-assign-inside-openacc-recipe.fir
Original file line number Diff line number Diff line change
@@ -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<!fir.heap<!fir.array<?xi32>>> reduction_operator <add> init {
^bb0(%arg0: !fir.box<!fir.heap<!fir.array<?xi32>>>):
%c0_i32 = arith.constant 0 : i32
%c0 = arith.constant 0 : index
%0:3 = fir.box_dims %arg0, %c0 : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
%1 = fir.shape %0#1 : (index) -> !fir.shape<1>
%2 = fir.allocmem !fir.array<?xi32>, %0#1 {bindc_name = ".tmp", uniq_name = ""}
%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>>)
hlfir.assign %c0_i32 to %3#0 : i32, !fir.box<!fir.array<?xi32>>
acc.yield %3#0 : !fir.box<!fir.array<?xi32>>
} combiner {
^bb0(%arg0: !fir.box<!fir.heap<!fir.array<?xi32>>>, %arg1: !fir.box<!fir.heap<!fir.array<?xi32>>>, %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<!fir.heap<!fir.array<?xi32>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
%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>>>
%8 = fir.allocmem !fir.array<?xi32>, %4 {bindc_name = ".tmp.array", uniq_name = ""}
%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>>)
%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<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
%14 = hlfir.designate %7 (%arg5) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
%15 = fir.load %13 : !fir.ref<i32>
%16 = fir.load %14 : !fir.ref<i32>
%17 = arith.addi %15, %16 : i32
%18 = hlfir.designate %9#0 (%arg5) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
hlfir.assign %17 to %18 temporary_lhs : i32, !fir.ref<i32>
}
%10 = fir.undefined tuple<!fir.box<!fir.array<?xi32>>, i1>
%11 = fir.insert_value %10, %true, [1 : index] : (tuple<!fir.box<!fir.array<?xi32>>, i1>, i1) -> tuple<!fir.box<!fir.array<?xi32>>, i1>
%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>
hlfir.assign %9#0 to %arg0 : !fir.box<!fir.array<?xi32>>, !fir.box<!fir.heap<!fir.array<?xi32>>>
acc.yield %arg0 : !fir.box<!fir.heap<!fir.array<?xi32>>>
}
// CHECK-LABEL: acc.reduction.recipe @reduction_add_box_heap_Uxi32 : !fir.box<!fir.heap<!fir.array<?xi32>>> reduction_operator <add> init {
// CHECK: ^bb0(%[[VAL_0:.*]]: !fir.box<!fir.heap<!fir.array<?xi32>>>):
// CHECK: %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.array<?xi32>>
// CHECK-LABEL: } combiner {
// 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):
// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
2 changes: 2 additions & 0 deletions mlir/include/mlir/Dialect/OpenACC/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 2 additions & 0 deletions mlir/include/mlir/Dialect/OpenACC/OpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
20 changes: 20 additions & 0 deletions mlir/include/mlir/Dialect/OpenACC/OpenACCInterfaces.h
Original file line number Diff line number Diff line change
@@ -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_
7 changes: 4 additions & 3 deletions mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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 = [{
Expand Down Expand Up @@ -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 = [{
Expand Down Expand Up @@ -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 = [{
Expand Down
41 changes: 41 additions & 0 deletions mlir/include/mlir/Dialect/OpenACC/OpenACCOpsInterfaces.td
Original file line number Diff line number Diff line change
@@ -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 &region.front();
}]
>,
];
}

#endif // OPENACC_OPS_INTERFACES
1 change: 1 addition & 0 deletions mlir/lib/Dialect/OpenACC/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_mlir_dialect_library(MLIROpenACCDialect
MLIROpenACCOpsIncGen
MLIROpenACCEnumsIncGen
MLIROpenACCAttributesIncGen
MLIROpenACCOpsInterfacesIncGen
MLIROpenACCTypeInterfacesIncGen

LINK_LIBS PUBLIC
Expand Down
1 change: 1 addition & 0 deletions mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 86b44f3

Please sign in to comment.