12 #include "llvm/ADT/SmallPtrSet.h"
22 #include "mlir/Interfaces/SideEffectInterfaces.cpp.inc"
29 return isa<Allocate, Free, Read, Write>(effect);
49 while (!effectingOps.empty()) {
53 effectingOps.pop_back();
60 bool hasRecursiveEffects =
62 if (hasRecursiveEffects) {
64 for (
auto &block : region) {
65 effectingOps.push_back(std::make_pair(block.begin(), block.end()));
72 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
76 effectInterface.getEffects(effects);
81 if (isa<MemoryEffects::Allocate>(it.getEffect()) && it.getValue() &&
82 it.getValue().getDefiningOp() == op)
83 allocResults.insert(it.getValue());
85 if (!llvm::all_of(effects, [&allocResults](
89 if (allocResults.contains(it.
getValue()))
92 return isa<MemoryEffects::Read>(it.
getEffect());
100 if (hasRecursiveEffects)
113 template <
typename EffectTy>
115 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
119 memOp.getEffects(effects);
120 bool hasSingleEffectOnVal =
false;
123 for (
auto &effect : effects) {
124 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
125 if (!hasSingleEffectOnVal)
128 return hasSingleEffectOnVal;
130 template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(
Operation *);
131 template bool mlir::hasSingleEffect<MemoryEffects::Free>(
Operation *);
132 template bool mlir::hasSingleEffect<MemoryEffects::Read>(
Operation *);
133 template bool mlir::hasSingleEffect<MemoryEffects::Write>(
Operation *);
135 template <
typename EffectTy>
137 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
141 memOp.getEffects(effects);
142 bool hasSingleEffectOnVal =
false;
145 for (
auto &effect : effects) {
146 if (effect.getValue() != value)
148 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
149 if (!hasSingleEffectOnVal)
152 return hasSingleEffectOnVal;
155 template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(
Operation *,
157 template bool mlir::hasSingleEffect<MemoryEffects::Free>(
Operation *,
159 template bool mlir::hasSingleEffect<MemoryEffects::Read>(
Operation *,
161 template bool mlir::hasSingleEffect<MemoryEffects::Write>(
Operation *,
164 template <
typename ValueTy,
typename EffectTy>
166 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
170 memOp.getEffects(effects);
171 bool hasSingleEffectOnVal =
false;
174 for (
auto &effect : effects) {
175 if (effect.getEffectValue<ValueTy>() != value)
177 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
178 if (!hasSingleEffectOnVal)
181 return hasSingleEffectOnVal;
185 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Allocate>(
Operation *,
188 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Free>(
Operation *,
191 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Read>(
Operation *,
194 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Write>(
Operation *,
198 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Free>(
Operation *,
200 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Read>(
Operation *,
202 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Write>(
Operation *,
205 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Allocate>(
Operation *,
208 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Free>(
Operation *,
211 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Read>(
Operation *,
214 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Write>(
Operation *,
217 template <
typename... EffectTys>
219 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
223 memOp.getEffects(effects);
225 return isa<EffectTys...>(effect.
getEffect());
228 template bool mlir::hasEffect<MemoryEffects::Allocate>(
Operation *);
229 template bool mlir::hasEffect<MemoryEffects::Free>(
Operation *);
230 template bool mlir::hasEffect<MemoryEffects::Read>(
Operation *);
231 template bool mlir::hasEffect<MemoryEffects::Write>(
Operation *);
233 mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(
Operation *);
235 template <
typename... EffectTys>
237 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
241 memOp.getEffects(effects);
245 return isa<EffectTys...>(effect.
getEffect());
248 template bool mlir::hasEffect<MemoryEffects::Allocate>(
Operation *,
254 mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(
Operation *,
257 template <
typename ValueTy,
typename... EffectTys>
259 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
263 memOp.getEffects(effects);
267 return isa<EffectTys...>(effect.
getEffect());
272 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Free>(
Operation *,
274 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Read>(
Operation *,
276 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Write>(
Operation *,
279 mlir::hasEffect<OpOperand *, MemoryEffects::Write, MemoryEffects::Free>(
282 template bool mlir::hasEffect<OpResult, MemoryEffects::Allocate>(
Operation *,
284 template bool mlir::hasEffect<OpResult, MemoryEffects::Free>(
Operation *,
286 template bool mlir::hasEffect<OpResult, MemoryEffects::Read>(
Operation *,
288 template bool mlir::hasEffect<OpResult, MemoryEffects::Write>(
Operation *,
291 mlir::hasEffect<OpResult, MemoryEffects::Write, MemoryEffects::Free>(
295 mlir::hasEffect<BlockArgument, MemoryEffects::Allocate>(
Operation *,
302 mlir::hasEffect<BlockArgument, MemoryEffects::Write>(
Operation *,
305 mlir::hasEffect<BlockArgument, MemoryEffects::Write, MemoryEffects::Free>(
311 if (isa<SymbolOpInterface>(op))
317 if (
auto memInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
318 if (!memInterface.hasNoEffect())
341 std::optional<llvm::SmallVector<MemoryEffects::EffectInstance>>
345 while (!effectingOps.empty()) {
346 Operation *op = effectingOps.pop_back_val();
350 bool hasRecursiveEffects =
352 if (hasRecursiveEffects) {
354 for (
Block &block : region) {
356 effectingOps.push_back(&nestedOp);
362 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
363 effectInterface.getEffects(effects);
364 }
else if (!hasRecursiveEffects) {
374 auto conditionallySpeculatable = dyn_cast<ConditionallySpeculatable>(op);
375 if (!conditionallySpeculatable)
378 switch (conditionallySpeculatable.getSpeculatability()) {
394 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.
OpListType::iterator iterator
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.