21 #include "mlir/Interfaces/SideEffectInterfaces.cpp.inc"
28 return isa<Allocate, Free, Read, Write>(effect);
48 while (!effectingOps.empty()) {
52 effectingOps.pop_back();
59 bool hasRecursiveEffects =
61 if (hasRecursiveEffects) {
63 for (
auto &block : region) {
64 effectingOps.push_back(std::make_pair(block.begin(), block.end()));
71 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
75 effectInterface.getEffects(effects);
80 if (isa<MemoryEffects::Allocate>(it.getEffect()) && it.getValue() &&
81 it.getValue().getDefiningOp() == op)
82 allocResults.insert(it.getValue());
84 if (!llvm::all_of(effects, [&allocResults](
88 if (allocResults.contains(it.
getValue()))
91 return isa<MemoryEffects::Read>(it.
getEffect());
99 if (hasRecursiveEffects)
112 template <
typename EffectTy>
114 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
118 memOp.getEffects(effects);
119 bool hasSingleEffectOnVal =
false;
122 for (
auto &effect : effects) {
123 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
124 if (!hasSingleEffectOnVal)
127 return hasSingleEffectOnVal;
129 template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(
Operation *);
130 template bool mlir::hasSingleEffect<MemoryEffects::Free>(
Operation *);
131 template bool mlir::hasSingleEffect<MemoryEffects::Read>(
Operation *);
132 template bool mlir::hasSingleEffect<MemoryEffects::Write>(
Operation *);
134 template <
typename EffectTy>
136 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
140 memOp.getEffects(effects);
141 bool hasSingleEffectOnVal =
false;
144 for (
auto &effect : effects) {
145 if (effect.getValue() != value)
147 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
148 if (!hasSingleEffectOnVal)
151 return hasSingleEffectOnVal;
154 template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(
Operation *,
156 template bool mlir::hasSingleEffect<MemoryEffects::Free>(
Operation *,
158 template bool mlir::hasSingleEffect<MemoryEffects::Read>(
Operation *,
160 template bool mlir::hasSingleEffect<MemoryEffects::Write>(
Operation *,
163 template <
typename ValueTy,
typename EffectTy>
165 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
169 memOp.getEffects(effects);
170 bool hasSingleEffectOnVal =
false;
173 for (
auto &effect : effects) {
174 if (effect.getEffectValue<ValueTy>() != value)
176 hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
177 if (!hasSingleEffectOnVal)
180 return hasSingleEffectOnVal;
184 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Allocate>(
Operation *,
187 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Free>(
Operation *,
190 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Read>(
Operation *,
193 mlir::hasSingleEffect<OpOperand *, MemoryEffects::Write>(
Operation *,
197 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Free>(
Operation *,
199 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Read>(
Operation *,
201 template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Write>(
Operation *,
204 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Allocate>(
Operation *,
207 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Free>(
Operation *,
210 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Read>(
Operation *,
213 mlir::hasSingleEffect<BlockArgument, MemoryEffects::Write>(
Operation *,
216 template <
typename... EffectTys>
218 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
222 memOp.getEffects(effects);
224 return isa<EffectTys...>(effect.
getEffect());
227 template bool mlir::hasEffect<MemoryEffects::Allocate>(
Operation *);
228 template bool mlir::hasEffect<MemoryEffects::Free>(
Operation *);
229 template bool mlir::hasEffect<MemoryEffects::Read>(
Operation *);
230 template bool mlir::hasEffect<MemoryEffects::Write>(
Operation *);
232 mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(
Operation *);
234 template <
typename... EffectTys>
236 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
240 memOp.getEffects(effects);
244 return isa<EffectTys...>(effect.
getEffect());
247 template bool mlir::hasEffect<MemoryEffects::Allocate>(
Operation *,
253 mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(
Operation *,
256 template <
typename ValueTy,
typename... EffectTys>
258 auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
262 memOp.getEffects(effects);
266 return isa<EffectTys...>(effect.
getEffect());
271 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Free>(
Operation *,
273 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Read>(
Operation *,
275 template bool mlir::hasEffect<OpOperand *, MemoryEffects::Write>(
Operation *,
278 mlir::hasEffect<OpOperand *, MemoryEffects::Write, MemoryEffects::Free>(
281 template bool mlir::hasEffect<OpResult, MemoryEffects::Allocate>(
Operation *,
283 template bool mlir::hasEffect<OpResult, MemoryEffects::Free>(
Operation *,
285 template bool mlir::hasEffect<OpResult, MemoryEffects::Read>(
Operation *,
287 template bool mlir::hasEffect<OpResult, MemoryEffects::Write>(
Operation *,
290 mlir::hasEffect<OpResult, MemoryEffects::Write, MemoryEffects::Free>(
294 mlir::hasEffect<BlockArgument, MemoryEffects::Allocate>(
Operation *,
301 mlir::hasEffect<BlockArgument, MemoryEffects::Write>(
Operation *,
304 mlir::hasEffect<BlockArgument, MemoryEffects::Write, MemoryEffects::Free>(
308 return !isa<MemoryEffectOpInterface>(op) &&
315 if (isa<SymbolOpInterface>(op))
321 if (
auto memInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
322 if (!memInterface.hasNoEffect())
345 std::optional<llvm::SmallVector<MemoryEffects::EffectInstance>>
349 while (!effectingOps.empty()) {
350 Operation *op = effectingOps.pop_back_val();
354 bool hasRecursiveEffects =
356 if (hasRecursiveEffects) {
358 for (
Block &block : region) {
360 effectingOps.push_back(&nestedOp);
366 if (
auto effectInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
367 effectInterface.getEffects(effects);
368 }
else if (!hasRecursiveEffects) {
378 auto conditionallySpeculatable = dyn_cast<ConditionallySpeculatable>(op);
379 if (!conditionallySpeculatable)
382 switch (conditionallySpeculatable.getSpeculatability()) {
398 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.
bool hasUnknownEffects(Operation *op)
Return "true" if op has unknown effects.
static bool classof(const SideEffects::Effect *effect)
Include the definitions of the side effect interfaces.