MLIR 23.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
18#include "llvm/ADT/Twine.h"
19
20namespace mlir {
21namespace SideEffects {
22//===----------------------------------------------------------------------===//
23// Effects
24//===----------------------------------------------------------------------===//
25
26/// This class represents a base class for a specific effect type.
27class Effect {
28public:
29 /// This base class is used for derived effects that are non-parametric.
30 template <typename DerivedEffect, typename BaseEffect = Effect>
31 class Base : public BaseEffect {
32 public:
34
35 /// Return the unique identifier for the base effects class.
37
38 /// 'classof' used to support llvm style cast functionality.
39 static bool classof(const ::mlir::SideEffects::Effect *effect) {
40 return effect->getEffectID() == BaseT::getEffectID();
41 }
42
43 /// Returns a unique instance for the derived effect class.
44 static DerivedEffect *get() {
45 return BaseEffect::template get<DerivedEffect>();
46 }
47 using BaseEffect::get;
48
49 protected:
50 Base() : BaseEffect(BaseT::getEffectID()) {}
51 };
52
53 /// Return the unique identifier for the base effects class.
54 TypeID getEffectID() const { return id; }
55
56 /// Returns a unique instance for the given effect class.
57 template <typename DerivedEffect>
58 static DerivedEffect *get() {
59 static_assert(std::is_base_of<Effect, DerivedEffect>::value,
60 "expected DerivedEffect to inherit from Effect");
61
62 static DerivedEffect instance;
63 return &instance;
64 }
65
66protected:
67 Effect(TypeID id) : id(id) {}
68
69private:
70 /// The id of the derived effect class.
71 TypeID id;
72};
73
74//===----------------------------------------------------------------------===//
75// Resources
76//===----------------------------------------------------------------------===//
77
78/// This class represents a specific resource that an effect applies to. This
79/// class represents an abstract interface for a given resource. Resources
80/// form a hierarchy via getParent(); disjointness (isDisjointFrom) is used to
81/// determine whether effects can conflict.
82///
83/// Scope: The resource hierarchy is for disjointness of *abstract* resources
84/// (e.g. addressable memory vs. runtime state). It is deliberately *not*
85/// intended for fine-grained regions with specific addresses/sizes, or for
86/// alias classes / offset-based disambiguation; such concerns are out of scope
87/// and should be handled by alias analysis or other mechanisms.
88class Resource {
89public:
90 virtual ~Resource() = default;
91
92 /// This base class is used for derived effects that are non-parametric.
93 template <typename DerivedResource, typename BaseResource = Resource>
94 class Base : public BaseResource {
95 public:
96 /// Use the current instantiation so get()/getResourceID() refer to this
97 /// hierarchy's singleton, not Base<DerivedResource, Resource>'s.
99
100 /// Returns a unique instance for the given effect class.
101 static DerivedResource *get() {
102 static DerivedResource instance;
103 return &instance;
104 }
105
106 /// Return the unique identifier for the base resource class.
108
109 /// 'classof' used to support llvm style cast functionality. Returns true
110 /// iff the resource is the same as or a descendant of this resource type
111 /// in the hierarchy (so isa/cast work for ancestor checks).
112 static bool classof(const Resource *resource) {
113 return resource->isSubresourceOf(BaseT::get());
114 }
115
116 protected:
117 Base() : BaseResource(BaseT::getResourceID()) {}
118 /// Constructor for use when this type is used as a parent (BaseResource);
119 /// allows the derived resource to pass its TypeID so the hierarchy is
120 /// correct.
121 Base(TypeID id) : BaseResource(id) {}
122 };
123
124 /// Return the unique identifier for the base resource class.
125 TypeID getResourceID() const { return id; }
126
127 /// Return a string name of the resource.
128 virtual StringRef getName() const = 0;
129
130 /// Return the parent resource in the hierarchy, or nullptr for a root.
131 virtual Resource *getParent() const { return nullptr; }
132
133 /// Returns true if this resource is addressable (effects on it can alias
134 /// pointer-based memory). Default is true.
135 virtual bool isAddressable() const { return true; }
136
137 /// Returns true if this resource is a subresource of (or equal to) another.
138 bool isSubresourceOf(const Resource *other) const {
139 for (const Resource *r = this; r != nullptr; r = r->getParent()) {
140#ifdef EXPENSIVE_CHECKS
141 r->verifyImmediateParentAddressability();
142#endif // EXPENSIVE_CHECKS
143 if (r == other)
144 return true;
145 }
146 return false;
147 }
148
149 /// Returns true if this resource is disjoint from another. Two resources are
150 /// disjoint if neither is an ancestor of the other.
151 bool isDisjointFrom(const Resource *other) const {
152 return !isSubresourceOf(other) && !other->isSubresourceOf(this);
153 }
154
155protected:
156 Resource(TypeID id) : id(id) {}
157
158private:
159#ifdef EXPENSIVE_CHECKS
160 /// Verifies the single-link invariant: an addressable resource must not have
161 /// a non-addressable parent. Used from isSubresourceOf() under
162 /// EXPENSIVE_CHECKS so the invariant is checked when the hierarchy is
163 /// traversed.
164 void verifyImmediateParentAddressability() const {
165 Resource *parent = getParent();
166 if (parent && isAddressable() && !parent->isAddressable())
167 llvm::report_fatal_error(
168 llvm::Twine("Resource '") + getName() +
169 "' is addressable but has non-addressable parent '" +
170 parent->getName() + "'");
171 }
172#endif // EXPENSIVE_CHECKS
173
174 /// The id of the derived resource class.
175 TypeID id;
176};
177
178/// A conservative default resource kind.
179struct DefaultResource : public Resource::Base<DefaultResource> {
180 DefaultResource() = default;
181 StringRef getName() const override { return "<Default>"; }
182
183protected:
184 /// For use when this type is the parent of another resource; allows the
185 /// derived resource to pass its TypeID so the hierarchy is correct.
187};
188
189/// An automatic allocation-scope resource that is valid in the context of a
190/// parent AutomaticAllocationScope trait.
192 : public Resource::Base<AutomaticAllocationScopeResource, DefaultResource> {
193 StringRef getName() const final { return "AutomaticAllocationScope"; }
194 Resource *getParent() const override { return DefaultResource::get(); }
195};
196
197/// This class represents a specific instance of an effect. It contains the
198/// effect being applied, a resource that corresponds to where the effect is
199/// applied, and an optional symbol reference or value(either operand, result,
200/// or region entry argument) that the effect is applied to, and an optional
201/// parameters attribute further specifying the details of the effect.
202template <typename EffectT>
204public:
205 EffectInstance(EffectT *effect, Resource *resource = DefaultResource::get())
206 : effect(effect), resource(resource), stage(0),
207 effectOnFullRegion(false) {}
208 EffectInstance(EffectT *effect, int stage, bool effectOnFullRegion,
209 Resource *resource = DefaultResource::get())
210 : effect(effect), resource(resource), stage(stage),
211 effectOnFullRegion(effectOnFullRegion) {}
212 template <typename T,
213 std::enable_if_t<
214 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
215 bool> = true>
216 EffectInstance(EffectT *effect, T value,
217 Resource *resource = DefaultResource::get())
218 : effect(effect), resource(resource), value(value), stage(0),
219 effectOnFullRegion(false) {
220 checkResourceAllowsValue();
221 }
222 template <typename T,
223 std::enable_if_t<
224 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
225 bool> = true>
226 EffectInstance(EffectT *effect, T value, int stage, bool effectOnFullRegion,
227 Resource *resource = DefaultResource::get())
228 : effect(effect), resource(resource), value(value), stage(stage),
229 effectOnFullRegion(effectOnFullRegion) {
230 checkResourceAllowsValue();
231 }
232 EffectInstance(EffectT *effect, SymbolRefAttr symbol,
233 Resource *resource = DefaultResource::get())
234 : effect(effect), resource(resource), value(symbol), stage(0),
235 effectOnFullRegion(false) {}
236 EffectInstance(EffectT *effect, SymbolRefAttr symbol, int stage,
237 bool effectOnFullRegion,
238 Resource *resource = DefaultResource::get())
239 : effect(effect), resource(resource), value(symbol), stage(stage),
240 effectOnFullRegion(effectOnFullRegion) {}
241 EffectInstance(EffectT *effect, Attribute parameters,
242 Resource *resource = DefaultResource::get())
243 : effect(effect), resource(resource), parameters(parameters), stage(0),
244 effectOnFullRegion(false) {}
245 EffectInstance(EffectT *effect, Attribute parameters, int stage,
246 bool effectOnFullRegion,
247 Resource *resource = DefaultResource::get())
248 : effect(effect), resource(resource), parameters(parameters),
249 stage(stage), effectOnFullRegion(effectOnFullRegion) {}
250 template <typename T,
251 std::enable_if_t<
252 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
253 bool> = true>
254 EffectInstance(EffectT *effect, T value, Attribute parameters,
255 Resource *resource = DefaultResource::get())
256 : effect(effect), resource(resource), value(value),
257 parameters(parameters), stage(0), effectOnFullRegion(false) {
258 checkResourceAllowsValue();
259 }
260 template <typename T,
261 std::enable_if_t<
262 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
263 bool> = true>
264 EffectInstance(EffectT *effect, T value, Attribute parameters, int stage,
265 bool effectOnFullRegion,
266 Resource *resource = DefaultResource::get())
267 : effect(effect), resource(resource), value(value),
268 parameters(parameters), stage(stage),
269 effectOnFullRegion(effectOnFullRegion) {
270 checkResourceAllowsValue();
271 }
272 EffectInstance(EffectT *effect, SymbolRefAttr symbol, Attribute parameters,
273 Resource *resource = DefaultResource::get())
274 : effect(effect), resource(resource), value(symbol),
275 parameters(parameters), stage(0), effectOnFullRegion(false) {}
276 EffectInstance(EffectT *effect, SymbolRefAttr symbol, Attribute parameters,
277 int stage, bool effectOnFullRegion,
278 Resource *resource = DefaultResource::get())
279 : effect(effect), resource(resource), value(symbol),
280 parameters(parameters), stage(stage),
281 effectOnFullRegion(effectOnFullRegion) {}
282
283 /// Return the effect being applied.
284 EffectT *getEffect() const { return effect; }
285
286 /// Return the value the effect is applied on, or nullptr if there isn't a
287 /// known value being affected.
288 Value getValue() const {
289 if (!value || llvm::isa_and_present<SymbolRefAttr>(value)) {
290 return Value();
291 }
292 if (OpOperand *operand = llvm::dyn_cast_if_present<OpOperand *>(value)) {
293 return operand->get();
294 }
295 if (OpResult result = llvm::dyn_cast_if_present<OpResult>(value)) {
296 return result;
297 }
298 return cast_if_present<BlockArgument>(value);
299 }
300
301 /// Returns the OpOperand effect is applied on, or nullptr if there isn't a
302 /// known value being effected.
303 template <typename T,
304 std::enable_if_t<
305 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
306 bool> = true>
307 T getEffectValue() const {
308 return value ? dyn_cast_if_present<T>(value) : nullptr;
309 }
310
311 /// Return the symbol reference the effect is applied on, or nullptr if there
312 /// isn't a known smbol being affected.
313 SymbolRefAttr getSymbolRef() const {
314 return value ? llvm::dyn_cast_if_present<SymbolRefAttr>(value)
315 : SymbolRefAttr();
316 }
317
318 /// Return the resource that the effect applies to.
319 Resource *getResource() const { return resource; }
320
321 /// Return the parameters of the effect, if any.
322 Attribute getParameters() const { return parameters; }
323
324 /// Return the effect happen stage.
325 int getStage() const { return stage; }
326
327 /// Return if this side effect act on every single value of resource.
328 bool getEffectOnFullRegion() const { return effectOnFullRegion; }
329
330private:
331 /// Effect on a non-addressable resource cannot have an associated Value.
332 void checkResourceAllowsValue() {
333 if (value && resource && !resource->isAddressable())
334 llvm::report_fatal_error(
335 llvm::Twine("EffectInstance: resource '") + resource->getName() +
336 "' is non-addressable and cannot have an associated Value");
337 }
338
339 /// The specific effect being applied.
340 EffectT *effect;
341
342 /// The resource that the given value resides in.
343 Resource *resource;
344
345 /// The Symbol, OpOperand, OpResult or BlockArgument that the effect applies
346 /// to. This is optionally null.
348
349 /// Additional parameters of the effect instance. An attribute is used for
350 /// type-safe structured storage and context-based uniquing. Concrete effects
351 /// can use this at their convenience. This is optionally null.
352 Attribute parameters;
353
354 // The stage side effect happen. Side effect with a lower stage
355 // number happen earlier than those with a higher stage number
356 int stage;
357
358 // Does this side effect act on every single value of resource.
359 bool effectOnFullRegion;
360};
361} // namespace SideEffects
362
363namespace Speculation {
364/// This enum is returned from the `getSpeculatability` method in the
365/// `ConditionallySpeculatable` op interface.
366enum class Speculatability {
367 /// The Operation in question cannot be speculatively executed. This could be
368 /// because it may invoke undefined behavior or have other side effects.
370
371 // The Operation in question can be speculatively executed. It does not have
372 // any side effects or undefined behavior.
374
375 // The Operation in question can be speculatively executed if all the
376 // operations in all attached regions can also be speculatively executed.
378};
379
384} // namespace Speculation
385
386//===----------------------------------------------------------------------===//
387// SideEffect Traits
388//===----------------------------------------------------------------------===//
389
390namespace OpTrait {
391/// This trait indicates that the memory effects of an operation includes the
392/// effects of operations nested within its regions. If the operation has no
393/// derived effects interfaces, the operation itself can be assumed to have no
394/// memory effects.
395template <typename ConcreteType>
397 : public TraitBase<ConcreteType, HasRecursiveMemoryEffects> {};
398
399/// This trait marks an op (which must be tagged as implementing the
400/// ConditionallySpeculatable interface) as being recursively speculatable.
401/// This means that said op can be speculated only if all the instructions in
402/// all the regions attached to the op can be speculated.
403template <typename ConcreteType>
405 : public TraitBase<ConcreteType, RecursivelySpeculatableImplTrait> {
406
410};
411
412/// This trait marks an op (which must be tagged as implementing the
413/// ConditionallySpeculatable interface) as being always speculatable.
414template <typename ConcreteType>
416 : public TraitBase<ConcreteType, AlwaysSpeculatableImplTrait> {
417
421};
422} // namespace OpTrait
423
424//===----------------------------------------------------------------------===//
425// Operation Memory-Effect Modeling
426//===----------------------------------------------------------------------===//
427
428namespace MemoryEffects {
429/// This class represents the base class used for memory effects.
432
433 /// A base class for memory effects that provides helper utilities.
434 template <typename DerivedEffect>
436
437 static bool classof(const SideEffects::Effect *effect);
438};
440
441/// The following effect indicates that the operation allocates from some
442/// resource. An 'allocate' effect implies only allocation of the resource, and
443/// not any visible mutation or dereference.
444struct Allocate : public Effect::Base<Allocate> {};
445
446/// The following effect indicates that the operation frees some resource that
447/// has been allocated. An 'allocate' effect implies only de-allocation of the
448/// resource, and not any visible allocation, mutation or dereference.
449struct Free : public Effect::Base<Free> {};
450
451/// The following effect indicates that the operation reads from some resource.
452/// A 'read' effect implies only dereferencing of the resource, and not any
453/// visible mutation.
454struct Read : public Effect::Base<Read> {};
455
456/// The following effect indicates that the operation writes to some resource. A
457/// 'write' effect implies only mutating a resource, and not any visible
458/// dereference or read.
459struct Write : public Effect::Base<Write> {};
460} // namespace MemoryEffects
461
462//===----------------------------------------------------------------------===//
463// SideEffect Utilities
464//===----------------------------------------------------------------------===//
465
466/// Return "true" if `op` has unknown effects. I.e., the effects of the
467/// operation itself are unknown and the operation does not derive its effects
468/// from its nested operations. (`HasRecursiveMemoryEffects` trait is not
469/// implemented or it is unknown whether it is implemented or not.)
471
472/// Returns "true" if `op` has only an effect of type `EffectTy`. Returns
473/// "false" if `op` has unknown effects or other/additional effects. Recursive
474/// effects are not taken into account.
475template <typename EffectTy>
476bool hasSingleEffect(Operation *op);
477
478/// Returns "true" if `op` has only an effect of type `EffectTy` on `value`.
479/// Returns "false" if `op` has unknown effects or other/additional effects.
480/// Recursive effects are not taken into account.
481template <typename EffectTy>
482bool hasSingleEffect(Operation *op, Value value);
483
484/// Returns "true" if `op` has only an effect of type `EffectTy` on `value` of
485/// type `ValueTy`. Returns "false" if `op` has unknown effects or
486/// other/additional effects. Recursive effects are not taken into account.
487template <typename ValueTy, typename EffectTy>
488bool hasSingleEffect(Operation *op, ValueTy value);
489
490/// Returns "true" if `op` has an effect of type `EffectTy`. Returns "false" if
491/// `op` has unknown effects. Recursive effects are not taken into account.
492template <typename... EffectTys>
493bool hasEffect(Operation *op);
494
495/// Returns "true" if `op` has an effect of type `EffectTy` on `value`. Returns
496/// "false" if `op` has unknown effects. Recursive effects are not taken into
497/// account.
498template <typename... EffectTys>
499bool hasEffect(Operation *op, Value value);
500
501/// Returns "true" if `op` has an effect of type `EffectTy` on `value` of type
502/// `ValueTy`. Returns "false" if `op` has unknown effects. Recursive effects
503/// are not taken into account.
504template <typename ValueTy, typename... EffectTys>
505bool hasEffect(Operation *op, ValueTy value);
506
507/// Returns "true" if `op` might have an effect of type `EffectTy`. Returns
508/// "true" if the op has unknown effects. Recursive effects are not taken into
509/// account.
510template <typename... EffectTys>
512 return hasUnknownEffects(op) || hasEffect<EffectTys...>(op);
513}
514
515/// Returns "true" if `op` might have an effect of type `EffectTy` on `value`.
516/// Returns "true" if the op has unknown effects. Recursive effects are not
517/// taken into account.
518template <typename... EffectTys>
520 return hasUnknownEffects(op) || hasEffect<EffectTys...>(op, value);
521}
522
523/// Returns "true" if `op` might have an effect of type `EffectTy` on `value`
524/// of type `ValueTy`. Returns "true" if the op has unknown effects. Recursive
525/// effects are not taken into account.
526template <typename ValueTy, typename... EffectTys>
527bool mightHaveEffect(Operation *op, ValueTy value) {
528 return hasUnknownEffects(op) || hasEffect<EffectTys...>(op, value);
529}
530
531/// Return true if the given operation is unused, and has no side effects on
532/// memory that prevent erasing.
533bool isOpTriviallyDead(Operation *op);
534
535/// Return true if the given operation would be dead if unused, and has no side
536/// effects on memory that would prevent erasing. This is equivalent to checking
537/// `isOpTriviallyDead` if `op` was unused.
538///
539/// Note: Terminators and symbols are never considered to be trivially dead.
540bool wouldOpBeTriviallyDead(Operation *op);
541
542/// Returns true if the given operation is free of memory effects.
543///
544/// An operation is free of memory effects if its implementation of
545/// `MemoryEffectOpInterface` indicates that it has no memory effects. For
546/// example, it may implement `NoMemoryEffect` in ODS. Alternatively, if the
547/// operation has the `HasRecursiveMemoryEffects` trait, then it is free of
548/// memory effects if all of its nested operations are free of memory effects.
549///
550/// If the operation has both, then it is free of memory effects if both
551/// conditions are satisfied.
552bool isMemoryEffectFree(Operation *op);
553
554/// Returns the side effects of an operation. If the operation has
555/// RecursiveMemoryEffects, include all side effects of child operations.
556///
557/// std::nullopt indicates that an option did not have a memory effect interface
558/// and so no result could be obtained. An empty vector indicates that there
559/// were no memory effects found (but every operation implemented the memory
560/// effect interface or has RecursiveMemoryEffects). If the vector contains
561/// multiple effects, these effects may be duplicates.
562std::optional<llvm::SmallVector<MemoryEffects::EffectInstance>>
563getEffectsRecursively(Operation *rootOp);
564
565/// Returns true if the given operation is speculatable, i.e. has no undefined
566/// behavior or other side effects.
567///
568/// An operation can indicate that it is speculatable by implementing the
569/// getSpeculatability hook in the ConditionallySpeculatable op interface.
570bool isSpeculatable(Operation *op);
571
572/// Returns true if the given operation is pure, i.e., is speculatable that does
573/// not touch memory.
574///
575/// This function is the C++ equivalent of the `Pure` trait.
576bool isPure(Operation *op);
577
578} // namespace mlir
579
580//===----------------------------------------------------------------------===//
581// SideEffect Interfaces
582//===----------------------------------------------------------------------===//
583
584/// Include the definitions of the side effect interfaces.
585#include "mlir/Interfaces/SideEffectInterfaces.h.inc"
586
587#endif // MLIR_INTERFACES_SIDEEFFECTINTERFACES_H
false
Parses a map_entries map type from a string format back into its numeric value.
Attributes are known-constant values of operations.
Definition Attributes.h:25
This class represents an operand of an operation.
Definition Value.h:254
This is a value defined by a result of an operation.
Definition Value.h:454
This trait indicates that the memory effects of an operation includes the effects of operations neste...
Helper class for implementing traits.
Operation is the basic unit of execution within MLIR.
Definition Operation.h:88
This class represents a specific instance of an effect.
Resource * getResource() const
Return the resource that the effect applies to.
EffectT * getEffect() const
Return the effect being applied.
EffectInstance(EffectT *effect, T value, Attribute parameters, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, T value, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, SymbolRefAttr symbol, Attribute parameters, int stage, bool effectOnFullRegion, Resource *resource=DefaultResource::get())
bool getEffectOnFullRegion() const
Return if this side effect act on every single value of resource.
int getStage() const
Return the effect happen stage.
EffectInstance(EffectT *effect, SymbolRefAttr symbol, Attribute parameters, Resource *resource=DefaultResource::get())
T getEffectValue() const
Returns the OpOperand effect is applied on, or nullptr if there isn't a known value being effected.
EffectInstance(EffectT *effect, SymbolRefAttr symbol, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, T value, int stage, bool effectOnFullRegion, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, Resource *resource=DefaultResource::get())
SymbolRefAttr getSymbolRef() const
Return the symbol reference the effect is applied on, or nullptr if there isn't a known smbol being a...
EffectInstance(EffectT *effect, int stage, bool effectOnFullRegion, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, Attribute parameters, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, T value, Attribute parameters, int stage, bool effectOnFullRegion, Resource *resource=DefaultResource::get())
Attribute getParameters() const
Return the parameters of the effect, if any.
Value getValue() const
Return the value the effect is applied on, or nullptr if there isn't a known value being affected.
EffectInstance(EffectT *effect, Attribute parameters, int stage, bool effectOnFullRegion, Resource *resource=DefaultResource::get())
EffectInstance(EffectT *effect, SymbolRefAttr symbol, int stage, bool effectOnFullRegion, Resource *resource=DefaultResource::get())
This base class is used for derived effects that are non-parametric.
static TypeID getEffectID()
Return the unique identifier for the base effects class.
static DerivedEffect * get()
Returns a unique instance for the derived effect class.
static bool classof(const ::mlir::SideEffects::Effect *effect)
'classof' used to support llvm style cast functionality.
This class represents a base class for a specific effect type.
TypeID getEffectID() const
Return the unique identifier for the base effects class.
static DerivedEffect * get()
Returns a unique instance for the given effect class.
This base class is used for derived effects that are non-parametric.
Base(TypeID id)
Constructor for use when this type is used as a parent (BaseResource); allows the derived resource to...
static DerivedResource * get()
Returns a unique instance for the given effect class.
Base< DerivedResource, BaseResource > BaseT
Use the current instantiation so get()/getResourceID() refer to this hierarchy's singleton,...
static TypeID getResourceID()
Return the unique identifier for the base resource class.
static bool classof(const Resource *resource)
'classof' used to support llvm style cast functionality.
This class represents a specific resource that an effect applies to.
TypeID getResourceID() const
Return the unique identifier for the base resource class.
bool isSubresourceOf(const Resource *other) const
Returns true if this resource is a subresource of (or equal to) another.
virtual bool isAddressable() const
Returns true if this resource is addressable (effects on it can alias pointer-based memory).
virtual StringRef getName() const =0
Return a string name of the resource.
virtual Resource * getParent() const
Return the parent resource in the hierarchy, or nullptr for a root.
bool isDisjointFrom(const Resource *other) const
Returns true if this resource is disjoint from another.
virtual ~Resource()=default
This class provides an efficient unique identifier for a specific C++ type.
Definition TypeID.h:107
static TypeID get()
Construct a type info object for the given type T.
Definition TypeID.h:245
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
SideEffects::EffectInstance< Effect > EffectInstance
constexpr auto RecursivelySpeculatable
Speculatability
This enum is returned from the getSpeculatability method in the ConditionallySpeculatable op interfac...
@ NotSpeculatable
The Operation in question cannot be speculatively executed.
constexpr auto Speculatable
constexpr auto NotSpeculatable
Include the generated interface declarations.
bool hasSingleEffect(Operation *op)
Returns "true" if op has only an effect of type EffectTy.
bool isPure(Operation *op)
Returns true if the given operation is pure, i.e., is speculatable that does not touch memory.
bool isMemoryEffectFree(Operation *op)
Returns true if the given operation is free of memory effects.
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 isSpeculatable(Operation *op)
Returns true if the given operation is speculatable, i.e.
bool isOpTriviallyDead(Operation *op)
Return true if the given operation is unused, and has no side effects on memory that prevent erasing.
std::optional< llvm::SmallVector< MemoryEffects::EffectInstance > > getEffectsRecursively(Operation *rootOp)
Returns the side effects of an operation.
bool hasEffect(Operation *op)
Returns "true" if op has an effect of type EffectTy.
bool hasUnknownEffects(Operation *op)
Return "true" if op has unknown effects.
bool mightHaveEffect(Operation *op)
Returns "true" if op might have an effect of type EffectTy.
The following effect indicates that the operation allocates from some resource.
SideEffects::Effect::Base< DerivedEffect, Effect > Base
A base class for memory effects that provides helper utilities.
static bool classof(const SideEffects::Effect *effect)
Include the definitions of the side effect interfaces.
The following effect indicates that the operation frees some resource that has been allocated.
The following effect indicates that the operation reads from some resource.
The following effect indicates that the operation writes to some resource.
This trait marks an op (which must be tagged as implementing the ConditionallySpeculatable interface)...
Speculation::Speculatability getSpeculatability()
This trait marks an op (which must be tagged as implementing the ConditionallySpeculatable interface)...
An automatic allocation-scope resource that is valid in the context of a parent AutomaticAllocationSc...
Resource * getParent() const override
Return the parent resource in the hierarchy, or nullptr for a root.
StringRef getName() const final
Return a string name of the resource.
StringRef getName() const override
Return a string name of the resource.
DefaultResource(TypeID id)
For use when this type is the parent of another resource; allows the derived resource to pass its Typ...