mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-04 20:20:54 +00:00
[mlir] Remove Transforms/SideEffectUtils.h
and move the methods into Interface/SideEffectInterfaces.h
.
The methods in `SideEffectUtils.h` (and their implementations in `SideEffectUtils.cpp`) seem to have similar intent to methods already existing in `SideEffectInterfaces.h`. Move the decleration (and implementation) from `SideEffectUtils.h` (and `SideEffectUtils.cpp`) into `SideEffectInterfaces.h` (and `SideEffectInterface.cpp`). Also drop the `SideEffectInterface::hasNoEffect` method in favor of `mlir::isMemoryEffectFree` which actually recurses into the operation instead of just relying on the `hasRecursiveMemoryEffectTrait` exclusively. Differential Revision: https://reviews.llvm.org/D137857
This commit is contained in:
parent
9332ddfba6
commit
fc367dfa67
@ -94,13 +94,6 @@ class EffectOpInterfaceBase<string name, string baseEffect>
|
||||
return effects.empty();
|
||||
}
|
||||
|
||||
/// Returns true if the given operation has no effects for this interface.
|
||||
static bool hasNoEffect(Operation *op) {
|
||||
if (auto interface = dyn_cast<}] # name # [{>(op))
|
||||
return interface.hasNoEffect();
|
||||
return op->hasTrait<::mlir::OpTrait::HasRecursiveMemoryEffects>();
|
||||
}
|
||||
|
||||
/// Collect all of the effect instances that operate on the provided value
|
||||
/// and place them in 'effects'.
|
||||
void getEffectsOnValue(::mlir::Value value,
|
||||
|
@ -318,6 +318,25 @@ bool isOpTriviallyDead(Operation *op);
|
||||
/// `isOpTriviallyDead` if `op` was unused.
|
||||
bool wouldOpBeTriviallyDead(Operation *op);
|
||||
|
||||
/// Returns true if the given operation is free of memory effects.
|
||||
///
|
||||
/// An operation is free of memory effects if its implementation of
|
||||
/// `MemoryEffectOpInterface` indicates that it has no memory effects. For
|
||||
/// example, it may implement `NoMemoryEffect` in ODS. Alternatively, if the
|
||||
/// operation has the `HasRecursiveMemoryEffects` trait, then it is free of
|
||||
/// memory effects if all of its nested operations are free of memory effects.
|
||||
///
|
||||
/// If the operation has both, then it is free of memory effects if both
|
||||
/// conditions are satisfied.
|
||||
bool isMemoryEffectFree(Operation *op);
|
||||
|
||||
/// Returns true if the given operation is speculatable, i.e. has no undefined
|
||||
/// behavior or other side effects.
|
||||
///
|
||||
/// An operation can indicate that it is speculatable by implementing the
|
||||
/// getSpeculatability hook in the ConditionallySpeculatable op interface.
|
||||
bool isSpeculatable(Operation *op);
|
||||
|
||||
} // namespace mlir
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1,37 +0,0 @@
|
||||
//===- SideEffectUtils.h - Side Effect Utils --------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef MLIR_TRANSFORMS_SIDEFFECTUTILS_H
|
||||
#define MLIR_TRANSFORMS_SIDEFFECTUTILS_H
|
||||
|
||||
namespace mlir {
|
||||
|
||||
class Operation;
|
||||
|
||||
/// Returns true if the given operation is free of memory effects.
|
||||
///
|
||||
/// An operation is free of memory effects if its implementation of
|
||||
/// `MemoryEffectOpInterface` indicates that it has no memory effects. For
|
||||
/// example, it may implement `NoMemoryEffect` in ODS. Alternatively, if the
|
||||
/// operation has the `HasRecursiveMemoryEffects` trait, then it is free of
|
||||
/// memory effects if all of its nested operations are free of memory effects.
|
||||
///
|
||||
/// If the operation has both, then it is free of memory effects if both
|
||||
/// conditions are satisfied.
|
||||
bool isMemoryEffectFree(Operation *op);
|
||||
|
||||
/// Returns true if the given operation is speculatable, i.e. has no undefined
|
||||
/// behavior or other side effects.
|
||||
///
|
||||
/// An operation can indicate that it is speculatable by implementing the
|
||||
/// getSpeculatability hook in the ConditionallySpeculatable op interface.
|
||||
bool isSpeculatable(Operation *op);
|
||||
|
||||
} // end namespace mlir
|
||||
|
||||
#endif // MLIR_TRANSFORMS_SIDEFFECTUTILS_H
|
@ -13,6 +13,7 @@
|
||||
#include "mlir/Analysis/SliceAnalysis.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/IR/Operation.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
@ -293,9 +294,8 @@ Value mlir::matchReduction(ArrayRef<BlockArgument> iterCarriedArgs,
|
||||
// terminator is found. Gather all the combiner ops along the way in
|
||||
// topological order.
|
||||
while (!combinerOp->mightHaveTrait<OpTrait::IsTerminator>()) {
|
||||
if (!MemoryEffectOpInterface::hasNoEffect(combinerOp) ||
|
||||
combinerOp->getNumResults() != 1 || !combinerOp->hasOneUse() ||
|
||||
combinerOp->getParentOp() != redRegionOp)
|
||||
if (!isMemoryEffectFree(combinerOp) || combinerOp->getNumResults() != 1 ||
|
||||
!combinerOp->hasOneUse() || combinerOp->getParentOp() != redRegionOp)
|
||||
return nullptr;
|
||||
|
||||
combinerOps.push_back(combinerOp);
|
||||
|
@ -19,5 +19,6 @@ add_mlir_conversion_library(MLIRSCFToGPU
|
||||
MLIRMemRefDialect
|
||||
MLIRPass
|
||||
MLIRSupport
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRTransforms
|
||||
)
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "mlir/IR/AffineExpr.h"
|
||||
#include "mlir/IR/BlockAndValueMapping.h"
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Pass/Pass.h"
|
||||
#include "mlir/Transforms/DialectConversion.h"
|
||||
#include "mlir/Transforms/Passes.h"
|
||||
@ -656,8 +657,8 @@ ParallelToGpuLaunchLowering::matchAndRewrite(ParallelOp parallelOp,
|
||||
cloningMap.map(op->getResults(), clone->getResults());
|
||||
// Check for side effects.
|
||||
// TODO: Handle region side effects properly.
|
||||
seenSideeffects |= !MemoryEffectOpInterface::hasNoEffect(clone) ||
|
||||
clone->getNumRegions() != 0;
|
||||
seenSideeffects |=
|
||||
!isMemoryEffectFree(clone) || clone->getNumRegions() != 0;
|
||||
// If we are no longer in the innermost scope, sideeffects are disallowed.
|
||||
if (seenSideeffects && leftNestingScope)
|
||||
return failure();
|
||||
|
@ -150,7 +150,7 @@ bool mlir::isLoopMemoryParallel(AffineForOp forOp) {
|
||||
loadAndStoreOps.push_back(op);
|
||||
} else if (!isa<AffineForOp, AffineYieldOp, AffineIfOp>(op) &&
|
||||
!hasSingleEffect<MemoryEffects::Allocate>(op) &&
|
||||
!MemoryEffectOpInterface::hasNoEffect(op)) {
|
||||
!isMemoryEffectFree(op)) {
|
||||
// Alloc-like ops inside `forOp` are fine (they don't impact parallelism)
|
||||
// as long as they don't escape the loop (which has been checked above).
|
||||
return WalkResult::interrupt();
|
||||
|
@ -14,6 +14,7 @@ add_mlir_dialect_library(MLIRAffineAnalysis
|
||||
MLIRCallInterfaces
|
||||
MLIRControlFlowInterfaces
|
||||
MLIRInferTypeOpInterface
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRPresburger
|
||||
MLIRSCFDialect
|
||||
)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
||||
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
||||
#include "mlir/IR/Operation.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Pass/PassManager.h"
|
||||
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
|
||||
#include "mlir/Transforms/Passes.h"
|
||||
@ -490,7 +491,7 @@ LogicalResult bufferization::bufferizeOp(Operation *op,
|
||||
if (opFilter && !opFilter->isOpAllowed(op))
|
||||
continue;
|
||||
// Ops without any uses and no side effects will fold away.
|
||||
if (op->getUses().empty() && MemoryEffectOpInterface::hasNoEffect(op))
|
||||
if (op->getUses().empty() && isMemoryEffectFree(op))
|
||||
continue;
|
||||
// ToTensorOps/ToMemrefOps are allowed in the output.
|
||||
if (isa<ToTensorOp, ToMemrefOp>(op))
|
||||
|
@ -29,6 +29,7 @@ add_mlir_dialect_library(MLIRBufferizationTransforms
|
||||
MLIRMemRefDialect
|
||||
MLIRPass
|
||||
MLIRTensorDialect
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRTransforms
|
||||
MLIRViewLikeInterface
|
||||
)
|
||||
|
@ -78,6 +78,7 @@ add_mlir_dialect_library(MLIRGPUTransforms
|
||||
MLIRMemRefDialect
|
||||
MLIRPass
|
||||
MLIRSCFDialect
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRSupport
|
||||
MLIRTransformUtils
|
||||
)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/IR/PatternMatch.h"
|
||||
#include "mlir/IR/SymbolTable.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Transforms/RegionUtils.h"
|
||||
#include "llvm/ADT/TypeSwitch.h"
|
||||
@ -45,9 +46,7 @@ class GpuAsyncRegionPass
|
||||
static bool isTerminator(Operation *op) {
|
||||
return op->mightHaveTrait<OpTrait::IsTerminator>();
|
||||
}
|
||||
static bool hasSideEffects(Operation *op) {
|
||||
return !MemoryEffectOpInterface::hasNoEffect(op);
|
||||
}
|
||||
static bool hasSideEffects(Operation *op) { return !isMemoryEffectFree(op); }
|
||||
|
||||
// Region walk callback which makes GPU ops implementing the AsyncOpInterface
|
||||
// execute asynchronously.
|
||||
|
@ -1486,7 +1486,7 @@ LogicalResult GenericAtomicRMWOp::verify() {
|
||||
|
||||
bool hasSideEffects =
|
||||
body.walk([&](Operation *nestedOp) {
|
||||
if (MemoryEffectOpInterface::hasNoEffect(nestedOp))
|
||||
if (isMemoryEffectFree(nestedOp))
|
||||
return WalkResult::advance();
|
||||
nestedOp->emitError(
|
||||
"body of 'memref.generic_atomic_rmw' should contain "
|
||||
|
@ -31,6 +31,7 @@ add_mlir_dialect_library(MLIRSCFTransforms
|
||||
MLIRPass
|
||||
MLIRSCFDialect
|
||||
MLIRSCFUtils
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRSupport
|
||||
MLIRTensorDialect
|
||||
MLIRTensorTransforms
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "mlir/IR/BlockAndValueMapping.h"
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/IR/OpDefinition.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
|
||||
namespace mlir {
|
||||
#define GEN_PASS_DEF_SCFPARALLELLOOPFUSION
|
||||
@ -155,8 +156,7 @@ void mlir::scf::naivelyFuseParallelOps(Region ®ion) {
|
||||
continue;
|
||||
}
|
||||
// TODO: Handle region side effects properly.
|
||||
noSideEffects &=
|
||||
MemoryEffectOpInterface::hasNoEffect(&op) && op.getNumRegions() == 0;
|
||||
noSideEffects &= isMemoryEffectFree(&op) && op.getNumRegions() == 0;
|
||||
}
|
||||
for (ArrayRef<ParallelOp> ploops : ploopChains) {
|
||||
for (int i = 0, e = ploops.size(); i + 1 < e; ++i)
|
||||
|
@ -14,6 +14,7 @@ add_mlir_dialect_library(MLIRSCFUtils
|
||||
MLIRFuncDialect
|
||||
MLIRIR
|
||||
MLIRSCFDialect
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRSupport
|
||||
MLIRTransforms
|
||||
)
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "mlir/IR/BlockAndValueMapping.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/IR/PatternMatch.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Support/MathExtras.h"
|
||||
#include "mlir/Transforms/RegionUtils.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
@ -825,7 +826,7 @@ static LogicalResult hoistOpsBetween(scf::ForOp outer, scf::ForOp inner) {
|
||||
}
|
||||
// Skip if op has side effects.
|
||||
// TODO: loads to immutable memory regions are ok.
|
||||
if (!MemoryEffectOpInterface::hasNoEffect(&op)) {
|
||||
if (!isMemoryEffectFree(&op)) {
|
||||
status = failure();
|
||||
continue;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ add_mlir_dialect_library(MLIRVectorTransforms
|
||||
MLIRLinalgDialect
|
||||
MLIRMemRefDialect
|
||||
MLIRSCFDialect
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRTransforms
|
||||
MLIRVectorDialect
|
||||
MLIRVectorInterfaces
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include "mlir/Dialect/Vector/IR/VectorOps.h"
|
||||
#include "mlir/Dialect/Vector/Transforms/VectorDistribution.h"
|
||||
#include "mlir/IR/AffineExpr.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Transforms/RegionUtils.h"
|
||||
#include "mlir/Transforms/SideEffectUtils.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include <utility>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "mlir/Dialect/Vector/Utils/VectorUtils.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/IR/Dominance.h"
|
||||
#include "mlir/Transforms/SideEffectUtils.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
@ -154,3 +154,51 @@ bool mlir::wouldOpBeTriviallyDead(Operation *op) {
|
||||
return false;
|
||||
return wouldOpBeTriviallyDeadImpl(op);
|
||||
}
|
||||
|
||||
bool mlir::isMemoryEffectFree(Operation *op) {
|
||||
if (auto memInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
|
||||
if (!memInterface.hasNoEffect())
|
||||
return false;
|
||||
// If the op does not have recursive side effects, then it is memory effect
|
||||
// free.
|
||||
if (!op->hasTrait<OpTrait::HasRecursiveMemoryEffects>())
|
||||
return true;
|
||||
} else if (!op->hasTrait<OpTrait::HasRecursiveMemoryEffects>()) {
|
||||
// Otherwise, if the op does not implement the memory effect interface and
|
||||
// it does not have recursive side effects, then it cannot be known that the
|
||||
// op is moveable.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recurse into the regions and ensure that all nested ops are memory effect
|
||||
// free.
|
||||
for (Region ®ion : op->getRegions())
|
||||
for (Operation &op : region.getOps())
|
||||
if (!isMemoryEffectFree(&op))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mlir::isSpeculatable(Operation *op) {
|
||||
auto conditionallySpeculatable = dyn_cast<ConditionallySpeculatable>(op);
|
||||
if (!conditionallySpeculatable)
|
||||
return false;
|
||||
|
||||
switch (conditionallySpeculatable.getSpeculatability()) {
|
||||
case Speculation::RecursivelySpeculatable:
|
||||
for (Region ®ion : op->getRegions()) {
|
||||
for (Operation &op : region.getOps())
|
||||
if (!isSpeculatable(&op))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
case Speculation::Speculatable:
|
||||
return true;
|
||||
|
||||
case Speculation::NotSpeculatable:
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm_unreachable("Unhandled enum in mlir::isSpeculatable!");
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ add_mlir_library(MLIRTransforms
|
||||
MLIRCopyOpInterface
|
||||
MLIRLoopLikeInterface
|
||||
MLIRPass
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRSupport
|
||||
MLIRTransformUtils
|
||||
)
|
||||
|
@ -209,7 +209,7 @@ LogicalResult CSE::simplifyOperation(ScopedMapTy &knownValues, Operation *op,
|
||||
|
||||
// Some simple use case of operation with memory side-effect are dealt with
|
||||
// here. Operations with no side-effect are done after.
|
||||
if (!MemoryEffectOpInterface::hasNoEffect(op)) {
|
||||
if (!isMemoryEffectFree(op)) {
|
||||
auto memEffects = dyn_cast<MemoryEffectOpInterface>(op);
|
||||
// TODO: Only basic use case for operations with MemoryEffects::Read can be
|
||||
// eleminated now. More work needs to be done for more complicated patterns
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "mlir/Interfaces/ControlFlowInterfaces.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Transforms/ControlFlowSinkUtils.h"
|
||||
#include "mlir/Transforms/SideEffectUtils.h"
|
||||
|
||||
namespace mlir {
|
||||
#define GEN_PASS_DEF_CONTROLFLOWSINK
|
||||
|
@ -201,7 +201,7 @@ bool CGUseList::isDead(CallGraphNode *node) const {
|
||||
// If the parent operation isn't a symbol, simply check normal SSA deadness.
|
||||
Operation *nodeOp = node->getCallableRegion()->getParentOp();
|
||||
if (!isa<SymbolOpInterface>(nodeOp))
|
||||
return MemoryEffectOpInterface::hasNoEffect(nodeOp) && nodeOp->use_empty();
|
||||
return isMemoryEffectFree(nodeOp) && nodeOp->use_empty();
|
||||
|
||||
// Otherwise, check the number of symbol uses.
|
||||
auto symbolIt = discardableSymNodeUses.find(node);
|
||||
@ -212,7 +212,7 @@ bool CGUseList::hasOneUseAndDiscardable(CallGraphNode *node) const {
|
||||
// If this isn't a symbol node, check for side-effects and SSA use count.
|
||||
Operation *nodeOp = node->getCallableRegion()->getParentOp();
|
||||
if (!isa<SymbolOpInterface>(nodeOp))
|
||||
return MemoryEffectOpInterface::hasNoEffect(nodeOp) && nodeOp->hasOneUse();
|
||||
return isMemoryEffectFree(nodeOp) && nodeOp->hasOneUse();
|
||||
|
||||
// Otherwise, check the number of symbol uses.
|
||||
auto symbolIt = discardableSymNodeUses.find(node);
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include "mlir/Transforms/Passes.h"
|
||||
|
||||
#include "mlir/Interfaces/LoopLikeInterface.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "mlir/Transforms/LoopInvariantCodeMotionUtils.h"
|
||||
#include "mlir/Transforms/SideEffectUtils.h"
|
||||
|
||||
namespace mlir {
|
||||
#define GEN_PASS_DEF_LOOPINVARIANTCODEMOTION
|
||||
|
@ -7,7 +7,6 @@ add_mlir_library(MLIRTransformUtils
|
||||
InliningUtils.cpp
|
||||
LoopInvariantCodeMotionUtils.cpp
|
||||
RegionUtils.cpp
|
||||
SideEffectUtils.cpp
|
||||
TopologicalSortUtils.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
@ -16,5 +15,6 @@ add_mlir_library(MLIRTransformUtils
|
||||
LINK_LIBS PUBLIC
|
||||
MLIRAnalysis
|
||||
MLIRLoopLikeInterface
|
||||
MLIRSideEffectInterfaces
|
||||
MLIRRewrite
|
||||
)
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "mlir/Transforms/LoopInvariantCodeMotionUtils.h"
|
||||
#include "mlir/IR/Operation.h"
|
||||
#include "mlir/Interfaces/LoopLikeInterface.h"
|
||||
#include "mlir/Transforms/SideEffectUtils.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include <queue>
|
||||
|
||||
|
@ -1,60 +0,0 @@
|
||||
//===- SideEffectUtils.cpp - Side Effect Utils ------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "mlir/Transforms/SideEffectUtils.h"
|
||||
#include "mlir/IR/Operation.h"
|
||||
#include "mlir/Interfaces/SideEffectInterfaces.h"
|
||||
|
||||
using namespace mlir;
|
||||
|
||||
bool mlir::isMemoryEffectFree(Operation *op) {
|
||||
if (auto memInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
|
||||
// If the op has side-effects, it cannot be moved.
|
||||
if (!memInterface.hasNoEffect())
|
||||
return false;
|
||||
// If the op does not have recursive side effects, then it can be moved.
|
||||
if (!op->hasTrait<OpTrait::HasRecursiveMemoryEffects>())
|
||||
return true;
|
||||
} else if (!op->hasTrait<OpTrait::HasRecursiveMemoryEffects>()) {
|
||||
// Otherwise, if the op does not implement the memory effect interface and
|
||||
// it does not have recursive side effects, then it cannot be known that the
|
||||
// op is moveable.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Recurse into the regions and ensure that all nested ops can also be moved.
|
||||
for (Region ®ion : op->getRegions())
|
||||
for (Operation &op : region.getOps())
|
||||
if (!isMemoryEffectFree(&op))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mlir::isSpeculatable(Operation *op) {
|
||||
auto conditionallySpeculatable = dyn_cast<ConditionallySpeculatable>(op);
|
||||
if (!conditionallySpeculatable)
|
||||
return false;
|
||||
|
||||
switch (conditionallySpeculatable.getSpeculatability()) {
|
||||
case Speculation::RecursivelySpeculatable:
|
||||
for (Region ®ion : op->getRegions()) {
|
||||
for (Operation &op : region.getOps())
|
||||
if (!isSpeculatable(&op))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
case Speculation::Speculatable:
|
||||
return true;
|
||||
|
||||
case Speculation::NotSpeculatable:
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm_unreachable("Unhandled enum in mlir::isSpeculatable!");
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
// CHECK-SAME: memref<1xindex>, memref<3xindex>, memref<?xindex>, memref<?xindex>, memref<?xf64>
|
||||
// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index
|
||||
// CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index
|
||||
// CHECK-DAG: %[[F0:.*]] = arith.constant 0.{{0*}}e+00 : f64
|
||||
// CHECK: %[[T0:.*]] = memref.alloc() : memref<1xindex>
|
||||
// CHECK: %[[T1:.*]] = memref.alloc() : memref<3xindex>
|
||||
// CHECK: %[[T2:.*]] = memref.alloc() : memref<16xindex>
|
||||
@ -18,7 +17,7 @@
|
||||
// CHECK: linalg.fill ins(%[[C0]] : index) outs(%[[T4]] : memref<16xindex>)
|
||||
// CHECK: %[[T6:.*]] = memref.alloc() : memref<16xf64>
|
||||
// CHECK: %[[T7:.*]] = memref.cast %[[T6]] : memref<16xf64> to memref<?xf64>
|
||||
// CHECK: linalg.fill ins(%[[F0]] : f64) outs(%[[T6]] : memref<16xf64>)
|
||||
// CHECK: linalg.fill ins(%{{.*}} : f64) outs(%[[T6]] : memref<16xf64>)
|
||||
// CHECK: linalg.fill ins(%[[C0]] : index) outs(%[[T1]] : memref<3xindex>)
|
||||
// CHECK: memref.store %[[A]], %[[T0]][%[[C0]]] : memref<1xindex>
|
||||
// CHECK: %[[P0:.*]] = sparse_tensor.push_back %[[T1]], %[[T3]]
|
||||
|
@ -1942,6 +1942,7 @@ cc_library(
|
||||
":SCFDialect",
|
||||
":SCFPassIncGen",
|
||||
":SCFUtils",
|
||||
":SideEffectInterfaces",
|
||||
":Support",
|
||||
":TensorDialect",
|
||||
":TensorTransforms",
|
||||
@ -2553,6 +2554,7 @@ cc_library(
|
||||
":ArithDialect",
|
||||
":FuncDialect",
|
||||
":IR",
|
||||
":SideEffectInterfaces",
|
||||
":Support",
|
||||
":ViewLikeInterface",
|
||||
"//llvm:Support",
|
||||
@ -2855,6 +2857,7 @@ cc_library(
|
||||
":FuncDialect",
|
||||
":IR",
|
||||
":SCFDialect",
|
||||
":SideEffectInterfaces",
|
||||
":Support",
|
||||
":Transforms",
|
||||
"//llvm:Support",
|
||||
@ -3337,6 +3340,7 @@ cc_library(
|
||||
":MemRefDialect",
|
||||
":Pass",
|
||||
":SCFDialect",
|
||||
":SideEffectInterfaces",
|
||||
":Support",
|
||||
":TensorDialect",
|
||||
":Transforms",
|
||||
@ -3841,6 +3845,7 @@ cc_library(
|
||||
":ROCDLToLLVMIRTranslation",
|
||||
":SCFDialect",
|
||||
":FuncDialect",
|
||||
":SideEffectInterfaces",
|
||||
":Support",
|
||||
":Transforms",
|
||||
":ToLLVMIRTranslation",
|
||||
@ -5694,6 +5699,7 @@ cc_library(
|
||||
":LoopLikeInterface",
|
||||
":Pass",
|
||||
":Rewrite",
|
||||
":SideEffectInterfaces",
|
||||
":Support",
|
||||
":TransformUtils",
|
||||
":TransformsPassIncGen",
|
||||
@ -5731,6 +5737,7 @@ cc_library(
|
||||
":MemRefDialect",
|
||||
":Pass",
|
||||
":SCFDialect",
|
||||
":SideEffectInterfaces",
|
||||
":Support",
|
||||
":TransformUtils",
|
||||
":Transforms",
|
||||
@ -10053,6 +10060,7 @@ cc_library(
|
||||
":LoopLikeInterface",
|
||||
":MemRefDialect",
|
||||
":Pass",
|
||||
":SideEffectInterfaces",
|
||||
":TensorDialect",
|
||||
":Transforms",
|
||||
":ViewLikeInterface",
|
||||
|
Loading…
Reference in New Issue
Block a user