MLIR 22.0.0git
OpenACCSupport.h
Go to the documentation of this file.
1//===- OpenACCSupport.h - OpenACC Support Interface -------------*- 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// This file defines the OpenACCSupport analysis interface, which provides
10// extensible support for OpenACC passes. Custom implementations
11// can be registered to provide pipeline and dialect-specific information
12// that cannot be adequately expressed through type or operation interfaces
13// alone.
14//
15// Usage Pattern:
16// ==============
17//
18// A pass that needs this functionality should call
19// getAnalysis<OpenACCSupport>(), which will provide either:
20// - A cached version if previously initialized, OR
21// - A default implementation if not previously initialized
22//
23// This analysis is never invalidated (isInvalidated returns false), so it only
24// needs to be initialized once and will persist throughout the pass pipeline.
25//
26// Registering a Custom Implementation:
27// =====================================
28//
29// If a custom implementation is needed, create a pass that runs BEFORE the pass
30// that needs the analysis. In this setup pass, use
31// getAnalysis<OpenACCSupport>() followed by setImplementation() to register
32// your custom implementation. The custom implementation will need to provide
33// implementation for all methods defined in the `OpenACCSupportTraits::Concept`
34// class.
35//
36// Example:
37// void MySetupPass::runOnOperation() {
38// OpenACCSupport &support = getAnalysis<OpenACCSupport>();
39// support.setImplementation(MyCustomImpl());
40// }
41//
42// void MyAnalysisConsumerPass::runOnOperation() {
43// OpenACCSupport &support = getAnalysis<OpenACCSupport>();
44// std::string name = support.getVariableName(someValue);
45// // ... use the analysis results
46// }
47//
48//===----------------------------------------------------------------------===//
49
50#ifndef MLIR_DIALECT_OPENACC_ANALYSIS_OPENACCSUPPORT_H
51#define MLIR_DIALECT_OPENACC_ANALYSIS_OPENACCSUPPORT_H
52
53#include "mlir/IR/Value.h"
55#include <memory>
56#include <string>
57
58namespace mlir {
59namespace acc {
60
61// Forward declarations
62enum class RecipeKind : uint32_t;
63bool isValidSymbolUse(Operation *user, SymbolRefAttr symbol,
64 Operation **definingOpPtr);
65
66namespace detail {
67/// This class contains internal trait classes used by OpenACCSupport.
68/// It follows the Concept-Model pattern used throughout MLIR (e.g., in
69/// AliasAnalysis and interface definitions).
71 class Concept {
72 public:
73 virtual ~Concept() = default;
74
75 /// Get the variable name for a given MLIR value.
76 virtual std::string getVariableName(Value v) = 0;
77
78 /// Get the recipe name for a given kind, type and value.
79 virtual std::string getRecipeName(RecipeKind kind, Type type,
80 Value var) = 0;
81
82 // Used to report a case that is not supported by the implementation.
83 virtual InFlightDiagnostic emitNYI(Location loc, const Twine &message) = 0;
84
85 /// Check if a symbol use is valid for use in an OpenACC region.
86 virtual bool isValidSymbolUse(Operation *user, SymbolRefAttr symbol,
87 Operation **definingOpPtr) = 0;
88 };
89
90 /// SFINAE helpers to detect if implementation has optional methods
91 template <typename ImplT, typename... Args>
93 decltype(std::declval<ImplT>().isValidSymbolUse(std::declval<Args>()...));
94
95 template <typename ImplT>
97 llvm::is_detected<isValidSymbolUse_t, ImplT, Operation *, SymbolRefAttr,
98 Operation **>;
99
100 /// This class wraps a concrete OpenACCSupport implementation and forwards
101 /// interface calls to it. This provides type erasure, allowing different
102 /// implementation types to be used interchangeably without inheritance.
103 /// Methods can be optionally implemented; if not present, default behavior
104 /// is used.
105 template <typename ImplT>
106 class Model final : public Concept {
107 public:
108 explicit Model(ImplT &&impl) : impl(std::forward<ImplT>(impl)) {}
109 ~Model() override = default;
110
111 std::string getVariableName(Value v) final {
112 return impl.getVariableName(v);
113 }
114
115 std::string getRecipeName(RecipeKind kind, Type type, Value var) final {
116 return impl.getRecipeName(kind, type, var);
117 }
118
119 InFlightDiagnostic emitNYI(Location loc, const Twine &message) final {
120 return impl.emitNYI(loc, message);
121 }
122
123 bool isValidSymbolUse(Operation *user, SymbolRefAttr symbol,
124 Operation **definingOpPtr) final {
126 return impl.isValidSymbolUse(user, symbol, definingOpPtr);
127 else
128 return acc::isValidSymbolUse(user, symbol, definingOpPtr);
129 }
130
131 private:
132 ImplT impl;
133 };
134};
135} // namespace detail
136
137//===----------------------------------------------------------------------===//
138// OpenACCSupport
139//===----------------------------------------------------------------------===//
140
143 template <typename ImplT>
145
146public:
147 OpenACCSupport() = default;
149
150 /// Register a custom OpenACCSupport implementation. Only one implementation
151 /// can be registered at a time; calling this replaces any existing
152 /// implementation.
153 template <typename AnalysisT>
154 void setImplementation(AnalysisT &&analysis) {
155 impl =
156 std::make_unique<Model<AnalysisT>>(std::forward<AnalysisT>(analysis));
157 }
158
159 /// Get the variable name for a given value.
160 ///
161 /// \param v The MLIR value to get the variable name for.
162 /// \return The variable name, or an empty string if unavailable.
163 std::string getVariableName(Value v);
164
165 /// Get the recipe name for a given type and value.
166 ///
167 /// \param kind The kind of recipe to get the name for.
168 /// \param type The type to get the recipe name for. Can be null if the
169 /// var is provided instead.
170 /// \param var The MLIR value to get the recipe name for. Can be null if
171 /// the type is provided instead.
172 /// \return The recipe name, or an empty string if not available.
173 std::string getRecipeName(RecipeKind kind, Type type, Value var);
174
175 /// Report a case that is not yet supported by the implementation.
176 ///
177 /// \param loc The location to report the unsupported case at.
178 /// \param message The message to report.
179 /// \return An in-flight diagnostic object that can be used to report the
180 /// unsupported case.
181 InFlightDiagnostic emitNYI(Location loc, const Twine &message);
182
183 /// Check if a symbol use is valid for use in an OpenACC region.
184 ///
185 /// \param user The operation using the symbol.
186 /// \param symbol The symbol reference being used.
187 /// \param definingOpPtr Optional output parameter to receive the defining op.
188 /// \return true if the symbol use is valid, false otherwise.
189 bool isValidSymbolUse(Operation *user, SymbolRefAttr symbol,
190 Operation **definingOpPtr = nullptr);
191
192 /// Signal that this analysis should always be preserved so that
193 /// underlying implementation registration is not lost.
195 return false;
196 }
197
198private:
199 /// The registered custom implementation (if any).
200 std::unique_ptr<Concept> impl;
201};
202
203} // namespace acc
204} // namespace mlir
205
206#endif // MLIR_DIALECT_OPENACC_ANALYSIS_OPENACCSUPPORT_H
detail::PreservedAnalyses PreservedAnalyses
This class represents a diagnostic that is inflight and set to be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
void setImplementation(AnalysisT &&analysis)
Register a custom OpenACCSupport implementation.
InFlightDiagnostic emitNYI(Location loc, const Twine &message)
Report a case that is not yet supported by the implementation.
bool isValidSymbolUse(Operation *user, SymbolRefAttr symbol, Operation **definingOpPtr=nullptr)
Check if a symbol use is valid for use in an OpenACC region.
bool isInvalidated(const AnalysisManager::PreservedAnalyses &pa)
Signal that this analysis should always be preserved so that underlying implementation registration i...
std::string getVariableName(Value v)
Get the variable name for a given value.
std::string getRecipeName(RecipeKind kind, Type type, Value var)
Get the recipe name for a given type and value.
virtual std::string getRecipeName(RecipeKind kind, Type type, Value var)=0
Get the recipe name for a given kind, type and value.
virtual std::string getVariableName(Value v)=0
Get the variable name for a given MLIR value.
virtual InFlightDiagnostic emitNYI(Location loc, const Twine &message)=0
virtual bool isValidSymbolUse(Operation *user, SymbolRefAttr symbol, Operation **definingOpPtr)=0
Check if a symbol use is valid for use in an OpenACC region.
This class wraps a concrete OpenACCSupport implementation and forwards interface calls to it.
InFlightDiagnostic emitNYI(Location loc, const Twine &message) final
std::string getRecipeName(RecipeKind kind, Type type, Value var) final
Get the recipe name for a given kind, type and value.
bool isValidSymbolUse(Operation *user, SymbolRefAttr symbol, Operation **definingOpPtr) final
Check if a symbol use is valid for use in an OpenACC region.
std::string getVariableName(Value v) final
Get the variable name for a given MLIR value.
bool isValidSymbolUse(Operation *user, SymbolRefAttr symbol, Operation **definingOpPtr)
Include the generated interface declarations.
This class contains internal trait classes used by OpenACCSupport.
llvm::is_detected< isValidSymbolUse_t, ImplT, Operation *, SymbolRefAttr, Operation ** > has_isValidSymbolUse
decltype(std::declval< ImplT >().isValidSymbolUse(std::declval< Args >()...)) isValidSymbolUse_t
SFINAE helpers to detect if implementation has optional methods.