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;
116 for (
auto &effect : effects) {
117 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
118 if (!hasSingleEffectOnVal)
121 return hasSingleEffectOnVal;
123 template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(
Operation *);
124 template bool mlir::hasSingleEffect<MemoryEffects::Free>(
Operation *);
125 template bool mlir::hasSingleEffect<MemoryEffects::Read>(
Operation *);
126 template bool mlir::hasSingleEffect<MemoryEffects::Write>(
Operation *);
128 template <
typename EffectTy>
130 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
134 memOp.getEffects(effects);
135 bool hasSingleEffectOnVal =
false;
138 for (
auto &effect : effects) {
139 if (effect.getValue() != value)
141 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
142 if (!hasSingleEffectOnVal)
145 return hasSingleEffectOnVal;
148 template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(
Operation *,
150 template bool mlir::hasSingleEffect<MemoryEffects::Free>(
Operation *,
152 template bool mlir::hasSingleEffect<MemoryEffects::Read>(
Operation *,
154 template bool mlir::hasSingleEffect<MemoryEffects::Write>(
Operation *,
157 template <
typename ValueTy,
typename EffectTy>
159 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
163 memOp.getEffects(effects);
164 bool hasSingleEffectOnVal =
false;
167 for (
auto &effect : effects) {
168 if (effect.getEffectValue<ValueTy>() != value)
170 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
171 if (!hasSingleEffectOnVal)
174 return hasSingleEffectOnVal;
178 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Allocate>(
Operation *,
181 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Free>(
Operation *,
184 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Read>(
Operation *,
187 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Write>(
Operation *,
191 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Free>(
Operation *,
193 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Read>(
Operation *,
195 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Write>(
Operation *,
198 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Allocate>(
Operation *,
201 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Free>(
Operation *,
204 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Read>(
Operation *,
207 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Write>(
Operation *,
210 template <
typename... EffectTys>
212 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
216 memOp.getEffects(effects);
218 return isa<EffectTys...>(effect.
getEffect());
221 template bool mlir::hasEffect<MemoryEffects::Allocate>(
Operation *);
222 template bool mlir::hasEffect<MemoryEffects::Free>(
Operation *);
223 template bool mlir::hasEffect<MemoryEffects::Read>(
Operation *);
224 template bool mlir::hasEffect<MemoryEffects::Write>(
Operation *);
226 mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(
Operation *);
228 template <
typename... EffectTys>
230 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
234 memOp.getEffects(effects);
238 return isa<EffectTys...>(effect.
getEffect());
241 template bool mlir::hasEffect<MemoryEffects::Allocate>(
Operation *,
247 mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(
Operation *,
250 template <
typename ValueTy,
typename... EffectTys>
252 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
256 memOp.getEffects(effects);
260 return isa<EffectTys...>(effect.
getEffect());
265 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Free>(
Operation *,
267 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Read>(
Operation *,
269 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Write>(
Operation *,
272 mlir::hasEffect<OpOperand *, MemoryEffects::Write, MemoryEffects::Free>(
275 template bool mlir::hasEffect<OpResult, MemoryEffects::Allocate>(
Operation *,
277 template bool mlir::hasEffect<OpResult, MemoryEffects::Free>(
Operation *,
279 template bool mlir::hasEffect<OpResult, MemoryEffects::Read>(
Operation *,
281 template bool mlir::hasEffect<OpResult, MemoryEffects::Write>(
Operation *,
284 mlir::hasEffect<OpResult, MemoryEffects::Write, MemoryEffects::Free>(
288 mlir::hasEffect<BlockArgument, MemoryEffects::Allocate>(
Operation *,
295 mlir::hasEffect<BlockArgument, MemoryEffects::Write>(
Operation *,
298 mlir::hasEffect<BlockArgument, MemoryEffects::Write, MemoryEffects::Free>(
304 if (isa<SymbolOpInterface>(op))
310 if (
auto memInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
311 if (!memInterface.hasNoEffect())
334 std::optional<llvm::SmallVector<MemoryEffects::EffectInstance>>
338 while (!effectingOps.empty()) {
339 Operation *op = effectingOps.pop_back_val();
343 bool hasRecursiveEffects =
345 if (hasRecursiveEffects) {
347 for (
Block &block : region) {
349 effectingOps.push_back(&nestedOp);
355 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
356 effectInterface.getEffects(effects);
357 }
else if (!hasRecursiveEffects) {
367 auto conditionallySpeculatable = dyn_cast<ConditionallySpeculatable>(op);
368 if (!conditionallySpeculatable)
371 switch (conditionallySpeculatable.getSpeculatability()) {
387 llvm_unreachable(
"Unhandled enum in mlir::isSpeculatable!");
static bool wouldOpBeTriviallyDeadImpl(Operation *rootOp)
Internal implementation of mlir::wouldOpBeTriviallyDead that also considers terminator operations as ...
This class represents an argument of a Block.
Block represents an ordered list 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...
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.
T getEffectValue() const
Returns the OpOperand effect is applied on, or nullptr if there isn't a known value being effected.
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
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.
static bool classof(const SideEffects::Effect *effect)
Include the definitions of the side effect interfaces.