12 #include "llvm/ADT/SmallPtrSet.h"
21 #include "mlir/Interfaces/SideEffectInterfaces.cpp.inc"
28 return isa<Allocate, Free, Read, Write>(effect);
46 while (!effectingOps.empty()) {
47 Operation *op = effectingOps.pop_back_val();
51 bool hasRecursiveEffects =
53 if (hasRecursiveEffects) {
55 for (
auto &block : region) {
56 for (
auto &nestedOp : block)
57 effectingOps.push_back(&nestedOp);
64 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
68 effectInterface.getEffects(effects);
73 if (isa<MemoryEffects::Allocate>(it.getEffect()) && it.getValue() &&
74 it.getValue().getDefiningOp() == op)
75 allocResults.insert(it.getValue());
77 if (!llvm::all_of(effects, [&allocResults](
81 if (allocResults.contains(it.
getValue()))
84 return isa<MemoryEffects::Read>(it.
getEffect());
93 if (hasRecursiveEffects)
106 template <
typename EffectTy>
108 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
112 memOp.getEffects(effects);
113 bool hasSingleEffectOnVal =
false;
117 for (
auto &effect : effects) {
118 if (value && effect.getValue() != value)
120 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
121 if (!hasSingleEffectOnVal)
124 return hasSingleEffectOnVal;
127 template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(
Operation *,
133 template <
typename... EffectTys>
135 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
139 memOp.getEffects(effects);
141 if (value && effect.
getValue() != value)
143 return isa<EffectTys...>(effect.
getEffect());
151 mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(
Operation *,
Value);
156 if (isa<SymbolOpInterface>(op))
162 if (
auto memInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
163 if (!memInterface.hasNoEffect())
186 std::optional<llvm::SmallVector<MemoryEffects::EffectInstance>>
190 while (!effectingOps.empty()) {
191 Operation *op = effectingOps.pop_back_val();
195 bool hasRecursiveEffects =
197 if (hasRecursiveEffects) {
199 for (
Block &block : region) {
201 effectingOps.push_back(&nestedOp);
207 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
208 effectInterface.getEffects(effects);
209 }
else if (!hasRecursiveEffects) {
219 auto conditionallySpeculatable = dyn_cast<ConditionallySpeculatable>(op);
220 if (!conditionallySpeculatable)
223 switch (conditionallySpeculatable.getSpeculatability()) {
239 llvm_unreachable(
"Unhandled enum in mlir::isSpeculatable!");
static bool wouldOpBeTriviallyDeadImpl(Operation *rootOp)
Internal implementation of mlir::wouldOpBeTriviallyDead that also considers terminator operations as ...
Block represents an ordered list of Operations.
This trait indicates that the memory effects of an operation includes the effects of operations neste...
This class provides the API for ops that are known to be terminators.
Operation is the basic unit of execution within MLIR.
bool use_empty()
Returns true if this operation has no uses.
bool hasTrait()
Returns true if the operation was registered with a particular trait, e.g.
bool mightHaveTrait()
Returns true if the operation might have the provided trait.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class represents a specific instance of an effect.
EffectT * getEffect() const
Return the effect being applied.
Value getValue() const
Return the value the effect is applied on, or nullptr if there isn't a known value being affected.
This class represents a base class for a specific effect type.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
constexpr auto RecursivelySpeculatable
constexpr auto Speculatable
constexpr auto NotSpeculatable
This header declares functions that assist transformations in the MemRef dialect.
bool hasEffect(Operation *op, Value value=nullptr)
Returns true if op has an effect of type EffectTy on value.
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 hasSingleEffect(Operation *op, Value value=nullptr)
Returns true if op has only an effect of type EffectTy (and of no other type) on value.
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.
static bool classof(const SideEffects::Effect *effect)
Include the definitions of the side effect interfaces.