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