MLIR 24.0.0git
OpenACCUtils.h
Go to the documentation of this file.
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
13#include "mlir/IR/Diagnostics.h"
14#include "mlir/IR/Remarks.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/ADT/Twine.h"
18#include <optional>
19#include <string>
20
21namespace mlir {
22class DominanceInfo;
24namespace acc {
25
26/// Used to obtain the enclosing compute construct operation that contains
27/// the provided `region`. Returns nullptr if no compute construct operation
28/// is found. The returned operation is one of types defined by
29/// `ACC_COMPUTE_CONSTRUCT_OPS`.
30mlir::Operation *getEnclosingComputeOp(mlir::Region &region);
31
32/// If `v` is not a block argument of an `acc.compute_region` body, returns
33/// nullptr. Otherwise maps the block argument to its operand and returns it.
34mlir::Value getACCOperandForBlockArg(mlir::Value v);
35
36/// If `v` is not a block argument of an `acc.compute_region` body, returns
37/// nullptr. Otherwise maps the block argument to its operand and returns the
38/// defining operation if it is one of `ACC_DATA_ENTRY_OPS`.
39mlir::Operation *getACCDataClauseOpForBlockArg(mlir::Value v);
40
41/// Returns true if this value is only used by `acc.private` operations in the
42/// `region`.
43bool isOnlyUsedByPrivateClauses(mlir::Value val, mlir::Region &region);
44
45/// Returns true if this value is only used by `acc.reduction` operations in
46/// the `region`.
47bool isOnlyUsedByReductionClauses(mlir::Value val, mlir::Region &region);
48
49/// Looks for an OpenACC default attribute on the current operation `op` or in
50/// a parent operation which encloses `op`. This is useful because OpenACC
51/// specification notes that a visible default clause is the nearest default
52/// clause appearing on the compute construct or a lexically containing data
53/// construct.
54std::optional<ClauseDefaultValue> getDefaultAttr(mlir::Operation *op);
55
56/// Get the type category of an OpenACC variable.
57mlir::acc::VariableTypeCategory getTypeCategory(mlir::Value var);
58
59/// Attempts to extract the variable name from a value by walking through
60/// view-like operations until an `acc.var_name` attribute, the name of a data
61/// clause operation, or the symbol a global is addressed through is found.
62/// Returns empty string if no name is found.
63std::string getVariableName(mlir::Value v);
64
65/// Returns a placeholder string for use as an acc.var_name attribute value when
66/// the actual variable name is not yet known at the point of IR construction.
67/// The placeholder is meant to be replaced with the real name at a later
68/// lowering stage.
69/// For example, recipe init regions may attach this to ops at recipe-generation
70/// time, and ACCRecipeMaterialization will subsequently replace the placeholder
71/// with the actual variable name on all marked ops after inlining the recipe
72/// into the compute construct.
73llvm::StringLiteral getVarNamePlaceholder();
74
75/// Get the recipe name for a given recipe kind and type.
76/// Returns an empty string if not possible to generate a recipe name.
77std::string getRecipeName(mlir::acc::RecipeKind kind, mlir::Type type);
78
79// Get the base entity from partial entity access. This is used for getting
80// the base `struct` from an operation that only accesses a field or the
81// base `array` from an operation that only accesses a subarray.
82mlir::Value getBaseEntity(mlir::Value val);
83
84/// Check if a symbol use is valid for use in an OpenACC region.
85/// This includes looking for various attributes such as `acc.routine_info`
86/// and `acc.declare` attributes.
87/// \param user The operation using the symbol
88/// \param symbol The symbol reference being used
89/// \param definingOpPtr Optional output parameter to receive the defining op
90/// \return true if the symbol use is valid, false otherwise
91bool isValidSymbolUse(mlir::Operation *user, mlir::SymbolRefAttr symbol,
92 mlir::Operation **definingOpPtr = nullptr);
93
94/// Check if a value represents device data.
95/// This checks if the value represents device data via the
96/// MappableType, PointerLikeType, and GlobalVariableOpInterface interfaces,
97/// and whether the defining operation carries `acc.declare` with the deviceptr
98/// clause.
99/// \param val The value to check
100/// \return true if the value is device data, false otherwise
101bool isDeviceValue(mlir::Value val);
102
103/// Check if a value use is valid in an OpenACC region.
104/// This is true if:
105/// - The value is produced by an ACC data entry operation
106/// - The value is device data
107/// - The value is only used by private clauses in the region
108/// \param val The value to check
109/// \param region The OpenACC region
110/// \return true if the value use is valid, false otherwise
111bool isValidValueUse(mlir::Value val, mlir::Region &region);
112
113/// Collects all data clauses that dominate the compute construct.
114/// This includes data clauses from:
115/// - The compute construct itself
116/// - Enclosing data constructs
117/// - Applicable declare directives (those that dominate and post-dominate)
118/// This is used to determine if a variable is already covered by an existing
119/// data clause.
120/// \param computeConstructOp The compute construct operation
121/// \param domInfo Dominance information
122/// \param postDomInfo Post-dominance information
123/// \return Vector of data clause values that dominate the compute construct
124llvm::SmallVector<mlir::Value>
125getDominatingDataClauses(mlir::Operation *computeConstructOp,
126 mlir::DominanceInfo &domInfo,
127 mlir::PostDominanceInfo &postDomInfo);
128
129/// Emit an OpenACC remark with lazy message generation.
130///
131/// The messageFn is only invoked if remarks are enabled, allowing callers
132/// to avoid constructing expensive messages when remarks are disabled.
133///
134/// \param op The operation to emit the remark for.
135/// \param messageFn A callable that returns the remark message.
136/// \param category Optional category for the remark. Defaults to "openacc".
137/// \return An in-flight remark object that can be used to append
138/// additional information to the remark.
139remark::detail::InFlightRemark
140emitRemark(mlir::Operation *op, const std::function<std::string()> &messageFn,
141 llvm::StringRef category = "openacc");
142
143/// Emit an OpenACC remark for the given operation with the given message.
144///
145/// \param op The operation to emit the remark for.
146/// \param message The remark message.
147/// \param category Optional category for the remark. Defaults to "openacc".
148/// \return An in-flight remark object that can be used to append
149/// additional information to the remark.
150inline remark::detail::InFlightRemark
151emitRemark(mlir::Operation *op, const llvm::Twine &message,
152 llvm::StringRef category = "openacc") {
153 return emitRemark(
154 op, std::function<std::string()>([msg = message.str()]() { return msg; }),
155 category);
156}
157
158} // namespace acc
159} // namespace mlir
160
161#endif // MLIR_DIALECT_OPENACC_OPENACCUTILS_H_
A class for computing basic dominance information.
Definition Dominance.h:143
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
A class for computing basic postdominance information.
Definition Dominance.h:207
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...
bool isValidSymbolUse(mlir::Operation *user, mlir::SymbolRefAttr symbol, mlir::Operation **definingOpPtr=nullptr)
Check if a symbol use is valid for use in an OpenACC region.
mlir::Value getACCOperandForBlockArg(mlir::Value v)
If v is not a block argument of an acc.compute_region body, returns nullptr.
mlir::Operation * getACCDataClauseOpForBlockArg(mlir::Value v)
If v is not a block argument of an acc.compute_region body, returns nullptr.
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.
bool isValidValueUse(mlir::Value val, mlir::Region &region)
Check if a value use is valid in an OpenACC region.
mlir::Operation * getEnclosingComputeOp(mlir::Region &region)
Used to obtain the enclosing compute construct operation that contains the provided region.
llvm::StringLiteral getVarNamePlaceholder()
Returns a placeholder string for use as an acc.var_name attribute value when the actual variable name...
llvm::SmallVector< mlir::Value > getDominatingDataClauses(mlir::Operation *computeConstructOp, mlir::DominanceInfo &domInfo, mlir::PostDominanceInfo &postDomInfo)
Collects all data clauses that dominate the compute construct.
std::string getRecipeName(mlir::acc::RecipeKind kind, mlir::Type type)
Get the recipe name for a given recipe kind and type.
remark::detail::InFlightRemark emitRemark(mlir::Operation *op, const std::function< std::string()> &messageFn, llvm::StringRef category="openacc")
Emit an OpenACC remark with lazy message generation.
bool isDeviceValue(mlir::Value val)
Check if a value represents device data.
mlir::Value getBaseEntity(mlir::Value val)
bool isOnlyUsedByPrivateClauses(mlir::Value val, mlir::Region &region)
Returns true if this value is only used by acc.private operations in the region.
Include the generated interface declarations.