blob: 12233254f3fb42da37d617276fabaebdb760ed23 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
//===- OpenACCUtils.cpp ---------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "llvm/ADT/TypeSwitch.h"
mlir::Operation *mlir::acc::getEnclosingComputeOp(mlir::Region ®ion) {
mlir::Operation *parentOp = region.getParentOp();
while (parentOp) {
if (mlir::isa<ACC_COMPUTE_CONSTRUCT_OPS>(parentOp))
return parentOp;
parentOp = parentOp->getParentOp();
}
return nullptr;
}
template <typename OpTy>
static bool isOnlyUsedByOpClauses(mlir::Value val, mlir::Region ®ion) {
auto checkIfUsedOnlyByOpInside = [&](mlir::Operation *user) {
// For any users which are not in the current acc region, we can ignore.
// Return true so that it can be used in a `all_of` check.
if (!region.isAncestor(user->getParentRegion()))
return true;
return mlir::isa<OpTy>(user);
};
return llvm::all_of(val.getUsers(), checkIfUsedOnlyByOpInside);
}
bool mlir::acc::isOnlyUsedByPrivateClauses(mlir::Value val,
mlir::Region ®ion) {
return isOnlyUsedByOpClauses<mlir::acc::PrivateOp>(val, region);
}
bool mlir::acc::isOnlyUsedByReductionClauses(mlir::Value val,
mlir::Region ®ion) {
return isOnlyUsedByOpClauses<mlir::acc::ReductionOp>(val, region);
}
std::optional<mlir::acc::ClauseDefaultValue>
mlir::acc::getDefaultAttr(Operation *op) {
std::optional<mlir::acc::ClauseDefaultValue> defaultAttr;
Operation *currOp = op;
// Iterate outwards until a default clause is found (since OpenACC
// specification notes that a visible default clause is the nearest default
// clause appearing on the compute construct or a lexically containing data
// construct.
while (!defaultAttr.has_value() && currOp) {
defaultAttr =
llvm::TypeSwitch<mlir::Operation *,
std::optional<mlir::acc::ClauseDefaultValue>>(currOp)
.Case<ACC_COMPUTE_CONSTRUCT_OPS, mlir::acc::DataOp>(
[&](auto op) { return op.getDefaultAttr(); })
.Default([&](Operation *) { return std::nullopt; });
currOp = currOp->getParentOp();
}
return defaultAttr;
}
mlir::acc::VariableTypeCategory mlir::acc::getTypeCategory(mlir::Value var) {
mlir::acc::VariableTypeCategory typeCategory =
mlir::acc::VariableTypeCategory::uncategorized;
if (auto mappableTy = dyn_cast<mlir::acc::MappableType>(var.getType()))
typeCategory = mappableTy.getTypeCategory(var);
else if (auto pointerLikeTy =
dyn_cast<mlir::acc::PointerLikeType>(var.getType()))
typeCategory = pointerLikeTy.getPointeeTypeCategory(
cast<TypedValue<mlir::acc::PointerLikeType>>(var),
pointerLikeTy.getElementType());
return typeCategory;
}
|