14#ifndef MLIR_INTERFACES_SIDEEFFECTINTERFACES_H
15#define MLIR_INTERFACES_SIDEEFFECTINTERFACES_H
18#include "llvm/ADT/Twine.h"
30 template <
typename DerivedEffect,
typename BaseEffect = Effect>
31 class Base :
public BaseEffect {
39 static bool classof(const ::mlir::SideEffects::Effect *effect) {
44 static DerivedEffect *
get() {
47 using BaseEffect::get;
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");
62 static DerivedEffect instance;
93 template <
typename DerivedResource,
typename BaseResource = Resource>
94 class Base :
public BaseResource {
101 static DerivedResource *
get() {
102 static DerivedResource instance;
139 for (
const Resource *r =
this; r !=
nullptr; r = r->getParent()) {
140#ifdef EXPENSIVE_CHECKS
141 r->verifyImmediateParentAddressability();
159#ifdef EXPENSIVE_CHECKS
164 void verifyImmediateParentAddressability()
const {
167 llvm::report_fatal_error(
168 llvm::Twine(
"Resource '") +
getName() +
169 "' is addressable but has non-addressable parent '" +
181 StringRef
getName()
const override {
return "<Default>"; }
192 :
public Resource::Base<AutomaticAllocationScopeResource, DefaultResource> {
193 StringRef
getName() const final {
return "AutomaticAllocationScope"; }
202template <
typename EffectT>
206 : effect(effect), resource(resource), stage(0),
207 effectOnFullRegion(
false) {}
210 : effect(effect), resource(resource), stage(stage),
211 effectOnFullRegion(effectOnFullRegion) {}
212 template <
typename T,
214 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
218 : effect(effect), resource(resource), value(value), stage(0),
219 effectOnFullRegion(
false) {
220 checkResourceAllowsValue();
222 template <
typename T,
224 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
228 : effect(effect), resource(resource), value(value), stage(stage),
229 effectOnFullRegion(effectOnFullRegion) {
230 checkResourceAllowsValue();
234 : effect(effect), resource(resource), value(symbol), stage(0),
235 effectOnFullRegion(
false) {}
237 bool effectOnFullRegion,
239 : effect(effect), resource(resource), value(symbol), stage(stage),
240 effectOnFullRegion(effectOnFullRegion) {}
243 : effect(effect), resource(resource), parameters(parameters), stage(0),
244 effectOnFullRegion(
false) {}
246 bool effectOnFullRegion,
248 : effect(effect), resource(resource), parameters(parameters),
249 stage(stage), effectOnFullRegion(effectOnFullRegion) {}
250 template <
typename T,
252 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
256 : effect(effect), resource(resource), value(value),
257 parameters(parameters), stage(0), effectOnFullRegion(
false) {
258 checkResourceAllowsValue();
260 template <
typename T,
262 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
265 bool effectOnFullRegion,
267 : effect(effect), resource(resource), value(value),
268 parameters(parameters), stage(stage),
269 effectOnFullRegion(effectOnFullRegion) {
270 checkResourceAllowsValue();
274 : effect(effect), resource(resource), value(symbol),
275 parameters(parameters), stage(0), effectOnFullRegion(
false) {}
277 int stage,
bool effectOnFullRegion,
279 : effect(effect), resource(resource), value(symbol),
280 parameters(parameters), stage(stage),
281 effectOnFullRegion(effectOnFullRegion) {}
289 if (!value || llvm::isa_and_present<SymbolRefAttr>(value)) {
292 if (
OpOperand *operand = llvm::dyn_cast_if_present<OpOperand *>(value)) {
293 return operand->get();
295 if (
OpResult result = llvm::dyn_cast_if_present<OpResult>(value)) {
298 return cast_if_present<BlockArgument>(value);
303 template <
typename T,
305 llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
308 return value ? dyn_cast_if_present<T>(value) :
nullptr;
314 return value ? llvm::dyn_cast_if_present<SymbolRefAttr>(value)
332 void checkResourceAllowsValue() {
334 llvm::report_fatal_error(
335 llvm::Twine(
"EffectInstance: resource '") + resource->
getName() +
336 "' is non-addressable and cannot have an associated Value");
359 bool effectOnFullRegion;
395template <
typename ConcreteType>
397 :
public TraitBase<ConcreteType, HasRecursiveMemoryEffects> {};
403template <
typename ConcreteType>
405 :
public TraitBase<ConcreteType, RecursivelySpeculatableImplTrait> {
414template <
typename ConcreteType>
416 :
public TraitBase<ConcreteType, AlwaysSpeculatableImplTrait> {
434 template <
typename DerivedEffect>
475template <
typename EffectTy>
481template <
typename EffectTy>
487template <
typename ValueTy,
typename EffectTy>
492template <
typename... EffectTys>
498template <
typename... EffectTys>
504template <
typename ValueTy,
typename... EffectTys>
510template <
typename... EffectTys>
518template <
typename... EffectTys>
526template <
typename ValueTy,
typename... EffectTys>
562std::optional<llvm::SmallVector<MemoryEffects::EffectInstance>>
576bool isPure(Operation *op);
585#include "mlir/Interfaces/SideEffectInterfaces.h.inc"
false
Parses a map_entries map type from a string format back into its numeric value.
Attributes are known-constant values of operations.
This class represents an operand of an operation.
This is a value defined by a result of an operation.
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.
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.
Base< DerivedEffect > BaseT
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.
static TypeID get()
Construct a type info object for the given type T.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
SideEffects::EffectInstance< Effect > EffectInstance
constexpr auto RecursivelySpeculatable
Speculatability
This enum is returned from the getSpeculatability method in the ConditionallySpeculatable op interfac...
@ RecursivelySpeculatable
@ 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)...
Speculation::Speculatability getSpeculatability()
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()=default
DefaultResource(TypeID id)
For use when this type is the parent of another resource; allows the derived resource to pass its Typ...