MLIR  22.0.0git
OpenACCUtils.cpp
Go to the documentation of this file.
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 
10 
13 #include "llvm/ADT/TypeSwitch.h"
14 
16  mlir::Operation *parentOp = region.getParentOp();
17  while (parentOp) {
18  if (mlir::isa<ACC_COMPUTE_CONSTRUCT_OPS>(parentOp))
19  return parentOp;
20  parentOp = parentOp->getParentOp();
21  }
22  return nullptr;
23 }
24 
25 template <typename OpTy>
26 static bool isOnlyUsedByOpClauses(mlir::Value val, mlir::Region &region) {
27  auto checkIfUsedOnlyByOpInside = [&](mlir::Operation *user) {
28  // For any users which are not in the current acc region, we can ignore.
29  // Return true so that it can be used in a `all_of` check.
30  if (!region.isAncestor(user->getParentRegion()))
31  return true;
32  return mlir::isa<OpTy>(user);
33  };
34 
35  return llvm::all_of(val.getUsers(), checkIfUsedOnlyByOpInside);
36 }
37 
39  mlir::Region &region) {
40  return isOnlyUsedByOpClauses<mlir::acc::PrivateOp>(val, region);
41 }
42 
44  mlir::Region &region) {
45  return isOnlyUsedByOpClauses<mlir::acc::ReductionOp>(val, region);
46 }
47 
48 std::optional<mlir::acc::ClauseDefaultValue>
50  std::optional<mlir::acc::ClauseDefaultValue> defaultAttr;
51  Operation *currOp = op;
52 
53  // Iterate outwards until a default clause is found (since OpenACC
54  // specification notes that a visible default clause is the nearest default
55  // clause appearing on the compute construct or a lexically containing data
56  // construct.
57  while (!defaultAttr.has_value() && currOp) {
58  defaultAttr =
60  std::optional<mlir::acc::ClauseDefaultValue>>(currOp)
61  .Case<ACC_COMPUTE_CONSTRUCT_OPS, mlir::acc::DataOp>(
62  [&](auto op) { return op.getDefaultAttr(); })
63  .Default([&](Operation *) { return std::nullopt; });
64  currOp = currOp->getParentOp();
65  }
66 
67  return defaultAttr;
68 }
69 
70 mlir::acc::VariableTypeCategory mlir::acc::getTypeCategory(mlir::Value var) {
71  mlir::acc::VariableTypeCategory typeCategory =
72  mlir::acc::VariableTypeCategory::uncategorized;
73  if (auto mappableTy = dyn_cast<mlir::acc::MappableType>(var.getType()))
74  typeCategory = mappableTy.getTypeCategory(var);
75  else if (auto pointerLikeTy =
76  dyn_cast<mlir::acc::PointerLikeType>(var.getType()))
77  typeCategory = pointerLikeTy.getPointeeTypeCategory(
79  pointerLikeTy.getElementType());
80  return typeCategory;
81 }
82 
84  Value current = v;
85 
86  // Walk through view operations until a name is found or can't go further
87  while (Operation *definingOp = current.getDefiningOp()) {
88  // Check for `acc.var_name` attribute
89  if (auto varNameAttr =
90  definingOp->getAttrOfType<VarNameAttr>(getVarNameAttrName()))
91  return varNameAttr.getName().str();
92 
93  // If it is a data entry operation, get name via getVarName
94  if (isa<ACC_DATA_ENTRY_OPS>(definingOp))
95  if (auto name = acc::getVarName(definingOp))
96  return name->str();
97 
98  // If it's a view operation, continue to the source
99  if (auto viewOp = dyn_cast<ViewLikeOpInterface>(definingOp)) {
100  current = viewOp.getViewSource();
101  continue;
102  }
103 
104  break;
105  }
106 
107  return "";
108 }
static bool isOnlyUsedByOpClauses(mlir::Value val, mlir::Region &region)
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Definition: Operation.h:234
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
bool isAncestor(Region *other)
Return true if this region is ancestor of the other region.
Definition: Region.h:222
Operation * getParentOp()
Return the parent operation this region is attached to.
Definition: Region.h:200
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
Type getType() const
Return the type of this value.
Definition: Value.h:105
user_range getUsers() const
Definition: Value.h:218
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Definition: Value.cpp:18
mlir::acc::VariableTypeCategory getTypeCategory(mlir::Value var)
Get the type category of an OpenACC variable.
std::string getVariableName(mlir::Value v)
Attempts to extract the variable name from a value by walking through view-like operations until an a...
std::optional< ClauseDefaultValue > getDefaultAttr(mlir::Operation *op)
Looks for an OpenACC default attribute on the current operation op or in a parent operation which enc...
bool isOnlyUsedByReductionClauses(mlir::Value val, mlir::Region &region)
Returns true if this value is only used by acc.reduction operations in the region.
std::optional< llvm::StringRef > getVarName(mlir::Operation *accOp)
Used to obtain the name from an acc operation.
Definition: OpenACC.cpp:4606
mlir::Operation * getEnclosingComputeOp(mlir::Region &region)
Used to obtain the enclosing compute construct operation that contains the provided region.
static constexpr StringLiteral getVarNameAttrName()
Definition: OpenACC.h:180
bool isOnlyUsedByPrivateClauses(mlir::Value val, mlir::Region &region)
Returns true if this value is only used by acc.private operations in the region.
std::conditional_t< std::is_same_v< Ty, mlir::Type >, mlir::Value, detail::TypedValue< Ty > > TypedValue
If Ty is mlir::Type this will select Value instead of having a wrapper around it.
Definition: Value.h:488