MLIR  16.0.0git
SideEffectInterfaces.h
Go to the documentation of this file.
1 //===- SideEffectInterfaces.h - SideEffect in MLIR --------------*- 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 contains traits, interfaces, and utilities for defining and
10 // querying the side effects of an operation.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_INTERFACES_SIDEEFFECTINTERFACES_H
15 #define MLIR_INTERFACES_SIDEEFFECTINTERFACES_H
16 
17 #include "mlir/IR/OpDefinition.h"
18 
19 namespace mlir {
20 namespace SideEffects {
21 //===----------------------------------------------------------------------===//
22 // Effects
23 //===----------------------------------------------------------------------===//
24 
25 /// This class represents a base class for a specific effect type.
26 class Effect {
27 public:
28  /// This base class is used for derived effects that are non-parametric.
29  template <typename DerivedEffect, typename BaseEffect = Effect>
30  class Base : public BaseEffect {
31  public:
33 
34  /// Return the unique identifier for the base effects class.
35  static TypeID getEffectID() { return TypeID::get<DerivedEffect>(); }
36 
37  /// 'classof' used to support llvm style cast functionality.
38  static bool classof(const ::mlir::SideEffects::Effect *effect) {
39  return effect->getEffectID() == BaseT::getEffectID();
40  }
41 
42  /// Returns a unique instance for the derived effect class.
43  static DerivedEffect *get() {
44  return BaseEffect::template get<DerivedEffect>();
45  }
46  using BaseEffect::get;
47 
48  protected:
50  };
51 
52  /// Return the unique identifier for the base effects class.
53  TypeID getEffectID() const { return id; }
54 
55  /// Returns a unique instance for the given effect class.
56  template <typename DerivedEffect>
57  static DerivedEffect *get() {
59  "expected DerivedEffect to inherit from Effect");
60 
61  static DerivedEffect instance;
62  return &instance;
63  }
64 
65 protected:
66  Effect(TypeID id) : id(id) {}
67 
68 private:
69  /// The id of the derived effect class.
70  TypeID id;
71 };
72 
73 //===----------------------------------------------------------------------===//
74 // Resources
75 //===----------------------------------------------------------------------===//
76 
77 /// This class represents a specific resource that an effect applies to. This
78 /// class represents an abstract interface for a given resource.
79 class Resource {
80 public:
81  virtual ~Resource() = default;
82 
83  /// This base class is used for derived effects that are non-parametric.
84  template <typename DerivedResource, typename BaseResource = Resource>
85  class Base : public BaseResource {
86  public:
88 
89  /// Returns a unique instance for the given effect class.
90  static DerivedResource *get() {
91  static DerivedResource instance;
92  return &instance;
93  }
94 
95  /// Return the unique identifier for the base resource class.
96  static TypeID getResourceID() { return TypeID::get<DerivedResource>(); }
97 
98  /// 'classof' used to support llvm style cast functionality.
99  static bool classof(const Resource *resource) {
100  return resource->getResourceID() == BaseT::getResourceID();
101  }
102 
103  protected:
104  Base() : BaseResource(BaseT::getResourceID()){};
105  };
106 
107  /// Return the unique identifier for the base resource class.
108  TypeID getResourceID() const { return id; }
109 
110  /// Return a string name of the resource.
111  virtual StringRef getName() = 0;
112 
113 protected:
114  Resource(TypeID id) : id(id) {}
115 
116 private:
117  /// The id of the derived resource class.
118  TypeID id;
119 };
120 
121 /// A conservative default resource kind.
122 struct DefaultResource : public Resource::Base<DefaultResource> {
123  StringRef getName() final { return "<Default>"; }
124 };
125 
126 /// An automatic allocation-scope resource that is valid in the context of a
127 /// parent AutomaticAllocationScope trait.
129  : public Resource::Base<AutomaticAllocationScopeResource> {
130  StringRef getName() final { return "AutomaticAllocationScope"; }
131 };
132 
133 /// This class represents a specific instance of an effect. It contains the
134 /// effect being applied, a resource that corresponds to where the effect is
135 /// applied, and an optional symbol reference or value(either operand, result,
136 /// or region entry argument) that the effect is applied to, and an optional
137 /// parameters attribute further specifying the details of the effect.
138 template <typename EffectT>
140 public:
141  EffectInstance(EffectT *effect, Resource *resource = DefaultResource::get())
142  : effect(effect), resource(resource) {}
143  EffectInstance(EffectT *effect, Value value,
144  Resource *resource = DefaultResource::get())
145  : effect(effect), resource(resource), value(value) {}
146  EffectInstance(EffectT *effect, SymbolRefAttr symbol,
147  Resource *resource = DefaultResource::get())
148  : effect(effect), resource(resource), value(symbol) {}
149  EffectInstance(EffectT *effect, Attribute parameters,
150  Resource *resource = DefaultResource::get())
151  : effect(effect), resource(resource), parameters(parameters) {}
152  EffectInstance(EffectT *effect, Value value, Attribute parameters,
153  Resource *resource = DefaultResource::get())
154  : effect(effect), resource(resource), value(value),
155  parameters(parameters) {}
156  EffectInstance(EffectT *effect, SymbolRefAttr symbol, Attribute parameters,
157  Resource *resource = DefaultResource::get())
158  : effect(effect), resource(resource), value(symbol),
159  parameters(parameters) {}
160 
161  /// Return the effect being applied.
162  EffectT *getEffect() const { return effect; }
163 
164  /// Return the value the effect is applied on, or nullptr if there isn't a
165  /// known value being affected.
166  Value getValue() const { return value ? value.dyn_cast<Value>() : Value(); }
167 
168  /// Return the symbol reference the effect is applied on, or nullptr if there
169  /// isn't a known smbol being affected.
170  SymbolRefAttr getSymbolRef() const {
171  return value ? value.dyn_cast<SymbolRefAttr>() : SymbolRefAttr();
172  }
173 
174  /// Return the resource that the effect applies to.
175  Resource *getResource() const { return resource; }
176 
177  /// Return the parameters of the effect, if any.
178  Attribute getParameters() const { return parameters; }
179 
180 private:
181  /// The specific effect being applied.
182  EffectT *effect;
183 
184  /// The resource that the given value resides in.
185  Resource *resource;
186 
187  /// The Symbol or Value that the effect applies to. This is optionally null.
189 
190  /// Additional parameters of the effect instance. An attribute is used for
191  /// type-safe structured storage and context-based uniquing. Concrete effects
192  /// can use this at their convenience. This is optionally null.
193  Attribute parameters;
194 };
195 } // namespace SideEffects
196 
197 //===----------------------------------------------------------------------===//
198 // SideEffect Traits
199 //===----------------------------------------------------------------------===//
200 
201 namespace OpTrait {
202 /// This trait indicates that the side effects of an operation includes the
203 /// effects of operations nested within its regions. If the operation has no
204 /// derived effects interfaces, the operation itself can be assumed to have no
205 /// side effects.
206 template <typename ConcreteType>
208  : public TraitBase<ConcreteType, HasRecursiveSideEffects> {};
209 } // namespace OpTrait
210 
211 //===----------------------------------------------------------------------===//
212 // Operation Memory-Effect Modeling
213 //===----------------------------------------------------------------------===//
214 
215 namespace MemoryEffects {
216 /// This class represents the base class used for memory effects.
217 struct Effect : public SideEffects::Effect {
219 
220  /// A base class for memory effects that provides helper utilities.
221  template <typename DerivedEffect>
223 
224  static bool classof(const SideEffects::Effect *effect);
225 };
227 
228 /// The following effect indicates that the operation allocates from some
229 /// resource. An 'allocate' effect implies only allocation of the resource, and
230 /// not any visible mutation or dereference.
231 struct Allocate : public Effect::Base<Allocate> {};
232 
233 /// The following effect indicates that the operation frees some resource that
234 /// has been allocated. An 'allocate' effect implies only de-allocation of the
235 /// resource, and not any visible allocation, mutation or dereference.
236 struct Free : public Effect::Base<Free> {};
237 
238 /// The following effect indicates that the operation reads from some resource.
239 /// A 'read' effect implies only dereferencing of the resource, and not any
240 /// visible mutation.
241 struct Read : public Effect::Base<Read> {};
242 
243 /// The following effect indicates that the operation writes to some resource. A
244 /// 'write' effect implies only mutating a resource, and not any visible
245 /// dereference or read.
246 struct Write : public Effect::Base<Write> {};
247 } // namespace MemoryEffects
248 
249 //===----------------------------------------------------------------------===//
250 // SideEffect Utilities
251 //===----------------------------------------------------------------------===//
252 
253 /// Returns true if `op` has only an effect of type `EffectTy` (and of no other
254 /// type) on `value`. If no value is provided, simply check if effects of that
255 /// type and only of that type are present.
256 template <typename EffectTy>
257 bool hasSingleEffect(Operation *op, Value value = nullptr);
258 
259 /// Return true if the given operation is unused, and has no side effects on
260 /// memory that prevent erasing.
261 bool isOpTriviallyDead(Operation *op);
262 
263 /// Return true if the given operation would be dead if unused, and has no side
264 /// effects on memory that would prevent erasing. This is equivalent to checking
265 /// `isOpTriviallyDead` if `op` was unused.
267 
268 } // namespace mlir
269 
270 //===----------------------------------------------------------------------===//
271 // SideEffect Interfaces
272 //===----------------------------------------------------------------------===//
273 
274 /// Include the definitions of the side effect interfaces.
275 #include "mlir/Interfaces/SideEffectInterfaces.h.inc"
276 
277 #endif // MLIR_INTERFACES_SIDEEFFECTINTERFACES_H
Include the generated interface declarations.
bool wouldOpBeTriviallyDead(Operation *op)
Return true if the given operation would be dead if unused, and has no side effects on memory that wo...
bool isOpTriviallyDead(Operation *op)
Return true if the given operation is unused, and has no side effects on memory that prevent erasing...
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
EffectT * getEffect() const
Return the effect being applied.
EffectInstance(EffectT *effect, SymbolRefAttr symbol, Attribute parameters, Resource *resource=DefaultResource::get())
Value getValue() const
Return the value the effect is applied on, or nullptr if there isn&#39;t a known value being affected...
This trait indicates that the side effects of an operation includes the effects of operations nested ...
static constexpr const bool value
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:104
static DefaultResource * get()
Returns a unique instance for the given effect class.
This class represents a specific resource that an effect applies to.
An automatic allocation-scope resource that is valid in the context of a parent AutomaticAllocationSc...
EffectInstance(EffectT *effect, Value value, Attribute parameters, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, Attribute parameters, Resource *resource=DefaultResource::get())
The following effect indicates that the operation writes to some resource.
static bool classof(const ::mlir::SideEffects::Effect *effect)
&#39;classof&#39; used to support llvm style cast functionality.
SymbolRefAttr getSymbolRef() const
Return the symbol reference the effect is applied on, or nullptr if there isn&#39;t a known smbol being a...
The following effect indicates that the operation reads from some resource.
Attributes are known-constant values of operations.
Definition: Attributes.h:24
U dyn_cast() const
Definition: Value.h:100
bool hasSingleEffect(Operation *op, Value value=nullptr)
Returns true if op has only an effect of type EffectTy (and of no other type) on value.
A conservative default resource kind.
This base class is used for derived effects that are non-parametric.
This class represents a specific instance of an effect.
This class represents the base class used for memory effects.
static bool classof(const Resource *resource)
&#39;classof&#39; used to support llvm style cast functionality.
static TypeID getResourceID()
Return the unique identifier for the base resource class.
TypeID getResourceID() const
Return the unique identifier for the base resource class.
StringRef getName() final
Return a string name of the resource.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
StringRef getName() final
Return a string name of the resource.
Attribute getParameters() const
Return the parameters of the effect, if any.
Resource * getResource() const
Return the resource that the effect applies to.
Helper class for implementing traits.
Definition: OpDefinition.h:316
EffectInstance(EffectT *effect, SymbolRefAttr symbol, Resource *resource=DefaultResource::get())
This class represents a base class for a specific effect type.
The following effect indicates that the operation frees some resource that has been allocated...
EffectInstance(EffectT *effect, Value value, Resource *resource=DefaultResource::get())
TypeID getEffectID() const
Return the unique identifier for the base effects class.
static TypeID getEffectID()
Return the unique identifier for the base effects class.
The following effect indicates that the operation allocates from some resource.
This base class is used for derived effects that are non-parametric.