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.
131 virtual Resource *getParent() const;
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/// The default resource kind. It serves as the root of the resource hierarchy:
179/// all resources that do not override getParent() have DefaultResource as their
180/// parent.
181struct DefaultResource : public Resource::Base<DefaultResource> {
182 DefaultResource() = default;
183 StringRef getName() const override { return "<Default>"; }
184 Resource *getParent() const override { return nullptr; }
185
186protected:
187 /// For use when this type is the parent of another resource; allows the
188 /// derived resource to pass its TypeID so the hierarchy is correct.
190};
191
192/// All resources that do not override getParent() have DefaultResource
193/// as their parent.
195
196/// An automatic allocation-scope resource that is valid in the context of a
197/// parent AutomaticAllocationScope trait.
199 : public Resource::Base<AutomaticAllocationScopeResource, DefaultResource> {
200 StringRef getName() const final { return "AutomaticAllocationScope"; }
201 Resource *getParent() const override { return DefaultResource::get(); }
202};
203
204/// This class represents a specific instance of an effect. It contains the
205/// effect being applied, a resource that corresponds to where the effect is
206/// applied, and an optional symbol reference or value(either operand, result,
207/// or region entry argument) that the effect is applied to, and an optional
208/// parameters attribute further specifying the details of the effect.
209template <typename EffectT>
211public:
212 EffectInstance(EffectT *effect, Resource *resource = DefaultResource::get())
213 : effect(effect), resource(resource), stage(0),
214 effectOnFullRegion(false) {}
215 EffectInstance(EffectT *effect, int stage, bool effectOnFullRegion,
216 Resource *resource = DefaultResource::get())
217 : effect(effect), resource(resource), stage(stage),
218 effectOnFullRegion(effectOnFullRegion) {}
219 template <typename T,
220 std::enable_if_t<
221 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
222 bool> = true>
223 EffectInstance(EffectT *effect, T value,
224 Resource *resource = DefaultResource::get())
225 : effect(effect), resource(resource), value(value), stage(0),
226 effectOnFullRegion(false) {
227 checkResourceAllowsValue();
228 }
229 template <typename T,
230 std::enable_if_t<
231 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
232 bool> = true>
233 EffectInstance(EffectT *effect, T value, int stage, bool effectOnFullRegion,
234 Resource *resource = DefaultResource::get())
235 : effect(effect), resource(resource), value(value), stage(stage),
236 effectOnFullRegion(effectOnFullRegion) {
237 checkResourceAllowsValue();
238 }
239 EffectInstance(EffectT *effect, SymbolRefAttr symbol,
240 Resource *resource = DefaultResource::get())
241 : effect(effect), resource(resource), value(symbol), stage(0),
242 effectOnFullRegion(false) {}
243 EffectInstance(EffectT *effect, SymbolRefAttr symbol, int stage,
244 bool effectOnFullRegion,
245 Resource *resource = DefaultResource::get())
246 : effect(effect), resource(resource), value(symbol), stage(stage),
247 effectOnFullRegion(effectOnFullRegion) {}
248 EffectInstance(EffectT *effect, Attribute parameters,
249 Resource *resource = DefaultResource::get())
250 : effect(effect), resource(resource), parameters(parameters), stage(0),
251 effectOnFullRegion(false) {}
252 EffectInstance(EffectT *effect, Attribute parameters, int stage,
253 bool effectOnFullRegion,
254 Resource *resource = DefaultResource::get())
255 : effect(effect), resource(resource), parameters(parameters),
256 stage(stage), effectOnFullRegion(effectOnFullRegion) {}
257 template <typename T,
258 std::enable_if_t<
259 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
260 bool> = true>
261 EffectInstance(EffectT *effect, T value, Attribute parameters,
262 Resource *resource = DefaultResource::get())
263 : effect(effect), resource(resource), value(value),
264 parameters(parameters), stage(0), effectOnFullRegion(false) {
265 checkResourceAllowsValue();
266 }
267 template <typename T,
268 std::enable_if_t<
269 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
270 bool> = true>
271 EffectInstance(EffectT *effect, T value, Attribute parameters, int stage,
272 bool effectOnFullRegion,
273 Resource *resource = DefaultResource::get())
274 : effect(effect), resource(resource), value(value),
275 parameters(parameters), stage(stage),
276 effectOnFullRegion(effectOnFullRegion) {
277 checkResourceAllowsValue();
278 }
279 EffectInstance(EffectT *effect, SymbolRefAttr symbol, Attribute parameters,
280 Resource *resource = DefaultResource::get())
281 : effect(effect), resource(resource), value(symbol),
282 parameters(parameters), stage(0), effectOnFullRegion(false) {}
283 EffectInstance(EffectT *effect, SymbolRefAttr symbol, Attribute parameters,
284 int stage, bool effectOnFullRegion,
285 Resource *resource = DefaultResource::get())
286 : effect(effect), resource(resource), value(symbol),
287 parameters(parameters), stage(stage),
288 effectOnFullRegion(effectOnFullRegion) {}
289
290 /// Return the effect being applied.
291 EffectT *getEffect() const { return effect; }
292
293 /// Return the value the effect is applied on, or nullptr if there isn't a
294 /// known value being affected.
295 Value getValue() const {
296 if (!value || llvm::isa_and_present<SymbolRefAttr>(value)) {
297 return Value();
298 }
299 if (OpOperand *operand = llvm::dyn_cast_if_present<OpOperand *>(value)) {
300 return operand->get();
301 }
302 if (OpResult result = llvm::dyn_cast_if_present<OpResult>(value)) {
303 return result;
304 }
305 return cast_if_present<BlockArgument>(value);
306 }
307
308 /// Returns the OpOperand effect is applied on, or nullptr if there isn't a
309 /// known value being effected.
310 template <typename T,
311 std::enable_if_t<
312 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
313 bool> = true>
314 T getEffectValue() const {
315 return value ? dyn_cast_if_present<T>(value) : nullptr;
316 }
317
318 /// Return the symbol reference the effect is applied on, or nullptr if there
319 /// isn't a known smbol being affected.
320 SymbolRefAttr getSymbolRef() const {
321 return value ? llvm::dyn_cast_if_present<SymbolRefAttr>(value)
322 : SymbolRefAttr();
323 }
324
325 /// Return the resource that the effect applies to.
326 Resource *getResource() const { return resource; }
327
328 /// Return the parameters of the effect, if any.
329 Attribute getParameters() const { return parameters; }
330
331 /// Return the effect happen stage.
332 int getStage() const { return stage; }
333
334 /// Return if this side effect act on every single value of resource.
335 bool getEffectOnFullRegion() const { return effectOnFullRegion; }
336
337private:
338 /// Effect on a non-addressable resource cannot have an associated Value.
339 void checkResourceAllowsValue() {
340 if (value && resource && !resource->isAddressable())
341 llvm::report_fatal_error(
342 llvm::Twine("EffectInstance: resource '") + resource->getName() +
343 "' is non-addressable and cannot have an associated Value");
344 }
345
346 /// The specific effect being applied.
347 EffectT *effect;
348
349 /// The resource that the given value resides in.
350 Resource *resource;
351
352 /// The Symbol, OpOperand, OpResult or BlockArgument that the effect applies
353 /// to. This is optionally null.
355
356 /// Additional parameters of the effect instance. An attribute is used for
357 /// type-safe structured storage and context-based uniquing. Concrete effects
358 /// can use this at their convenience. This is optionally null.
359 Attribute parameters;
360
361 // The stage side effect happen. Side effect with a lower stage
362 // number happen earlier than those with a higher stage number
363 int stage;
364
365 // Does this side effect act on every single value of resource.
366 bool effectOnFullRegion;
367};
368} // namespace SideEffects
369
370namespace Speculation {
371/// This enum is returned from the `getSpeculatability` method in the
372/// `ConditionallySpeculatable` op interface.
373enum class Speculatability {
374 /// The Operation in question cannot be speculatively executed. This could be
375 /// because it may invoke undefined behavior or have other side effects.
377
378 // The Operation in question can be speculatively executed. It does not have
379 // any side effects or undefined behavior.
381
382 // The Operation in question can be speculatively executed if all the
383 // operations in all attached regions can also be speculatively executed.
385};
386
391} // namespace Speculation
392
393//===----------------------------------------------------------------------===//
394// SideEffect Traits
395//===----------------------------------------------------------------------===//
396
397namespace OpTrait {
398/// This trait indicates that the memory effects of an operation includes the
399/// effects of operations nested within its regions. If the operation has no
400/// derived effects interfaces, the operation itself can be assumed to have no
401/// memory effects.
402template <typename ConcreteType>
404 : public TraitBase<ConcreteType, HasRecursiveMemoryEffects> {};
405
406/// This trait marks an op (which must be tagged as implementing the
407/// ConditionallySpeculatable interface) as being recursively speculatable.
408/// This means that said op can be speculated only if all the instructions in
409/// all the regions attached to the op can be speculated.
410template <typename ConcreteType>
412 : public TraitBase<ConcreteType, RecursivelySpeculatableImplTrait> {
413
417};
418
419/// This trait marks an op (which must be tagged as implementing the
420/// ConditionallySpeculatable interface) as being always speculatable.
421template <typename ConcreteType>
423 : public TraitBase<ConcreteType, AlwaysSpeculatableImplTrait> {
424
428};
429} // namespace OpTrait
430
431//===----------------------------------------------------------------------===//
432// Operation Memory-Effect Modeling
433//===----------------------------------------------------------------------===//
434
435namespace MemoryEffects {
436/// This class represents the base class used for memory effects.
439
440 /// A base class for memory effects that provides helper utilities.
441 template <typename DerivedEffect>
443
444 static bool classof(const SideEffects::Effect *effect);
445};
447
448/// The following effect indicates that the operation allocates from some
449/// resource. An 'allocate' effect implies only allocation of the resource, and
450/// not any visible mutation or dereference.
451struct Allocate : public Effect::Base<Allocate> {};
452
453/// The following effect indicates that the operation frees some resource that
454/// has been allocated. An 'allocate' effect implies only de-allocation of the
455/// resource, and not any visible allocation, mutation or dereference.
456struct Free : public Effect::Base<Free> {};
457
458/// The following effect indicates that the operation reads from some resource.
459/// A 'read' effect implies only dereferencing of the resource, and not any
460/// visible mutation.
461struct Read : public Effect::Base<Read> {};
462
463/// The following effect indicates that the operation writes to some resource. A
464/// 'write' effect implies only mutating a resource, and not any visible
465/// dereference or read.
466struct Write : public Effect::Base<Write> {};
467} // namespace MemoryEffects
468
469//===----------------------------------------------------------------------===//
470// SideEffect Utilities
471//===----------------------------------------------------------------------===//
472
473/// Return "true" if `op` has unknown effects. I.e., the effects of the
474/// operation itself are unknown and the operation does not derive its effects
475/// from its nested operations. (`HasRecursiveMemoryEffects` trait is not
476/// implemented or it is unknown whether it is implemented or not.)
478
479/// Returns "true" if `op` has only an effect of type `EffectTy`. Returns
480/// "false" if `op` has unknown effects or other/additional effects. Recursive
481/// effects are not taken into account.
482template <typename EffectTy>
483bool hasSingleEffect(Operation *op);
484
485/// Returns "true" if `op` has only an effect of type `EffectTy` on `value`.
486/// Returns "false" if `op` has unknown effects or other/additional effects.
487/// Recursive effects are not taken into account.
488template <typename EffectTy>
489bool hasSingleEffect(Operation *op, Value value);
490
491/// Returns "true" if `op` has only an effect of type `EffectTy` on `value` of
492/// type `ValueTy`. Returns "false" if `op` has unknown effects or
493/// other/additional effects. Recursive effects are not taken into account.
494template <typename ValueTy, typename EffectTy>
495bool hasSingleEffect(Operation *op, ValueTy value);
496
497/// Returns "true" if `op` has an effect of type `EffectTy`. Returns "false" if
498/// `op` has unknown effects. Recursive effects are not taken into account.
499template <typename... EffectTys>
500bool hasEffect(Operation *op);
501
502/// Returns "true" if `op` has an effect of type `EffectTy` on `value`. Returns
503/// "false" if `op` has unknown effects. Recursive effects are not taken into
504/// account.
505template <typename... EffectTys>
506bool hasEffect(Operation *op, Value value);
507
508/// Returns "true" if `op` has an effect of type `EffectTy` on `value` of type
509/// `ValueTy`. Returns "false" if `op` has unknown effects. Recursive effects
510/// are not taken into account.
511template <typename ValueTy, typename... EffectTys>
512bool hasEffect(Operation *op, ValueTy value);
513
514/// Returns "true" if `op` might have an effect of type `EffectTy`. Returns
515/// "true" if the op has unknown effects. Recursive effects are not taken into
516/// account.
517template <typename... EffectTys>
519 return hasUnknownEffects(op) || hasEffect<EffectTys...>(op);
520}
521
522/// Returns "true" if `op` might have an effect of type `EffectTy` on `value`.
523/// Returns "true" if the op has unknown effects. Recursive effects are not
524/// taken into account.
525template <typename... EffectTys>
527 return hasUnknownEffects(op) || hasEffect<EffectTys...>(op, value);
528}
529
530/// Returns "true" if `op` might have an effect of type `EffectTy` on `value`
531/// of type `ValueTy`. Returns "true" if the op has unknown effects. Recursive
532/// effects are not taken into account.
533template <typename ValueTy, typename... EffectTys>
534bool mightHaveEffect(Operation *op, ValueTy value) {
535 return hasUnknownEffects(op) || hasEffect<EffectTys...>(op, value);
536}
537
538/// Return true if the given operation is unused, and has no side effects on
539/// memory that prevent erasing.
540bool isOpTriviallyDead(Operation *op);
541
542/// Return true if the given operation would be dead if unused, and has no side
543/// effects on memory that would prevent erasing. This is equivalent to checking
544/// `isOpTriviallyDead` if `op` was unused.
545///
546/// Note: Terminators and symbols are never considered to be trivially dead.
547bool wouldOpBeTriviallyDead(Operation *op);
548
549/// Returns true if the given operation is free of memory effects.
550///
551/// An operation is free of memory effects if its implementation of
552/// `MemoryEffectOpInterface` indicates that it has no memory effects. For
553/// example, it may implement `NoMemoryEffect` in ODS. Alternatively, if the
554/// operation has the `HasRecursiveMemoryEffects` trait, then it is free of
555/// memory effects if all of its nested operations are free of memory effects.
556///
557/// If the operation has both, then it is free of memory effects if both
558/// conditions are satisfied.
559bool isMemoryEffectFree(Operation *op);
560
561/// Returns the side effects of an operation. If the operation has
562/// RecursiveMemoryEffects, include all side effects of child operations.
563///
564/// std::nullopt indicates that an option did not have a memory effect interface
565/// and so no result could be obtained. An empty vector indicates that there
566/// were no memory effects found (but every operation implemented the memory
567/// effect interface or has RecursiveMemoryEffects). If the vector contains
568/// multiple effects, these effects may be duplicates.
569std::optional<llvm::SmallVector<MemoryEffects::EffectInstance>>
570getEffectsRecursively(Operation *rootOp);
571
572/// Returns true if the given operation is speculatable, i.e. has no undefined
573/// behavior or other side effects.
574///
575/// An operation can indicate that it is speculatable by implementing the
576/// getSpeculatability hook in the ConditionallySpeculatable op interface.
577bool isSpeculatable(Operation *op);
578
579/// Returns true if the given operation is pure, i.e., is speculatable that does
580/// not touch memory.
581///
582/// This function is the C++ equivalent of the `Pure` trait.
583bool isPure(Operation *op);
584
585} // namespace mlir
586
587//===----------------------------------------------------------------------===//
588// SideEffect Interfaces
589//===----------------------------------------------------------------------===//
590
591/// Include the definitions of the side effect interfaces.
592#include "mlir/Interfaces/SideEffectInterfaces.h.inc"
593
594#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 Resource * getParent() const
Return the parent resource in the hierarchy.
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.
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.
StringRef getName() const final
Return a string name of the resource.
StringRef getName() const override
Return a string name of the resource.
Resource * getParent() const override
Return the parent resource in the hierarchy.
DefaultResource(TypeID id)
For use when this type is the parent of another resource; allows the derived resource to pass its Typ...