Skip to content

Commit 2feaa77

Browse files
razvanlupusoruLukacma
authored andcommitted
[mlir][acc] Add utilities for acc dialect (llvm#164022)
Created new OpenACC utilities library (MLIROpenACCUtils) containing helper functions for region analysis, value usage checking, default attribute lookup, and type categorization. Includes comprehensive unit tests and refactors existing getEnclosingComputeOp function into the new library.
1 parent bae4ede commit 2feaa77

File tree

9 files changed

+563
-17
lines changed

9 files changed

+563
-17
lines changed

flang/lib/Lower/OpenACC.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "flang/Semantics/scope.h"
3535
#include "flang/Semantics/tools.h"
3636
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
37+
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
3738
#include "mlir/IR/IRMapping.h"
3839
#include "mlir/IR/MLIRContext.h"
3940
#include "mlir/Support/LLVM.h"

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,6 @@ mlir::ValueRange getDataOperands(mlir::Operation *accOp);
152152
/// Used to get a mutable range iterating over the data operands.
153153
mlir::MutableOperandRange getMutableDataOperands(mlir::Operation *accOp);
154154

155-
/// Used to obtain the enclosing compute construct operation that contains
156-
/// the provided `region`. Returns nullptr if no compute construct operation
157-
/// is found. The returns operation is one of types defined by
158-
///`ACC_COMPUTE_CONSTRUCT_OPS`.
159-
mlir::Operation *getEnclosingComputeOp(mlir::Region &region);
160-
161155
/// Used to check whether the provided `type` implements the `PointerLikeType`
162156
/// interface.
163157
inline bool isPointerLikeType(mlir::Type type) {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===- OpenACCUtils.h - OpenACC Utilities -----------------------*- 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+
#ifndef MLIR_DIALECT_OPENACC_OPENACCUTILS_H_
10+
#define MLIR_DIALECT_OPENACC_OPENACCUTILS_H_
11+
12+
#include "mlir/Dialect/OpenACC/OpenACC.h"
13+
14+
namespace mlir {
15+
namespace acc {
16+
17+
/// Used to obtain the enclosing compute construct operation that contains
18+
/// the provided `region`. Returns nullptr if no compute construct operation
19+
/// is found. The returned operation is one of types defined by
20+
/// `ACC_COMPUTE_CONSTRUCT_OPS`.
21+
mlir::Operation *getEnclosingComputeOp(mlir::Region &region);
22+
23+
/// Returns true if this value is only used by `acc.private` operations in the
24+
/// `region`.
25+
bool isOnlyUsedByPrivateClauses(mlir::Value val, mlir::Region &region);
26+
27+
/// Returns true if this value is only used by `acc.reduction` operations in
28+
/// the `region`.
29+
bool isOnlyUsedByReductionClauses(mlir::Value val, mlir::Region &region);
30+
31+
/// Looks for an OpenACC default attribute on the current operation `op` or in
32+
/// a parent operation which encloses `op`. This is useful because OpenACC
33+
/// specification notes that a visible default clause is the nearest default
34+
/// clause appearing on the compute construct or a lexically containing data
35+
/// construct.
36+
std::optional<ClauseDefaultValue> getDefaultAttr(mlir::Operation *op);
37+
38+
/// Get the type category of an OpenACC variable.
39+
mlir::acc::VariableTypeCategory getTypeCategory(mlir::Value var);
40+
41+
} // namespace acc
42+
} // namespace mlir
43+
44+
#endif // MLIR_DIALECT_OPENACC_OPENACCUTILS_H_
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
add_subdirectory(IR)
2+
add_subdirectory(Utils)
23
add_subdirectory(Transforms)

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

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4650,14 +4650,3 @@ mlir::acc::getMutableDataOperands(mlir::Operation *accOp) {
46504650
.Default([&](mlir::Operation *) { return nullptr; })};
46514651
return dataOperands;
46524652
}
4653-
4654-
mlir::Operation *mlir::acc::getEnclosingComputeOp(mlir::Region &region) {
4655-
mlir::Operation *parentOp = region.getParentOp();
4656-
while (parentOp) {
4657-
if (mlir::isa<ACC_COMPUTE_CONSTRUCT_OPS>(parentOp)) {
4658-
return parentOp;
4659-
}
4660-
parentOp = parentOp->getParentOp();
4661-
}
4662-
return nullptr;
4663-
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
add_mlir_dialect_library(MLIROpenACCUtils
2+
OpenACCUtils.cpp
3+
4+
ADDITIONAL_HEADER_DIRS
5+
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/OpenACC
6+
7+
DEPENDS
8+
MLIROpenACCPassIncGen
9+
MLIROpenACCOpsIncGen
10+
MLIROpenACCEnumsIncGen
11+
MLIROpenACCAttributesIncGen
12+
MLIROpenACCMPOpsInterfacesIncGen
13+
MLIROpenACCOpsInterfacesIncGen
14+
MLIROpenACCTypeInterfacesIncGen
15+
16+
LINK_LIBS PUBLIC
17+
MLIROpenACCDialect
18+
MLIRIR
19+
MLIRSupport
20+
)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//===- OpenACCUtils.cpp ---------------------------------------------------===//
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+
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
10+
11+
#include "mlir/Dialect/OpenACC/OpenACC.h"
12+
#include "llvm/ADT/TypeSwitch.h"
13+
14+
mlir::Operation *mlir::acc::getEnclosingComputeOp(mlir::Region &region) {
15+
mlir::Operation *parentOp = region.getParentOp();
16+
while (parentOp) {
17+
if (mlir::isa<ACC_COMPUTE_CONSTRUCT_OPS>(parentOp))
18+
return parentOp;
19+
parentOp = parentOp->getParentOp();
20+
}
21+
return nullptr;
22+
}
23+
24+
template <typename OpTy>
25+
static bool isOnlyUsedByOpClauses(mlir::Value val, mlir::Region &region) {
26+
auto checkIfUsedOnlyByOpInside = [&](mlir::Operation *user) {
27+
// For any users which are not in the current acc region, we can ignore.
28+
// Return true so that it can be used in a `all_of` check.
29+
if (!region.isAncestor(user->getParentRegion()))
30+
return true;
31+
return mlir::isa<OpTy>(user);
32+
};
33+
34+
return llvm::all_of(val.getUsers(), checkIfUsedOnlyByOpInside);
35+
}
36+
37+
bool mlir::acc::isOnlyUsedByPrivateClauses(mlir::Value val,
38+
mlir::Region &region) {
39+
return isOnlyUsedByOpClauses<mlir::acc::PrivateOp>(val, region);
40+
}
41+
42+
bool mlir::acc::isOnlyUsedByReductionClauses(mlir::Value val,
43+
mlir::Region &region) {
44+
return isOnlyUsedByOpClauses<mlir::acc::ReductionOp>(val, region);
45+
}
46+
47+
std::optional<mlir::acc::ClauseDefaultValue>
48+
mlir::acc::getDefaultAttr(Operation *op) {
49+
std::optional<mlir::acc::ClauseDefaultValue> defaultAttr;
50+
Operation *currOp = op;
51+
52+
// Iterate outwards until a default clause is found (since OpenACC
53+
// specification notes that a visible default clause is the nearest default
54+
// clause appearing on the compute construct or a lexically containing data
55+
// construct.
56+
while (!defaultAttr.has_value() && currOp) {
57+
defaultAttr =
58+
llvm::TypeSwitch<mlir::Operation *,
59+
std::optional<mlir::acc::ClauseDefaultValue>>(currOp)
60+
.Case<ACC_COMPUTE_CONSTRUCT_OPS, mlir::acc::DataOp>(
61+
[&](auto op) { return op.getDefaultAttr(); })
62+
.Default([&](Operation *) { return std::nullopt; });
63+
currOp = currOp->getParentOp();
64+
}
65+
66+
return defaultAttr;
67+
}
68+
69+
mlir::acc::VariableTypeCategory mlir::acc::getTypeCategory(mlir::Value var) {
70+
mlir::acc::VariableTypeCategory typeCategory =
71+
mlir::acc::VariableTypeCategory::uncategorized;
72+
if (auto mappableTy = dyn_cast<mlir::acc::MappableType>(var.getType()))
73+
typeCategory = mappableTy.getTypeCategory(var);
74+
else if (auto pointerLikeTy =
75+
dyn_cast<mlir::acc::PointerLikeType>(var.getType()))
76+
typeCategory = pointerLikeTy.getPointeeTypeCategory(
77+
cast<TypedValue<mlir::acc::PointerLikeType>>(var),
78+
pointerLikeTy.getElementType());
79+
return typeCategory;
80+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
add_mlir_unittest(MLIROpenACCTests
22
OpenACCOpsTest.cpp
3+
OpenACCUtilsTest.cpp
34
)
45
mlir_target_link_libraries(MLIROpenACCTests
56
PRIVATE
67
MLIRIR
8+
MLIRFuncDialect
9+
MLIRMemRefDialect
10+
MLIRArithDialect
711
MLIROpenACCDialect
12+
MLIROpenACCUtils
813
)

0 commit comments

Comments
 (0)