[mlir][side effect] refactor(*): Include more precise side effects (#94213)
This patch adds more precise side effects to the current ops with memory effects, allowing us to determine which OpOperand/OpResult/BlockArgument the operation reads or writes, rather than just recording the reading and writing of values. This allows for convenient use of precise side effects to achieve analysis and optimization. Related discussions: https://discourse.llvm.org/t/rfc-add-operandindex-to-sideeffect-instance/79243
This commit is contained in:
@@ -1058,9 +1058,9 @@ void fir::BoxRankOp::getEffects(
|
||||
llvm::SmallVectorImpl<
|
||||
mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
mlir::Value inputBox = getBox();
|
||||
if (fir::isBoxAddress(inputBox.getType()))
|
||||
effects.emplace_back(mlir::MemoryEffects::Read::get(), inputBox,
|
||||
mlir::OpOperand &inputBox = getBoxMutable();
|
||||
if (fir::isBoxAddress(inputBox.get().getType()))
|
||||
effects.emplace_back(mlir::MemoryEffects::Read::get(), &inputBox,
|
||||
mlir::SideEffects::DefaultResource::get());
|
||||
}
|
||||
|
||||
@@ -2901,9 +2901,9 @@ void fir::ReboxAssumedRankOp::getEffects(
|
||||
llvm::SmallVectorImpl<
|
||||
mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
mlir::Value inputBox = getBox();
|
||||
if (fir::isBoxAddress(inputBox.getType()))
|
||||
effects.emplace_back(mlir::MemoryEffects::Read::get(), inputBox,
|
||||
mlir::OpOperand &inputBox = getBoxMutable();
|
||||
if (fir::isBoxAddress(inputBox.get().getType()))
|
||||
effects.emplace_back(mlir::MemoryEffects::Read::get(), &inputBox,
|
||||
mlir::SideEffects::DefaultResource::get());
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ getIntrinsicEffects(mlir::Operation *self,
|
||||
"hlfir intrinsic ops only produce 1 result");
|
||||
if (mlir::isa<hlfir::ExprType>(self->getResult(0).getType()))
|
||||
effects.emplace_back(mlir::MemoryEffects::Allocate::get(),
|
||||
self->getResult(0),
|
||||
self->getOpResult(0),
|
||||
mlir::SideEffects::DefaultResource::get());
|
||||
|
||||
// read effect if we read from a pointer or refference type
|
||||
@@ -59,10 +59,10 @@ getIntrinsicEffects(mlir::Operation *self,
|
||||
// } to {
|
||||
// hlfir.yield %0#0 : !fir.box<!fir.array<?x?xf32>>
|
||||
// }
|
||||
for (mlir::Value operand : self->getOperands()) {
|
||||
mlir::Type opTy = operand.getType();
|
||||
for (mlir::OpOperand &operand : self->getOpOperands()) {
|
||||
mlir::Type opTy = operand.get().getType();
|
||||
if (fir::isa_ref_type(opTy) || fir::isa_box_type(opTy))
|
||||
effects.emplace_back(mlir::MemoryEffects::Read::get(), operand,
|
||||
effects.emplace_back(mlir::MemoryEffects::Read::get(), &operand,
|
||||
mlir::SideEffects::DefaultResource::get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,14 +225,14 @@ static void gatherMemoryEffects(
|
||||
|
||||
/// Return the entity yielded by a region, or a null value if the region
|
||||
/// is not terminated by a yield.
|
||||
static mlir::Value getYieldedEntity(mlir::Region ®ion) {
|
||||
static mlir::OpOperand *getYieldedEntity(mlir::Region ®ion) {
|
||||
if (region.empty() || region.back().empty())
|
||||
return nullptr;
|
||||
if (auto yield = mlir::dyn_cast<hlfir::YieldOp>(region.back().back()))
|
||||
return yield.getEntity();
|
||||
return &yield.getEntityMutable();
|
||||
if (auto elementalAddr =
|
||||
mlir::dyn_cast<hlfir::ElementalAddrOp>(region.back().back()))
|
||||
return elementalAddr.getYieldOp().getEntity();
|
||||
return &elementalAddr.getYieldOp().getEntityMutable();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ static void gatherAssignEffects(
|
||||
hlfir::RegionAssignOp regionAssign,
|
||||
bool userDefAssignmentMayOnlyWriteToAssignedVariable,
|
||||
llvm::SmallVectorImpl<mlir::MemoryEffects::EffectInstance> &assignEffects) {
|
||||
mlir::Value assignedVar = getYieldedEntity(regionAssign.getLhsRegion());
|
||||
mlir::OpOperand *assignedVar = getYieldedEntity(regionAssign.getLhsRegion());
|
||||
assert(assignedVar && "lhs cannot be an empty region");
|
||||
assignEffects.emplace_back(mlir::MemoryEffects::Write::get(), assignedVar);
|
||||
|
||||
@@ -389,8 +389,8 @@ void Scheduler::saveEvaluationIfConflict(mlir::Region &yieldRegion,
|
||||
// with a finalizer, or a user defined assignment where the LHS is
|
||||
// intent(inout)).
|
||||
if (yieldIsImplicitRead) {
|
||||
mlir::Value entity = getYieldedEntity(yieldRegion);
|
||||
if (entity && hlfir::isFortranVariableType(entity.getType()))
|
||||
mlir::OpOperand *entity = getYieldedEntity(yieldRegion);
|
||||
if (entity && hlfir::isFortranVariableType(entity->get().getType()))
|
||||
effects.emplace_back(mlir::MemoryEffects::Read::get(), entity);
|
||||
}
|
||||
if (!leafRegionsMayOnlyRead && anyWrite(effects)) {
|
||||
@@ -600,9 +600,9 @@ hlfir::buildEvaluationSchedule(hlfir::OrderedAssignmentTreeOpInterface root,
|
||||
}
|
||||
|
||||
mlir::Value hlfir::SaveEntity::getSavedValue() {
|
||||
mlir::Value saved = getYieldedEntity(*yieldRegion);
|
||||
mlir::OpOperand *saved = getYieldedEntity(*yieldRegion);
|
||||
assert(saved && "SaveEntity must contain region terminated by YieldOp");
|
||||
return saved;
|
||||
return saved->get();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -3,214 +3,186 @@
|
||||
func.func @concat(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: !fir.ref<!fir.char<1, 20>>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%c30 = arith.constant 30 : index
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%0 = hlfir.concat %arg0, %arg1 len %c30 : (!fir.ref<!fir.char<1,10>>, !fir.ref<!fir.char<1,20>>, index) -> (!hlfir.expr<!fir.char<1,30>>)
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @all_no_effects(%arg0: !hlfir.expr<2x!fir.logical<4>>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%all = hlfir.all %arg0 : (!hlfir.expr<2x!fir.logical<4>>) -> !fir.logical<4>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @all_effects(%arg0: !fir.ref<!fir.array<2x10x!fir.logical<4>>>, %arg1: i32) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%all = hlfir.all %arg0 dim %arg1 : (!fir.ref<!fir.array<2x10x!fir.logical<4>>>, i32) -> !hlfir.expr<?x!fir.logical<4>>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @any_no_effects(%arg0: !hlfir.expr<2x!fir.logical<4>>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%all = hlfir.any %arg0 : (!hlfir.expr<2x!fir.logical<4>>) -> !fir.logical<4>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @any_effects(%arg0: !fir.ref<!fir.array<2x10x!fir.logical<4>>>, %arg1: i32) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%all = hlfir.any %arg0 dim %arg1 : (!fir.ref<!fir.array<2x10x!fir.logical<4>>>, i32) -> !hlfir.expr<?x!fir.logical<4>>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @count_no_effects(%arg0: !hlfir.expr<2x!fir.logical<4>>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%all = hlfir.count %arg0 : (!hlfir.expr<2x!fir.logical<4>>) -> i32
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @count_effects(%arg0: !fir.ref<!fir.array<2x10x!fir.logical<4>>>, %arg1: i32) {
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%all = hlfir.count %arg0 dim %arg1 : (!fir.ref<!fir.array<2x10x!fir.logical<4>>>, i32) -> i32
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @product_no_effects(%arg0: !hlfir.expr<?xf32>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%product = hlfir.product %arg0 : (!hlfir.expr<?xf32>) -> f32
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @product_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%product = hlfir.product %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @set_length_read(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: index) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%0 = hlfir.set_length %arg0 len %arg1 : (!fir.ref<!fir.char<1,10>>, index) -> !hlfir.expr<!fir.char<1,?>>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @sum_no_effects(%arg0: !hlfir.expr<?xf32>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%sum = hlfir.sum %arg0 : (!hlfir.expr<?xf32>) -> f32
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @sum_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%sum = hlfir.sum %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @maxval_no_effects(%arg0: !hlfir.expr<?xf32>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%maxval = hlfir.maxval %arg0 : (!hlfir.expr<?xf32>) -> f32
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @maxval_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%maxval = hlfir.maxval %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @minval_no_effects(%arg0: !hlfir.expr<?xf32>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%minval = hlfir.minval %arg0 : (!hlfir.expr<?xf32>) -> f32
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @minval_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%minval = hlfir.minval %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @minloc_effects_simple(%arg0: !hlfir.expr<?xf32>) {
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
%minloc = hlfir.minloc %arg0 : (!hlfir.expr<?xf32>) -> !hlfir.expr<?xi32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @minloc_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%minloc = hlfir.minloc %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xi32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @maxloc_effects_simple(%arg0: !hlfir.expr<?xf32>) {
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
%maxloc = hlfir.maxloc %arg0 : (!hlfir.expr<?xf32>) -> !hlfir.expr<?xi32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @maxloc_effects(%arg0: !fir.ref<!fir.array<2x2xf32>>, %arg1: i32) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%maxloc = hlfir.maxloc %arg0 dim %arg1 : (!fir.ref<!fir.array<2x2xf32>>, i32) -> !hlfir.expr<2xi32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @dot_product_no_effects(%arg0: !hlfir.expr<?xf32>, %arg1: !hlfir.expr<?xf32>) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%0 = hlfir.dot_product %arg0 %arg1 : (!hlfir.expr<?xf32>, !hlfir.expr<?xf32>) -> f32
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @dot_product_effects(%arg0: !fir.ref<!fir.array<10xf32>>, %arg1: !fir.ref<!fir.array<10xf32>>) {
|
||||
// there are read effects on both arguments - the diagnostic verification just doesn't register duplicate identical diagnostics
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%0 = hlfir.dot_product %arg0 %arg1 : (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>) -> f32
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @matmul_no_reads(%arg0: !hlfir.expr<?x?xf32>, %arg1: !hlfir.expr<?x?xf32>) {
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
%0 = hlfir.matmul %arg0 %arg1 : (!hlfir.expr<?x?xf32>, !hlfir.expr<?x?xf32>) -> !hlfir.expr<?x?xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @matmul_reads(%arg0: !fir.ref<!fir.array<10x5xf32>>, %arg1: !fir.ref<!fir.array<5x10xf32>>) {
|
||||
// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// there are read effects on both arguments - the diagnostic verification just doesn't register duplicate identical diagnostics
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%0 = hlfir.matmul %arg0 %arg1 : (!fir.ref<!fir.array<10x5xf32>>, !fir.ref<!fir.array<5x10xf32>>) -> !hlfir.expr<10x10xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @transpose_no_reads(%arg0: !hlfir.expr<?x?xf32>) {
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
%0 = hlfir.transpose %arg0 : (!hlfir.expr<?x?xf32>) -> !hlfir.expr<?x?xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @transpose_read(%arg0: !fir.ref<!fir.array<10x5xf32>>) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%0 = hlfir.transpose %arg0 : (!fir.ref<!fir.array<10x5xf32>>) -> !hlfir.expr<5x10xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @matmul_transpose_no_reads(%arg0: !hlfir.expr<?x?xf32>, %arg1: !hlfir.expr<?x?xf32>) {
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
%0 = hlfir.matmul_transpose %arg0 %arg1 : (!hlfir.expr<?x?xf32>, !hlfir.expr<?x?xf32>) -> !hlfir.expr<?x?xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @matmul_transpose_reads(%arg0: !fir.ref<!fir.array<5x10xf32>>, %arg1: !fir.ref<!fir.array<5x10xf32>>) {
|
||||
// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// there are read effects on both arguments - the diagnostic verification just doesn't register duplicate identical diagnostics
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%0 = hlfir.matmul_transpose %arg0 %arg1 : (!fir.ref<!fir.array<5x10xf32>>, !fir.ref<!fir.array<5x10xf32>>) -> !hlfir.expr<10x10xf32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -219,46 +191,41 @@ func.func @associate(%arg0: i32) {
|
||||
%0:3 = hlfir.associate %arg0 {uniq_name = "x"} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
|
||||
// expected-remark@+1 {{found an instance of 'free' on resource '<Default>'}}
|
||||
hlfir.end_associate %0#1, %0#2 : !fir.ref<i32>, i1
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @as_expr_read(%arg0: !fir.ref<!fir.array<2xi32>>) {
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%0 = hlfir.as_expr %arg0 : (!fir.ref<!fir.array<2xi32>>) -> !hlfir.expr<?xi32>
|
||||
// expected-remark@+1 {{found an instance of 'free' on resource '<Default>'}}
|
||||
hlfir.destroy %0 : !hlfir.expr<?xi32>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @char_extremum(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: !fir.ref<!fir.char<1,20>>) {
|
||||
// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
// there are read effects on both arguments - the diagnostic verification just doesn't register duplicate identical diagnostics
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
%0 = hlfir.char_extremum min, %arg0, %arg1 : (!fir.ref<!fir.char<1, 10>>, !fir.ref<!fir.char<1,20>>) -> !hlfir.expr<!fir.char<1,10>>
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @copy_in(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %is_present: i1) {
|
||||
// expected-remark@+3 {{found an instance of 'allocate' on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'write' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'write' on a op operand, on resource '<Default>'}}
|
||||
%0:2 = hlfir.copy_in %box to %temp : (!fir.box<!fir.array<?xf64>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>) -> (!fir.box<!fir.array<?xf64>>, i1)
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
func.func @copy_out(%box: !fir.box<!fir.array<?xf64>>, %temp: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, %was_copied: i1) {
|
||||
// expected-remark@+2 {{found an instance of 'free' on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
hlfir.copy_out %temp, %was_copied : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1) -> ()
|
||||
// expected-remark@+3 {{found an instance of 'free' on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'write' on a value, on resource '<Default>'}}
|
||||
// expected-remark@+2 {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'write' on a op operand, on resource '<Default>'}}
|
||||
hlfir.copy_out %temp, %was_copied to %box : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, i1, !fir.box<!fir.array<?xf64>>) -> ()
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ void mlir::transform::ChangeCallTargetOp::getEffects(
|
||||
// Indicate that the `call` handle is only read by this operation because the
|
||||
// associated operation is not erased but rather modified in-place, so the
|
||||
// reference to it remains valid.
|
||||
onlyReadsHandle(getCall(), effects);
|
||||
onlyReadsHandle(getCallMutable(), effects);
|
||||
|
||||
// Indicate that the payload is modified by this operation.
|
||||
modifiesPayload(effects);
|
||||
|
||||
@@ -139,7 +139,7 @@ void mlir::transform::ChangeCallTargetOp::getEffects(
|
||||
// Indicate that the `call` handle is only read by this operation because the
|
||||
// associated operation is not erased but rather modified in-place, so the
|
||||
// reference to it remains valid.
|
||||
onlyReadsHandle(getCall(), effects);
|
||||
onlyReadsHandle(getCallMutable(), effects);
|
||||
|
||||
// Indicate that the payload is modified by this operation.
|
||||
modifiesPayload(effects);
|
||||
|
||||
@@ -160,9 +160,8 @@ mlir::transform::HasOperandSatisfyingOp::apply(
|
||||
void mlir::transform::HasOperandSatisfyingOp::getEffects(
|
||||
llvm::SmallVectorImpl<mlir::MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsPayload(effects);
|
||||
onlyReadsHandle(getOp(), effects);
|
||||
producesHandle(getPosition(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
onlyReadsHandle(getOpMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
// Verify well-formedness of the operation and emit diagnostics if it is
|
||||
|
||||
@@ -107,6 +107,9 @@ public:
|
||||
|
||||
/// Returns the source MemRefType for this DMA operation.
|
||||
Value getSrcMemRef() { return getOperand(getSrcMemRefOperandIndex()); }
|
||||
OpOperand &getSrcMemRefMutable() {
|
||||
return getOperation()->getOpOperand(getSrcMemRefOperandIndex());
|
||||
}
|
||||
MemRefType getSrcMemRefType() {
|
||||
return cast<MemRefType>(getSrcMemRef().getType());
|
||||
}
|
||||
@@ -117,7 +120,8 @@ public:
|
||||
/// Returns the affine map used to access the source memref.
|
||||
AffineMap getSrcMap() { return getSrcMapAttr().getValue(); }
|
||||
AffineMapAttr getSrcMapAttr() {
|
||||
return cast<AffineMapAttr>(*(*this)->getInherentAttr(getSrcMapAttrStrName()));
|
||||
return cast<AffineMapAttr>(
|
||||
*(*this)->getInherentAttr(getSrcMapAttrStrName()));
|
||||
}
|
||||
|
||||
/// Returns the source memref affine map indices for this DMA operation.
|
||||
@@ -139,6 +143,9 @@ public:
|
||||
|
||||
/// Returns the destination MemRefType for this DMA operation.
|
||||
Value getDstMemRef() { return getOperand(getDstMemRefOperandIndex()); }
|
||||
OpOperand &getDstMemRefMutable() {
|
||||
return getOperation()->getOpOperand(getDstMemRefOperandIndex());
|
||||
}
|
||||
MemRefType getDstMemRefType() {
|
||||
return cast<MemRefType>(getDstMemRef().getType());
|
||||
}
|
||||
@@ -156,7 +163,8 @@ public:
|
||||
/// Returns the affine map used to access the destination memref.
|
||||
AffineMap getDstMap() { return getDstMapAttr().getValue(); }
|
||||
AffineMapAttr getDstMapAttr() {
|
||||
return cast<AffineMapAttr>(*(*this)->getInherentAttr(getDstMapAttrStrName()));
|
||||
return cast<AffineMapAttr>(
|
||||
*(*this)->getInherentAttr(getDstMapAttrStrName()));
|
||||
}
|
||||
|
||||
/// Returns the destination memref indices for this DMA operation.
|
||||
@@ -173,6 +181,9 @@ public:
|
||||
|
||||
/// Returns the Tag MemRef for this DMA operation.
|
||||
Value getTagMemRef() { return getOperand(getTagMemRefOperandIndex()); }
|
||||
OpOperand &getTagMemRefMutable() {
|
||||
return getOperation()->getOpOperand(getTagMemRefOperandIndex());
|
||||
}
|
||||
MemRefType getTagMemRefType() {
|
||||
return cast<MemRefType>(getTagMemRef().getType());
|
||||
}
|
||||
@@ -185,7 +196,8 @@ public:
|
||||
/// Returns the affine map used to access the tag memref.
|
||||
AffineMap getTagMap() { return getTagMapAttr().getValue(); }
|
||||
AffineMapAttr getTagMapAttr() {
|
||||
return cast<AffineMapAttr>(*(*this)->getInherentAttr(getTagMapAttrStrName()));
|
||||
return cast<AffineMapAttr>(
|
||||
*(*this)->getInherentAttr(getTagMapAttrStrName()));
|
||||
}
|
||||
|
||||
/// Returns the tag memref indices for this DMA operation.
|
||||
@@ -300,6 +312,7 @@ public:
|
||||
|
||||
/// Returns the Tag MemRef associated with the DMA operation being waited on.
|
||||
Value getTagMemRef() { return getOperand(0); }
|
||||
OpOperand &getTagMemRefMutable() { return getOperation()->getOpOperand(0); }
|
||||
MemRefType getTagMemRefType() {
|
||||
return cast<MemRefType>(getTagMemRef().getType());
|
||||
}
|
||||
@@ -307,7 +320,8 @@ public:
|
||||
/// Returns the affine map used to access the tag memref.
|
||||
AffineMap getTagMap() { return getTagMapAttr().getValue(); }
|
||||
AffineMapAttr getTagMapAttr() {
|
||||
return cast<AffineMapAttr>(*(*this)->getInherentAttr(getTagMapAttrStrName()));
|
||||
return cast<AffineMapAttr>(
|
||||
*(*this)->getInherentAttr(getTagMapAttrStrName()));
|
||||
}
|
||||
|
||||
/// Returns the tag memref index for this DMA operation.
|
||||
|
||||
@@ -706,6 +706,7 @@ def MemRef_DmaStartOp : MemRef_Op<"dma_start"> {
|
||||
let extraClassDeclaration = [{
|
||||
// Returns the source MemRefType for this DMA operation.
|
||||
Value getSrcMemRef() { return getOperand(0); }
|
||||
OpOperand &getSrcMemRefMutable() { return getOperation()->getOpOperand(0); }
|
||||
// Returns the rank (number of indices) of the source MemRefType.
|
||||
unsigned getSrcMemRefRank() {
|
||||
return ::llvm::cast<MemRefType>(getSrcMemRef().getType()).getRank();
|
||||
@@ -718,6 +719,7 @@ def MemRef_DmaStartOp : MemRef_Op<"dma_start"> {
|
||||
|
||||
// Returns the destination MemRefType for this DMA operations.
|
||||
Value getDstMemRef() { return getOperand(1 + getSrcMemRefRank()); }
|
||||
OpOperand &getDstMemRefMutable() { return getOperation()->getOpOperand(1 + getSrcMemRefRank()); }
|
||||
// Returns the rank (number of indices) of the destination MemRefType.
|
||||
unsigned getDstMemRefRank() {
|
||||
return ::llvm::cast<MemRefType>(getDstMemRef().getType()).getRank();
|
||||
@@ -745,6 +747,9 @@ def MemRef_DmaStartOp : MemRef_Op<"dma_start"> {
|
||||
Value getTagMemRef() {
|
||||
return getOperand(1 + getSrcMemRefRank() + 1 + getDstMemRefRank() + 1);
|
||||
}
|
||||
OpOperand &getTagMemRefMutable() {
|
||||
return getOperation()->getOpOperand(1 + getSrcMemRefRank() + 1 + getDstMemRefRank() + 1);
|
||||
}
|
||||
|
||||
// Returns the rank (number of indices) of the tag MemRefType.
|
||||
unsigned getTagMemRefRank() {
|
||||
@@ -801,11 +806,11 @@ def MemRef_DmaStartOp : MemRef_Op<"dma_start"> {
|
||||
void getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>> &
|
||||
effects) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getSrcMemRef(),
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getSrcMemRefMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
effects.emplace_back(MemoryEffects::Write::get(), getDstMemRef(),
|
||||
effects.emplace_back(MemoryEffects::Write::get(), &getDstMemRefMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getTagMemRef(),
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getTagMemRefMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
}];
|
||||
@@ -852,7 +857,7 @@ def MemRef_DmaWaitOp : MemRef_Op<"dma_wait"> {
|
||||
void getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>> &
|
||||
effects) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getTagMemRef(),
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getTagMemRefMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
}];
|
||||
|
||||
@@ -102,8 +102,8 @@ public:
|
||||
}
|
||||
|
||||
void getEffects(SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(this->getOperation()->getOperands(), effects);
|
||||
producesHandle(this->getOperation()->getResults(), effects);
|
||||
onlyReadsHandle(this->getOperation()->getOpOperands(), effects);
|
||||
producesHandle(this->getOperation()->getOpResults(), effects);
|
||||
onlyReadsPayload(effects);
|
||||
}
|
||||
};
|
||||
@@ -163,8 +163,8 @@ public:
|
||||
}
|
||||
|
||||
void getEffects(SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(this->getOperation()->getOperands(), effects);
|
||||
producesHandle(this->getOperation()->getResults(), effects);
|
||||
onlyReadsHandle(this->getOperation()->getOpOperands(), effects);
|
||||
producesHandle(this->getOperation()->getOpResults(), effects);
|
||||
onlyReadsPayload(effects);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1261,11 +1261,13 @@ struct PayloadIRResource
|
||||
/// - consumes = Read + Free,
|
||||
/// - produces = Allocate + Write,
|
||||
/// - onlyReads = Read.
|
||||
void consumesHandle(ValueRange handles,
|
||||
void consumesHandle(MutableArrayRef<OpOperand> handles,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects);
|
||||
void producesHandle(ValueRange handles,
|
||||
void producesHandle(ResultRange handles,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects);
|
||||
void onlyReadsHandle(ValueRange handles,
|
||||
void producesHandle(MutableArrayRef<BlockArgument> handles,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects);
|
||||
void onlyReadsHandle(MutableArrayRef<OpOperand> handles,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects);
|
||||
|
||||
/// Checks whether the transform op consumes the given handle.
|
||||
@@ -1296,8 +1298,8 @@ public:
|
||||
/// the results by allocating and writing it and reads/writes the payload IR
|
||||
/// in the process.
|
||||
void getEffects(SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(this->getOperation()->getOperands(), effects);
|
||||
producesHandle(this->getOperation()->getResults(), effects);
|
||||
consumesHandle(this->getOperation()->getOpOperands(), effects);
|
||||
producesHandle(this->getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1322,8 +1324,8 @@ public:
|
||||
/// This op produces handles to the Payload IR without consuming the original
|
||||
/// handles and without modifying the IR itself.
|
||||
void getEffects(SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(this->getOperation()->getOperands(), effects);
|
||||
producesHandle(this->getOperation()->getResults(), effects);
|
||||
onlyReadsHandle(this->getOperation()->getOpOperands(), effects);
|
||||
producesHandle(this->getOperation()->getOpResults(), effects);
|
||||
if (llvm::any_of(this->getOperation()->getOperandTypes(), [](Type t) {
|
||||
return isa<TransformHandleTypeInterface,
|
||||
TransformValueHandleTypeInterface>(t);
|
||||
|
||||
@@ -145,12 +145,19 @@ public:
|
||||
Resource *resource = DefaultResource::get())
|
||||
: effect(effect), resource(resource), stage(stage),
|
||||
effectOnFullRegion(effectOnFullRegion) {}
|
||||
EffectInstance(EffectT *effect, Value value,
|
||||
template <typename T,
|
||||
std::enable_if_t<
|
||||
llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
|
||||
bool> = true>
|
||||
EffectInstance(EffectT *effect, T value,
|
||||
Resource *resource = DefaultResource::get())
|
||||
: effect(effect), resource(resource), value(value), stage(0),
|
||||
effectOnFullRegion(false) {}
|
||||
EffectInstance(EffectT *effect, Value value, int stage,
|
||||
bool effectOnFullRegion,
|
||||
template <typename T,
|
||||
std::enable_if_t<
|
||||
llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
|
||||
bool> = true>
|
||||
EffectInstance(EffectT *effect, T value, int stage, bool effectOnFullRegion,
|
||||
Resource *resource = DefaultResource::get())
|
||||
: effect(effect), resource(resource), value(value), stage(stage),
|
||||
effectOnFullRegion(effectOnFullRegion) {}
|
||||
@@ -172,11 +179,19 @@ public:
|
||||
Resource *resource = DefaultResource::get())
|
||||
: effect(effect), resource(resource), parameters(parameters),
|
||||
stage(stage), effectOnFullRegion(effectOnFullRegion) {}
|
||||
EffectInstance(EffectT *effect, Value value, Attribute parameters,
|
||||
template <typename T,
|
||||
std::enable_if_t<
|
||||
llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
|
||||
bool> = true>
|
||||
EffectInstance(EffectT *effect, T value, Attribute parameters,
|
||||
Resource *resource = DefaultResource::get())
|
||||
: effect(effect), resource(resource), value(value),
|
||||
parameters(parameters), stage(0), effectOnFullRegion(false) {}
|
||||
EffectInstance(EffectT *effect, Value value, Attribute parameters, int stage,
|
||||
template <typename T,
|
||||
std::enable_if_t<
|
||||
llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
|
||||
bool> = true>
|
||||
EffectInstance(EffectT *effect, T value, Attribute parameters, int stage,
|
||||
bool effectOnFullRegion,
|
||||
Resource *resource = DefaultResource::get())
|
||||
: effect(effect), resource(resource), value(value),
|
||||
@@ -199,7 +214,26 @@ public:
|
||||
/// Return the value the effect is applied on, or nullptr if there isn't a
|
||||
/// known value being affected.
|
||||
Value getValue() const {
|
||||
return value ? llvm::dyn_cast_if_present<Value>(value) : Value();
|
||||
if (!value || llvm::isa_and_present<SymbolRefAttr>(value)) {
|
||||
return Value();
|
||||
}
|
||||
if (OpOperand *operand = llvm::dyn_cast_if_present<OpOperand *>(value)) {
|
||||
return operand->get();
|
||||
}
|
||||
if (OpResult result = llvm::dyn_cast_if_present<OpResult>(value)) {
|
||||
return result;
|
||||
}
|
||||
return cast_if_present<BlockArgument>(value);
|
||||
}
|
||||
|
||||
/// Returns the OpOperand effect is applied on, or nullptr if there isn't a
|
||||
/// known value being effected.
|
||||
template <typename T,
|
||||
std::enable_if_t<
|
||||
llvm::is_one_of<T, OpOperand *, OpResult, BlockArgument>::value,
|
||||
bool> = true>
|
||||
T getEffectValue() const {
|
||||
return value ? dyn_cast_if_present<T>(value) : nullptr;
|
||||
}
|
||||
|
||||
/// Return the symbol reference the effect is applied on, or nullptr if there
|
||||
@@ -228,8 +262,9 @@ private:
|
||||
/// The resource that the given value resides in.
|
||||
Resource *resource;
|
||||
|
||||
/// The Symbol or Value that the effect applies to. This is optionally null.
|
||||
PointerUnion<SymbolRefAttr, Value> value;
|
||||
/// The Symbol, OpOperand, OpResult or BlockArgument that the effect applies
|
||||
/// to. This is optionally null.
|
||||
PointerUnion<SymbolRefAttr, OpOperand *, OpResult, BlockArgument> value;
|
||||
|
||||
/// Additional parameters of the effect instance. An attribute is used for
|
||||
/// type-safe structured storage and context-based uniquing. Concrete effects
|
||||
@@ -348,17 +383,32 @@ struct Write : public Effect::Base<Write> {};
|
||||
// SideEffect Utilities
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Returns true if `op` has only an effect of type `EffectTy` (and of no other
|
||||
/// type) on `value`. If no value is provided, simply check if effects of that
|
||||
/// type and only of that type are present.
|
||||
/// Returns true if `op` has only an effect of type `EffectTy`.
|
||||
template <typename EffectTy>
|
||||
bool hasSingleEffect(Operation *op, Value value = nullptr);
|
||||
bool hasSingleEffect(Operation *op);
|
||||
|
||||
/// Returns true if `op` has an effect of type `EffectTy` on `value`. If no
|
||||
/// `value` is provided, simply check if effects of the given type(s) are
|
||||
/// present.
|
||||
/// Returns true if `op` has only an effect of type `EffectTy` (and of no other
|
||||
/// type) on `value`.
|
||||
template <typename EffectTy>
|
||||
bool hasSingleEffect(Operation *op, Value value);
|
||||
|
||||
/// Returns true if `op` has only an effect of type `EffectTy` (and of no other
|
||||
/// type) on `value` of type `ValueTy`.
|
||||
template <typename ValueTy, typename EffectTy>
|
||||
bool hasSingleEffect(Operation *op, ValueTy value);
|
||||
|
||||
/// Returns true if `op` has an effect of type `EffectTy`.
|
||||
template <typename... EffectTys>
|
||||
bool hasEffect(Operation *op, Value value = nullptr);
|
||||
bool hasEffect(Operation *op);
|
||||
|
||||
/// Returns true if `op` has an effect of type `EffectTy` on `value`.
|
||||
template <typename... EffectTys>
|
||||
bool hasEffect(Operation *op, Value value);
|
||||
|
||||
/// Returns true if `op` has an effect of type `EffectTy` on `value` of type
|
||||
/// `ValueTy`.
|
||||
template <typename ValueTy, typename... EffectTys>
|
||||
bool hasEffect(Operation *op, ValueTy value);
|
||||
|
||||
/// Return true if the given operation is unused, and has no side effects on
|
||||
/// memory that prevent erasing.
|
||||
|
||||
@@ -1707,11 +1707,11 @@ LogicalResult AffineDmaStartOp::fold(ArrayRef<Attribute> cstOperands,
|
||||
void AffineDmaStartOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getSrcMemRef(),
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getSrcMemRefMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
effects.emplace_back(MemoryEffects::Write::get(), getDstMemRef(),
|
||||
effects.emplace_back(MemoryEffects::Write::get(), &getDstMemRefMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getTagMemRef(),
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getTagMemRefMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
|
||||
@@ -1797,7 +1797,7 @@ LogicalResult AffineDmaWaitOp::fold(ArrayRef<Attribute> cstOperands,
|
||||
void AffineDmaWaitOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getTagMemRef(),
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getTagMemRefMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
|
||||
|
||||
@@ -142,9 +142,9 @@ SimplifyBoundedAffineOpsOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void SimplifyBoundedAffineOpsOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
for (Value v : getBoundedValues())
|
||||
onlyReadsHandle(v, effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
for (OpOperand &operand : getBoundedValuesMutable())
|
||||
onlyReadsHandle(operand, effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -728,7 +728,7 @@ void MaterializeInDestinationOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
if (isa<BaseMemRefType>(getDest().getType()))
|
||||
effects.emplace_back(MemoryEffects::Write::get(), getDest(),
|
||||
effects.emplace_back(MemoryEffects::Write::get(), &getDestMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ DiagnosedSilenceableFailure transform::BufferLoopHoistingOp::applyToOne(
|
||||
|
||||
void transform::BufferLoopHoistingOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getTargetMutable(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ transform::OneShotBufferizeOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::EliminateEmptyTensorsOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getTargetMutable(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,14 +216,14 @@ LogicalResult transform::CastAndCallOp::verify() {
|
||||
|
||||
void transform::CastAndCallOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getInsertionPoint(), effects);
|
||||
transform::onlyReadsHandle(getInsertionPointMutable(), effects);
|
||||
if (getInputs())
|
||||
transform::onlyReadsHandle(getInputs(), effects);
|
||||
transform::onlyReadsHandle(getInputsMutable(), effects);
|
||||
if (getOutputs())
|
||||
transform::onlyReadsHandle(getOutputs(), effects);
|
||||
transform::onlyReadsHandle(getOutputsMutable(), effects);
|
||||
if (getFunction())
|
||||
transform::onlyReadsHandle(getFunction(), effects);
|
||||
transform::producesHandle(getResult(), effects);
|
||||
transform::onlyReadsHandle(getFunctionMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -825,7 +825,7 @@ Type GEPOp::getResultPtrElementType() {
|
||||
void LoadOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getAddr());
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getAddrMutable());
|
||||
// Volatile operations can have target-specific read-write effects on
|
||||
// memory besides the one referred to by the pointer operand.
|
||||
// Similarly, atomic operations that are monotonic or stricter cause
|
||||
@@ -902,7 +902,7 @@ void LoadOp::build(OpBuilder &builder, OperationState &state, Type type,
|
||||
void StoreOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
effects.emplace_back(MemoryEffects::Write::get(), getAddr());
|
||||
effects.emplace_back(MemoryEffects::Write::get(), &getAddrMutable());
|
||||
// Volatile operations can have target-specific read-write effects on
|
||||
// memory besides the one referred to by the pointer operand.
|
||||
// Similarly, atomic operations that are monotonic or stricter cause
|
||||
|
||||
@@ -1123,28 +1123,23 @@ static void getGenericEffectsImpl(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects,
|
||||
LinalgOp linalgOp) {
|
||||
SmallVector<Value> inputOperands = linalgOp.getDpsInputs();
|
||||
for (auto [index, operand] : llvm::enumerate(inputOperands)) {
|
||||
for (auto [index, operand] : llvm::enumerate(linalgOp.getDpsInputs())) {
|
||||
if (!llvm::isa<MemRefType>(operand.getType()))
|
||||
continue;
|
||||
if (linalgOp.payloadUsesValueFromOperand(&linalgOp->getOpOperand(index))) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), operand, /*stage=*/0,
|
||||
/*effectOnFullRegion=*/true,
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
effects.emplace_back(
|
||||
MemoryEffects::Read::get(), &linalgOp->getOpOperand(index), /*stage=*/0,
|
||||
/*effectOnFullRegion=*/true, SideEffects::DefaultResource::get());
|
||||
}
|
||||
unsigned inputOperandSize = inputOperands.size();
|
||||
|
||||
for (auto [index, operand] : llvm::enumerate(linalgOp.getDpsInits())) {
|
||||
if (!llvm::isa<MemRefType>(operand.getType()))
|
||||
for (OpOperand &operand : linalgOp.getDpsInitsMutable()) {
|
||||
if (!llvm::isa<MemRefType>(operand.get().getType()))
|
||||
continue;
|
||||
if (linalgOp.payloadUsesValueFromOperand(
|
||||
&linalgOp->getOpOperand(index + inputOperandSize))) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), operand, /*stage=*/0,
|
||||
if (linalgOp.payloadUsesValueFromOperand(&operand)) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &operand, /*stage=*/0,
|
||||
/*effectOnFullRegion=*/true,
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
effects.emplace_back(MemoryEffects::Write::get(), operand, /*stage=*/0,
|
||||
effects.emplace_back(MemoryEffects::Write::get(), &operand, /*stage=*/0,
|
||||
/*effectOnFullRegion=*/true,
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
@@ -2546,20 +2541,22 @@ SoftmaxOp::reifyResultShapes(OpBuilder &b,
|
||||
void SoftmaxOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
for (Value operand : getDpsInputs()) {
|
||||
for (auto [index, operand] : llvm::enumerate(getDpsInputs())) {
|
||||
if (!llvm::isa<MemRefType>(operand.getType()))
|
||||
continue;
|
||||
effects.emplace_back(MemoryEffects::Read::get(), operand, /*stage=*/0,
|
||||
effects.emplace_back(MemoryEffects::Read::get(),
|
||||
&getOperation()->getOpOperand(index), /*stage=*/0,
|
||||
/*effectOnFullRegion=*/true,
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
for (Value operand : getDpsInits()) {
|
||||
if (!llvm::isa<MemRefType>(operand.getType()))
|
||||
|
||||
for (OpOperand &operand : getDpsInitsMutable()) {
|
||||
if (!llvm::isa<MemRefType>(operand.get().getType()))
|
||||
continue;
|
||||
effects.emplace_back(MemoryEffects::Read::get(), operand, /*stage=*/0,
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &operand, /*stage=*/0,
|
||||
/*effectOnFullRegion=*/true,
|
||||
SideEffects::DefaultResource::get());
|
||||
effects.emplace_back(MemoryEffects::Write::get(), operand, /*stage=*/0,
|
||||
effects.emplace_back(MemoryEffects::Write::get(), &operand, /*stage=*/0,
|
||||
/*effectOnFullRegion=*/true,
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
|
||||
@@ -115,9 +115,9 @@ DiagnosedSilenceableFailure transform::MatchStructuredOp::matchOperation(
|
||||
|
||||
void transform::MatchStructuredOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getCurrent(), effects);
|
||||
onlyReadsHandle(getCurrentMutable(), effects);
|
||||
onlyReadsPayload(effects);
|
||||
producesHandle(getOutputs(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
LogicalResult transform::MatchStructuredOp::verify() {
|
||||
@@ -707,7 +707,7 @@ LogicalResult transform::MatchStructuredResultOp::verify() {
|
||||
|
||||
void transform::MatchStructuredYieldOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getHandles(), effects);
|
||||
onlyReadsHandle(getHandlesMutable(), effects);
|
||||
onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -369,12 +369,11 @@ void transform::BufferizeToAllocationOp::getEffects(
|
||||
if (getBufferizeDestinationOnly()) {
|
||||
// The destination is replaced with a newly allocated buffer, but the op
|
||||
// itself remains in place.
|
||||
onlyReadsHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getTargetMutable(), effects);
|
||||
} else {
|
||||
consumesHandle(getTarget(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
}
|
||||
producesHandle(getAllocatedBuffer(), effects);
|
||||
producesHandle(getNewOps(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -463,7 +462,7 @@ DiagnosedSilenceableFailure transform::DecomposeInterfaceOp::applyToOne(
|
||||
|
||||
void transform::EliminateLinalgOpAnchoredEmptyTensorsOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getTargetMutable(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1040,9 +1039,9 @@ transform::FuseIntoContainingOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::FuseIntoContainingOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getProducerOp(), effects);
|
||||
onlyReadsHandle(getContainingOp(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
consumesHandle(getProducerOpMutable(), effects);
|
||||
onlyReadsHandle(getContainingOpMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1391,8 +1390,8 @@ DiagnosedSilenceableFailure transform::MultiTileSizesOp::applyToOne(
|
||||
|
||||
void transform::MultiTileSizesOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getTarget(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
onlyReadsHandle(getTargetMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
if (isa<TransformParamTypeInterface>(getLowSize().getType()))
|
||||
onlyReadsPayload(effects);
|
||||
else
|
||||
@@ -1478,9 +1477,9 @@ transform::PackOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::PackOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::consumesHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getPackedSizes(), effects);
|
||||
transform::producesHandle(getPackedOp(), effects);
|
||||
transform::consumesHandle(getTargetMutable(), effects);
|
||||
transform::onlyReadsHandle(getPackedSizesMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1549,9 +1548,9 @@ SmallVector<OpFoldResult> PackGreedilyOp::getMixedMatmulPackedSizes() {
|
||||
|
||||
void transform::PackGreedilyOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::consumesHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getMatmulPackedSizes(), effects);
|
||||
transform::producesHandle(getPackedOp(), effects);
|
||||
transform::consumesHandle(getTargetMutable(), effects);
|
||||
transform::onlyReadsHandle(getMatmulPackedSizesMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1761,11 +1760,9 @@ void transform::PadOp::build(OpBuilder &b, OperationState &result, Value target,
|
||||
|
||||
void PadOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getPadToMultipleOf(), effects);
|
||||
producesHandle(getPadded(), effects);
|
||||
producesHandle(getPad(), effects);
|
||||
producesHandle(getCopy(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
onlyReadsHandle(getPadToMultipleOfMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1992,9 +1989,9 @@ LogicalResult transform::HoistPadBuildPackingLoopNestOp::verify() {
|
||||
|
||||
void transform::HoistPadBuildPackingLoopNestOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getLoop(), effects);
|
||||
transform::producesHandle(getPackingLoop(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
transform::onlyReadsHandle(getLoopMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -2135,8 +2132,8 @@ transform::ReplaceOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::ReplaceOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
producesHandle(getReplacement(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -2361,10 +2358,10 @@ SplitOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void SplitOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
if (getDynamicSplitPoint())
|
||||
onlyReadsHandle(getDynamicSplitPoint(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
onlyReadsHandle(getDynamicSplitPointMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -2831,10 +2828,9 @@ SmallVector<OpFoldResult> transform::TileUsingForOp::getMixedSizes() {
|
||||
|
||||
void transform::TileUsingForOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getDynamicSizes(), effects);
|
||||
producesHandle(getTiledLinalgOp(), effects);
|
||||
producesHandle(getLoops(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
onlyReadsHandle(getDynamicSizesMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -2999,12 +2995,12 @@ DiagnosedSilenceableFailure transform::TileUsingForallOp::apply(
|
||||
|
||||
void transform::TileUsingForallOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getTileSizes(), effects);
|
||||
onlyReadsHandle(getNumThreads(), effects);
|
||||
onlyReadsHandle(getPackedNumThreads(), effects);
|
||||
onlyReadsHandle(getPackedTileSizes(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
onlyReadsHandle(getTileSizesMutable(), effects);
|
||||
onlyReadsHandle(getNumThreadsMutable(), effects);
|
||||
onlyReadsHandle(getPackedNumThreadsMutable(), effects);
|
||||
onlyReadsHandle(getPackedTileSizesMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -3182,8 +3178,8 @@ DiagnosedSilenceableFailure transform::VectorizeOp::apply(
|
||||
|
||||
void transform::VectorizeOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getVectorSizes(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
onlyReadsHandle(getVectorSizesMutable(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -181,9 +181,8 @@ transform::MemRefAllocaToGlobalOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::MemRefAllocaToGlobalOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
producesHandle(getGlobal(), effects);
|
||||
producesHandle(getGetGlobal(), effects);
|
||||
consumesHandle(getAlloca(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
consumesHandle(getAllocaMutable(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -249,7 +248,7 @@ transform::MemRefEraseDeadAllocAndStoresOp::applyToOne(
|
||||
|
||||
void transform::MemRefEraseDeadAllocAndStoresOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
void transform::MemRefEraseDeadAllocAndStoresOp::build(OpBuilder &builder,
|
||||
|
||||
@@ -134,8 +134,8 @@ transform::ApplyNVGPUToNVVMConversionPatternsOp::verifyTypeConverter(
|
||||
|
||||
void transform::CreateAsyncGroupsOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::consumesHandle(getTarget(), effects);
|
||||
transform::producesHandle(getResult(), effects);
|
||||
transform::consumesHandle(getTargetMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ DiagnosedSilenceableFailure transform::LoopPromoteIfOneIterationOp::applyToOne(
|
||||
|
||||
void transform::LoopPromoteIfOneIterationOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ DiagnosedSilenceableFailure transform::TakeAssumedBranchOp::applyToOne(
|
||||
|
||||
void transform::TakeAssumedBranchOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getTargetMutable(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -211,8 +211,8 @@ transform::AlternativesOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::AlternativesOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getOperands(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
consumesHandle(getOperation()->getOpOperands(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
for (Region *region : getRegions()) {
|
||||
if (!region->empty())
|
||||
producesHandle(region->front().getArguments(), effects);
|
||||
@@ -269,8 +269,8 @@ transform::AnnotateOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::AnnotateOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getTarget(), effects);
|
||||
onlyReadsHandle(getParam(), effects);
|
||||
onlyReadsHandle(getTargetMutable(), effects);
|
||||
onlyReadsHandle(getParamMutable(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ transform::ApplyCommonSubexpressionEliminationOp::applyToOne(
|
||||
|
||||
void transform::ApplyCommonSubexpressionEliminationOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -361,7 +361,7 @@ DiagnosedSilenceableFailure transform::ApplyDeadCodeEliminationOp::applyToOne(
|
||||
|
||||
void transform::ApplyDeadCodeEliminationOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ LogicalResult transform::ApplyPatternsOp::verify() {
|
||||
|
||||
void transform::ApplyPatternsOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -674,9 +674,9 @@ LogicalResult transform::ApplyConversionPatternsOp::verify() {
|
||||
void transform::ApplyConversionPatternsOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
if (!getPreserveHandles()) {
|
||||
transform::consumesHandle(getTarget(), effects);
|
||||
transform::consumesHandle(getTargetMutable(), effects);
|
||||
} else {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
}
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
@@ -757,7 +757,7 @@ transform::ApplyLoopInvariantCodeMotionOp::applyToOne(
|
||||
|
||||
void transform::ApplyLoopInvariantCodeMotionOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -820,8 +820,8 @@ transform::CastOp::applyToOne(transform::TransformRewriter &rewriter,
|
||||
void transform::CastOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsPayload(effects);
|
||||
onlyReadsHandle(getInput(), effects);
|
||||
producesHandle(getOutput(), effects);
|
||||
onlyReadsHandle(getInputMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
bool transform::CastOp::areCastCompatible(TypeRange inputs, TypeRange outputs) {
|
||||
@@ -964,8 +964,8 @@ transform::CollectMatchingOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::CollectMatchingOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getRoot(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
onlyReadsHandle(getRootMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1159,9 +1159,9 @@ void transform::ForeachMatchOp::getEffects(
|
||||
return modifiesPayload(effects);
|
||||
}
|
||||
|
||||
consumesHandle(getRoot(), effects);
|
||||
onlyReadsHandle(getForwardedInputs(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
consumesHandle(getRootMutable(), effects);
|
||||
onlyReadsHandle(getForwardedInputsMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1458,7 +1458,7 @@ void transform::ForeachOp::getEffects(
|
||||
// NB: this `zip` should be `zip_equal` - while this op's verifier catches
|
||||
// arity errors, this method might get called before/in absence of `verify()`.
|
||||
for (auto &&[target, blockArg] :
|
||||
llvm::zip(getTargets(), getBody().front().getArguments())) {
|
||||
llvm::zip(getTargetsMutable(), getBody().front().getArguments())) {
|
||||
BlockArgument blockArgument = blockArg;
|
||||
if (any_of(getBody().front().without_terminator(), [&](Operation &op) {
|
||||
return isHandleConsumed(blockArgument,
|
||||
@@ -1480,8 +1480,7 @@ void transform::ForeachOp::getEffects(
|
||||
onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
for (Value result : getResults())
|
||||
producesHandle(result, effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
void transform::ForeachOp::getSuccessorRegions(
|
||||
@@ -1733,8 +1732,8 @@ LogicalResult transform::GetResultOp::verify() {
|
||||
|
||||
void transform::GetTypeOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getValue(), effects);
|
||||
producesHandle(getResult(), effects);
|
||||
onlyReadsHandle(getValueMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -1833,12 +1832,14 @@ void transform::IncludeOp::getEffects(
|
||||
modifiesPayload(effects);
|
||||
|
||||
// Results are always produced.
|
||||
producesHandle(getResults(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
|
||||
// Adds default effects to operands and results. This will be added if
|
||||
// preconditions fail so the trait verifier doesn't complain about missing
|
||||
// effects and the real precondition failure is reported later on.
|
||||
auto defaultEffects = [&] { onlyReadsHandle(getOperands(), effects); };
|
||||
auto defaultEffects = [&] {
|
||||
onlyReadsHandle(getOperation()->getOpOperands(), effects);
|
||||
};
|
||||
|
||||
// Bail if the callee is unknown. This may run as part of the verification
|
||||
// process before we verified the validity of the callee or of this op.
|
||||
@@ -1859,9 +1860,9 @@ void transform::IncludeOp::getEffects(
|
||||
|
||||
for (unsigned i = 0, e = getNumOperands(); i < e; ++i) {
|
||||
if (callee.getArgAttr(i, TransformDialect::kArgConsumedAttrName))
|
||||
consumesHandle(getOperand(i), effects);
|
||||
consumesHandle(getOperation()->getOpOperand(i), effects);
|
||||
else
|
||||
onlyReadsHandle(getOperand(i), effects);
|
||||
onlyReadsHandle(getOperation()->getOpOperand(i), effects);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2022,8 +2023,8 @@ transform::MatchParamCmpIOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::MatchParamCmpIOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getParam(), effects);
|
||||
onlyReadsHandle(getReference(), effects);
|
||||
onlyReadsHandle(getParamMutable(), effects);
|
||||
onlyReadsHandle(getReferenceMutable(), effects);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -2098,8 +2099,8 @@ bool transform::MergeHandlesOp::allowsRepeatedHandleOperands() {
|
||||
|
||||
void transform::MergeHandlesOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getHandles(), effects);
|
||||
producesHandle(getResult(), effects);
|
||||
onlyReadsHandle(getHandlesMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
|
||||
// There are no effects on the Payload IR as this is only a handle
|
||||
// manipulation.
|
||||
@@ -2440,8 +2441,8 @@ transform::SplitHandleOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::SplitHandleOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getHandle(), effects);
|
||||
producesHandle(getResults(), effects);
|
||||
onlyReadsHandle(getHandleMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
// There are no effects on the Payload IR as this is only a handle
|
||||
// manipulation.
|
||||
}
|
||||
@@ -2489,9 +2490,9 @@ transform::ReplicateOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::ReplicateOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getPattern(), effects);
|
||||
onlyReadsHandle(getHandles(), effects);
|
||||
producesHandle(getReplicated(), effects);
|
||||
onlyReadsHandle(getPatternMutable(), effects);
|
||||
onlyReadsHandle(getHandlesMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -2802,7 +2803,7 @@ void transform::PrintOp::getEffects(
|
||||
// unconditionally casts to a specific type before verification could run
|
||||
// here.
|
||||
if (!getTargetMutable().empty())
|
||||
onlyReadsHandle(getTargetMutable()[0].get(), effects);
|
||||
onlyReadsHandle(getTargetMutable()[0], effects);
|
||||
onlyReadsPayload(effects);
|
||||
|
||||
// There is no resource for stderr file descriptor, so just declare print
|
||||
@@ -2830,7 +2831,7 @@ transform::VerifyOp::applyToOne(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::VerifyOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -2839,5 +2840,5 @@ void transform::VerifyOp::getEffects(
|
||||
|
||||
void transform::YieldOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getOperands(), effects);
|
||||
onlyReadsHandle(getOperandsMutable(), effects);
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ IRDLCollectMatchingOp::apply(TransformRewriter &rewriter,
|
||||
|
||||
void IRDLCollectMatchingOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getRoot(), effects);
|
||||
producesHandle(getMatched(), effects);
|
||||
onlyReadsHandle(getRootMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -1603,7 +1603,8 @@ transform::detail::makeTransformStateForTesting(Region *region,
|
||||
/// Appends to `effects` the memory effect instances on `target` with the same
|
||||
/// resource and effect as the ones the operation `iface` having on `source`.
|
||||
static void
|
||||
remapEffects(MemoryEffectOpInterface iface, BlockArgument source, Value target,
|
||||
remapEffects(MemoryEffectOpInterface iface, BlockArgument source,
|
||||
OpOperand *target,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
SmallVector<MemoryEffects::EffectInstance> nestedEffects;
|
||||
iface.getEffectsOnValue(source, nestedEffects);
|
||||
@@ -1614,7 +1615,7 @@ remapEffects(MemoryEffectOpInterface iface, BlockArgument source, Value target,
|
||||
/// Appends to `effects` the same effects as the operations of `block` have on
|
||||
/// block arguments but associated with `operands.`
|
||||
static void
|
||||
remapArgumentEffects(Block &block, ValueRange operands,
|
||||
remapArgumentEffects(Block &block, MutableArrayRef<OpOperand> operands,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
for (Operation &op : block) {
|
||||
auto iface = dyn_cast<MemoryEffectOpInterface>(&op);
|
||||
@@ -1622,7 +1623,7 @@ remapArgumentEffects(Block &block, ValueRange operands,
|
||||
continue;
|
||||
|
||||
for (auto &&[source, target] : llvm::zip(block.getArguments(), operands)) {
|
||||
remapEffects(iface, source, target, effects);
|
||||
remapEffects(iface, source, &target, effects);
|
||||
}
|
||||
|
||||
SmallVector<MemoryEffects::EffectInstance> nestedEffects;
|
||||
@@ -1635,8 +1636,8 @@ remapArgumentEffects(Block &block, ValueRange operands,
|
||||
void transform::detail::getPotentialTopLevelEffects(
|
||||
Operation *operation, Value root, Block &body,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(operation->getOperands(), effects);
|
||||
transform::producesHandle(operation->getResults(), effects);
|
||||
transform::onlyReadsHandle(operation->getOpOperands(), effects);
|
||||
transform::producesHandle(operation->getOpResults(), effects);
|
||||
|
||||
if (!root) {
|
||||
for (Operation &op : body) {
|
||||
@@ -1652,7 +1653,7 @@ void transform::detail::getPotentialTopLevelEffects(
|
||||
|
||||
// Carry over all effects on arguments of the entry block as those on the
|
||||
// operands, this is the same value just remapped.
|
||||
remapArgumentEffects(body, operation->getOperands(), effects);
|
||||
remapArgumentEffects(body, operation->getOpOperands(), effects);
|
||||
}
|
||||
|
||||
LogicalResult transform::detail::mapPossibleTopLevelTransformOpBlockArguments(
|
||||
@@ -1761,10 +1762,10 @@ void transform::detail::getParamProducerTransformOpTraitEffects(
|
||||
Operation *op, SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
producesHandle(op->getResults(), effects);
|
||||
bool hasPayloadOperands = false;
|
||||
for (Value operand : op->getOperands()) {
|
||||
for (OpOperand &operand : op->getOpOperands()) {
|
||||
onlyReadsHandle(operand, effects);
|
||||
if (llvm::isa<TransformHandleTypeInterface,
|
||||
TransformValueHandleTypeInterface>(operand.getType()))
|
||||
TransformValueHandleTypeInterface>(operand.get().getType()))
|
||||
hasPayloadOperands = true;
|
||||
}
|
||||
if (hasPayloadOperands)
|
||||
@@ -1796,12 +1797,12 @@ transform::detail::verifyParamProducerTransformOpTrait(Operation *op) {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void transform::consumesHandle(
|
||||
ValueRange handles,
|
||||
MutableArrayRef<OpOperand> handles,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
for (Value handle : handles) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), handle,
|
||||
for (OpOperand &handle : handles) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &handle,
|
||||
TransformMappingResource::get());
|
||||
effects.emplace_back(MemoryEffects::Free::get(), handle,
|
||||
effects.emplace_back(MemoryEffects::Free::get(), &handle,
|
||||
TransformMappingResource::get());
|
||||
}
|
||||
}
|
||||
@@ -1826,9 +1827,20 @@ bool transform::isHandleConsumed(Value handle,
|
||||
}
|
||||
|
||||
void transform::producesHandle(
|
||||
ValueRange handles,
|
||||
ResultRange handles,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
for (Value handle : handles) {
|
||||
for (OpResult handle : handles) {
|
||||
effects.emplace_back(MemoryEffects::Allocate::get(), handle,
|
||||
TransformMappingResource::get());
|
||||
effects.emplace_back(MemoryEffects::Write::get(), handle,
|
||||
TransformMappingResource::get());
|
||||
}
|
||||
}
|
||||
|
||||
void transform::producesHandle(
|
||||
MutableArrayRef<BlockArgument> handles,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
for (BlockArgument handle : handles) {
|
||||
effects.emplace_back(MemoryEffects::Allocate::get(), handle,
|
||||
TransformMappingResource::get());
|
||||
effects.emplace_back(MemoryEffects::Write::get(), handle,
|
||||
@@ -1837,10 +1849,10 @@ void transform::producesHandle(
|
||||
}
|
||||
|
||||
void transform::onlyReadsHandle(
|
||||
ValueRange handles,
|
||||
MutableArrayRef<OpOperand> handles,
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
for (Value handle : handles) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), handle,
|
||||
for (OpOperand &handle : handles) {
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &handle,
|
||||
TransformMappingResource::get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,6 @@ DiagnosedSilenceableFailure transform::HoistLoopInvariantSubsetsOp::applyToOne(
|
||||
|
||||
void transform::HoistLoopInvariantSubsetsOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -158,8 +158,8 @@ transform::PDLMatchOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void transform::PDLMatchOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
onlyReadsHandle(getRoot(), effects);
|
||||
producesHandle(getMatched(), effects);
|
||||
onlyReadsHandle(getRootMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -4232,7 +4232,7 @@ void TransferReadOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
if (llvm::isa<MemRefType>(getShapedType()))
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getSource(),
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getSourceMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
|
||||
@@ -4606,7 +4606,7 @@ void TransferWriteOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
if (llvm::isa<MemRefType>(getShapedType()))
|
||||
effects.emplace_back(MemoryEffects::Write::get(), getSource(),
|
||||
effects.emplace_back(MemoryEffects::Write::get(), &getSourceMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
}
|
||||
|
||||
|
||||
@@ -103,6 +103,28 @@ static bool wouldOpBeTriviallyDeadImpl(Operation *rootOp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename EffectTy>
|
||||
bool mlir::hasSingleEffect(Operation *op) {
|
||||
auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
|
||||
if (!memOp)
|
||||
return false;
|
||||
SmallVector<SideEffects::EffectInstance<MemoryEffects::Effect>, 4> effects;
|
||||
memOp.getEffects(effects);
|
||||
bool hasSingleEffectOnVal = false;
|
||||
// Iterate through `effects` and check if an effect of type `EffectTy` and
|
||||
// only of that type is present.
|
||||
for (auto &effect : effects) {
|
||||
hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
|
||||
if (!hasSingleEffectOnVal)
|
||||
return false;
|
||||
}
|
||||
return hasSingleEffectOnVal;
|
||||
}
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(Operation *);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Free>(Operation *);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Read>(Operation *);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Write>(Operation *);
|
||||
|
||||
template <typename EffectTy>
|
||||
bool mlir::hasSingleEffect(Operation *op, Value value) {
|
||||
auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
|
||||
@@ -112,10 +134,9 @@ bool mlir::hasSingleEffect(Operation *op, Value value) {
|
||||
memOp.getEffects(effects);
|
||||
bool hasSingleEffectOnVal = false;
|
||||
// Iterate through `effects` and check if an effect of type `EffectTy` and
|
||||
// only of that type is present. A `value` to check the effect on may or may
|
||||
// not have been provided.
|
||||
// only of that type is present.
|
||||
for (auto &effect : effects) {
|
||||
if (value && effect.getValue() != value)
|
||||
if (effect.getValue() != value)
|
||||
continue;
|
||||
hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
|
||||
if (!hasSingleEffectOnVal)
|
||||
@@ -125,10 +146,84 @@ bool mlir::hasSingleEffect(Operation *op, Value value) {
|
||||
}
|
||||
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Allocate>(Operation *,
|
||||
Value);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Free>(Operation *, Value);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Read>(Operation *, Value);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Write>(Operation *, Value);
|
||||
Value value);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Free>(Operation *,
|
||||
Value value);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Read>(Operation *,
|
||||
Value value);
|
||||
template bool mlir::hasSingleEffect<MemoryEffects::Write>(Operation *,
|
||||
Value value);
|
||||
|
||||
template <typename ValueTy, typename EffectTy>
|
||||
bool mlir::hasSingleEffect(Operation *op, ValueTy value) {
|
||||
auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
|
||||
if (!memOp)
|
||||
return false;
|
||||
SmallVector<SideEffects::EffectInstance<MemoryEffects::Effect>, 4> effects;
|
||||
memOp.getEffects(effects);
|
||||
bool hasSingleEffectOnVal = false;
|
||||
// Iterate through `effects` and check if an effect of type `EffectTy` and
|
||||
// only of that type is present on value.
|
||||
for (auto &effect : effects) {
|
||||
if (effect.getEffectValue<ValueTy>() != value)
|
||||
continue;
|
||||
hasSingleEffectOnVal = isa<EffectTy>(effect.getEffect());
|
||||
if (!hasSingleEffectOnVal)
|
||||
return false;
|
||||
}
|
||||
return hasSingleEffectOnVal;
|
||||
}
|
||||
|
||||
template bool
|
||||
mlir::hasSingleEffect<OpOperand *, MemoryEffects::Allocate>(Operation *,
|
||||
OpOperand *);
|
||||
template bool
|
||||
mlir::hasSingleEffect<OpOperand *, MemoryEffects::Free>(Operation *,
|
||||
OpOperand *);
|
||||
template bool
|
||||
mlir::hasSingleEffect<OpOperand *, MemoryEffects::Read>(Operation *,
|
||||
OpOperand *);
|
||||
template bool
|
||||
mlir::hasSingleEffect<OpOperand *, MemoryEffects::Write>(Operation *,
|
||||
OpOperand *);
|
||||
template bool
|
||||
mlir::hasSingleEffect<OpResult, MemoryEffects::Allocate>(Operation *, OpResult);
|
||||
template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Free>(Operation *,
|
||||
OpResult);
|
||||
template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Read>(Operation *,
|
||||
OpResult);
|
||||
template bool mlir::hasSingleEffect<OpResult, MemoryEffects::Write>(Operation *,
|
||||
OpResult);
|
||||
template bool
|
||||
mlir::hasSingleEffect<BlockArgument, MemoryEffects::Allocate>(Operation *,
|
||||
BlockArgument);
|
||||
template bool
|
||||
mlir::hasSingleEffect<BlockArgument, MemoryEffects::Free>(Operation *,
|
||||
BlockArgument);
|
||||
template bool
|
||||
mlir::hasSingleEffect<BlockArgument, MemoryEffects::Read>(Operation *,
|
||||
BlockArgument);
|
||||
template bool
|
||||
mlir::hasSingleEffect<BlockArgument, MemoryEffects::Write>(Operation *,
|
||||
BlockArgument);
|
||||
|
||||
template <typename... EffectTys>
|
||||
bool mlir::hasEffect(Operation *op) {
|
||||
auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
|
||||
if (!memOp)
|
||||
return false;
|
||||
SmallVector<SideEffects::EffectInstance<MemoryEffects::Effect>, 4> effects;
|
||||
memOp.getEffects(effects);
|
||||
return llvm::any_of(effects, [&](MemoryEffects::EffectInstance &effect) {
|
||||
return isa<EffectTys...>(effect.getEffect());
|
||||
});
|
||||
}
|
||||
template bool mlir::hasEffect<MemoryEffects::Allocate>(Operation *);
|
||||
template bool mlir::hasEffect<MemoryEffects::Free>(Operation *);
|
||||
template bool mlir::hasEffect<MemoryEffects::Read>(Operation *);
|
||||
template bool mlir::hasEffect<MemoryEffects::Write>(Operation *);
|
||||
template bool
|
||||
mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(Operation *);
|
||||
|
||||
template <typename... EffectTys>
|
||||
bool mlir::hasEffect(Operation *op, Value value) {
|
||||
@@ -138,17 +233,70 @@ bool mlir::hasEffect(Operation *op, Value value) {
|
||||
SmallVector<SideEffects::EffectInstance<MemoryEffects::Effect>, 4> effects;
|
||||
memOp.getEffects(effects);
|
||||
return llvm::any_of(effects, [&](MemoryEffects::EffectInstance &effect) {
|
||||
if (value && effect.getValue() != value)
|
||||
if (effect.getValue() != value)
|
||||
return false;
|
||||
return isa<EffectTys...>(effect.getEffect());
|
||||
});
|
||||
}
|
||||
template bool mlir::hasEffect<MemoryEffects::Allocate>(Operation *, Value);
|
||||
template bool mlir::hasEffect<MemoryEffects::Free>(Operation *, Value);
|
||||
template bool mlir::hasEffect<MemoryEffects::Read>(Operation *, Value);
|
||||
template bool mlir::hasEffect<MemoryEffects::Write>(Operation *, Value);
|
||||
template bool mlir::hasEffect<MemoryEffects::Allocate>(Operation *,
|
||||
Value value);
|
||||
template bool mlir::hasEffect<MemoryEffects::Free>(Operation *, Value value);
|
||||
template bool mlir::hasEffect<MemoryEffects::Read>(Operation *, Value value);
|
||||
template bool mlir::hasEffect<MemoryEffects::Write>(Operation *, Value value);
|
||||
template bool
|
||||
mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(Operation *, Value);
|
||||
mlir::hasEffect<MemoryEffects::Write, MemoryEffects::Free>(Operation *,
|
||||
Value value);
|
||||
|
||||
template <typename ValueTy, typename... EffectTys>
|
||||
bool mlir::hasEffect(Operation *op, ValueTy value) {
|
||||
auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
|
||||
if (!memOp)
|
||||
return false;
|
||||
SmallVector<SideEffects::EffectInstance<MemoryEffects::Effect>, 4> effects;
|
||||
memOp.getEffects(effects);
|
||||
return llvm::any_of(effects, [&](MemoryEffects::EffectInstance &effect) {
|
||||
if (effect.getEffectValue<ValueTy>() != value)
|
||||
return false;
|
||||
return isa<EffectTys...>(effect.getEffect());
|
||||
});
|
||||
}
|
||||
template bool
|
||||
mlir::hasEffect<OpOperand *, MemoryEffects::Allocate>(Operation *, OpOperand *);
|
||||
template bool mlir::hasEffect<OpOperand *, MemoryEffects::Free>(Operation *,
|
||||
OpOperand *);
|
||||
template bool mlir::hasEffect<OpOperand *, MemoryEffects::Read>(Operation *,
|
||||
OpOperand *);
|
||||
template bool mlir::hasEffect<OpOperand *, MemoryEffects::Write>(Operation *,
|
||||
OpOperand *);
|
||||
template bool
|
||||
mlir::hasEffect<OpOperand *, MemoryEffects::Write, MemoryEffects::Free>(
|
||||
Operation *, OpOperand *);
|
||||
|
||||
template bool mlir::hasEffect<OpResult, MemoryEffects::Allocate>(Operation *,
|
||||
OpResult);
|
||||
template bool mlir::hasEffect<OpResult, MemoryEffects::Free>(Operation *,
|
||||
OpResult);
|
||||
template bool mlir::hasEffect<OpResult, MemoryEffects::Read>(Operation *,
|
||||
OpResult);
|
||||
template bool mlir::hasEffect<OpResult, MemoryEffects::Write>(Operation *,
|
||||
OpResult);
|
||||
template bool
|
||||
mlir::hasEffect<OpResult, MemoryEffects::Write, MemoryEffects::Free>(
|
||||
Operation *, OpResult);
|
||||
|
||||
template bool
|
||||
mlir::hasEffect<BlockArgument, MemoryEffects::Allocate>(Operation *,
|
||||
BlockArgument);
|
||||
template bool
|
||||
mlir::hasEffect<BlockArgument, MemoryEffects::Free>(Operation *, BlockArgument);
|
||||
template bool
|
||||
mlir::hasEffect<BlockArgument, MemoryEffects::Read>(Operation *, BlockArgument);
|
||||
template bool
|
||||
mlir::hasEffect<BlockArgument, MemoryEffects::Write>(Operation *,
|
||||
BlockArgument);
|
||||
template bool
|
||||
mlir::hasEffect<BlockArgument, MemoryEffects::Write, MemoryEffects::Free>(
|
||||
Operation *, BlockArgument);
|
||||
|
||||
bool mlir::wouldOpBeTriviallyDead(Operation *op) {
|
||||
if (op->mightHaveTrait<OpTrait::IsTerminator>())
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// RUN: mlir-opt %s --test-side-effects --verify-diagnostics
|
||||
|
||||
func.func @test_side_effects(%arg0: memref<2xi32>) -> memref<2xi32> {
|
||||
// expected-remark @below {{found an instance of 'read' on a value, on resource '<Default>'}}
|
||||
// expected-remark @below {{found an instance of 'write' on a value, on resource '<Default>'}}
|
||||
// expected-remark @below {{found an instance of 'allocate' on a value, on resource '<Default>'}}
|
||||
// expected-remark @below {{found an instance of 'read' on a op operand, on resource '<Default>'}}
|
||||
// expected-remark @below {{found an instance of 'write' on a op result, on resource '<Default>'}}
|
||||
// expected-remark @below {{found an instance of 'allocate' on a op result, on resource '<Default>'}}
|
||||
%0 = bufferization.clone %arg0 : memref<2xi32> to memref<2xi32>
|
||||
// expected-remark @below {{operation has no memory effects}}
|
||||
return %0 : memref<2xi32>
|
||||
}
|
||||
|
||||
@@ -1,38 +1,60 @@
|
||||
// RUN: mlir-opt %s -test-side-effects -verify-diagnostics
|
||||
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%0 = "test.side_effect_op"() {} : () -> i32
|
||||
func.func @side_effect(%arg : index) {
|
||||
// expected-remark@+1 {{operation has no memory effects}}
|
||||
%0 = "test.side_effect_op"() {} : () -> i32
|
||||
|
||||
// expected-remark@+2 {{found an instance of 'read' on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'free' on resource '<Default>'}}
|
||||
%1 = "test.side_effect_op"() {effects = [
|
||||
{effect="read"}, {effect="free"}
|
||||
]} : () -> i32
|
||||
|
||||
// expected-remark@+1 {{found an instance of 'write' on resource '<Test>'}}
|
||||
%2 = "test.side_effect_op"() {effects = [
|
||||
{effect="write", test_resource}
|
||||
]} : () -> i32
|
||||
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Test>'}}
|
||||
%3 = "test.side_effect_op"() {effects = [
|
||||
{effect="allocate", on_result, test_resource}
|
||||
]} : () -> i32
|
||||
|
||||
// expected-remark@+1 {{found an instance of 'read' on a symbol '@foo_ref', on resource '<Test>'}}
|
||||
"test.side_effect_op"() {effects = [
|
||||
{effect="read", on_reference = @foo_ref, test_resource}
|
||||
]} : () -> i32
|
||||
|
||||
// No _memory_ effects, but a parametric test effect.
|
||||
// expected-remark@+2 {{operation has no memory effects}}
|
||||
// expected-remark@+1 {{found a parametric effect with affine_map<(d0, d1) -> (d1, d0)>}}
|
||||
%4 = "test.side_effect_op"() {
|
||||
effect_parameter = affine_map<(i, j) -> (j, i)>
|
||||
} : () -> i32
|
||||
|
||||
// Check with this unregistered operation to test the fallback on the dialect.
|
||||
// expected-remark@+1 {{found a parametric effect with affine_map<(d0, d1) -> (d1, d0)>}}
|
||||
%5 = "test.unregistered_side_effect_op"() {
|
||||
effect_parameter = affine_map<(i, j) -> (j, i)>
|
||||
} : () -> i32
|
||||
|
||||
// expected-remark@+2 {{found an instance of 'read' on resource '<Default>'}}
|
||||
// expected-remark@+1 {{found an instance of 'free' on resource '<Default>'}}
|
||||
%1 = "test.side_effect_op"() {effects = [
|
||||
{effect="read"}, {effect="free"}
|
||||
]} : () -> i32
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a op operand, on resource '<Test>'}}
|
||||
%6 = test.side_effect_with_region_op (%arg) {
|
||||
^bb0(%arg0 : index):
|
||||
test.region_yield %arg0 : index
|
||||
} {effects = [ {effect="allocate", on_operand, test_resource} ]} : index -> index
|
||||
|
||||
// expected-remark@+1 {{found an instance of 'write' on resource '<Test>'}}
|
||||
%2 = "test.side_effect_op"() {effects = [
|
||||
{effect="write", test_resource}
|
||||
]} : () -> i32
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource '<Test>'}}
|
||||
%7 = test.side_effect_with_region_op (%arg) {
|
||||
^bb0(%arg0 : index):
|
||||
test.region_yield %arg0 : index
|
||||
} {effects = [ {effect="allocate", on_result, test_resource} ]} : index -> index
|
||||
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource '<Test>'}}
|
||||
%3 = "test.side_effect_op"() {effects = [
|
||||
{effect="allocate", on_result, test_resource}
|
||||
]} : () -> i32
|
||||
// expected-remark@+1 {{found an instance of 'allocate' on a block argument, on resource '<Test>'}}
|
||||
%8 = test.side_effect_with_region_op (%arg) {
|
||||
^bb0(%arg0 : index):
|
||||
test.region_yield %arg0 : index
|
||||
} {effects = [ {effect="allocate", on_argument, test_resource} ]} : index -> index
|
||||
|
||||
// expected-remark@+1 {{found an instance of 'read' on a symbol '@foo_ref', on resource '<Test>'}}
|
||||
"test.side_effect_op"() {effects = [
|
||||
{effect="read", on_reference = @foo_ref, test_resource}
|
||||
]} : () -> i32
|
||||
|
||||
// No _memory_ effects, but a parametric test effect.
|
||||
// expected-remark@+2 {{operation has no memory effects}}
|
||||
// expected-remark@+1 {{found a parametric effect with affine_map<(d0, d1) -> (d1, d0)>}}
|
||||
%4 = "test.side_effect_op"() {
|
||||
effect_parameter = affine_map<(i, j) -> (j, i)>
|
||||
} : () -> i32
|
||||
|
||||
// Check with this unregistered operation to test the fallback on the dialect.
|
||||
// expected-remark@+1 {{found a parametric effect with affine_map<(d0, d1) -> (d1, d0)>}}
|
||||
%5 = "test.unregistered_side_effect_op"() {
|
||||
effect_parameter = affine_map<(i, j) -> (j, i)>
|
||||
} : () -> i32
|
||||
func.return
|
||||
}
|
||||
|
||||
@@ -329,8 +329,6 @@ void SideEffectOp::getEffects(
|
||||
if (!effectsAttr)
|
||||
return;
|
||||
|
||||
// If there is one, it is an array of dictionary attributes that hold
|
||||
// information on the effects of this operation.
|
||||
for (Attribute element : effectsAttr) {
|
||||
DictionaryAttr effectElement = cast<DictionaryAttr>(element);
|
||||
|
||||
@@ -350,7 +348,7 @@ void SideEffectOp::getEffects(
|
||||
|
||||
// Check for a result to affect.
|
||||
if (effectElement.get("on_result"))
|
||||
effects.emplace_back(effect, getResult(), resource);
|
||||
effects.emplace_back(effect, getOperation()->getOpResults()[0], resource);
|
||||
else if (Attribute ref = effectElement.get("on_reference"))
|
||||
effects.emplace_back(effect, cast<SymbolRefAttr>(ref), resource);
|
||||
else
|
||||
@@ -363,6 +361,51 @@ void SideEffectOp::getEffects(
|
||||
testSideEffectOpGetEffect(getOperation(), effects);
|
||||
}
|
||||
|
||||
void SideEffectWithRegionOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
// Check for an effects attribute on the op instance.
|
||||
ArrayAttr effectsAttr = (*this)->getAttrOfType<ArrayAttr>("effects");
|
||||
if (!effectsAttr)
|
||||
return;
|
||||
|
||||
for (Attribute element : effectsAttr) {
|
||||
DictionaryAttr effectElement = cast<DictionaryAttr>(element);
|
||||
|
||||
// Get the specific memory effect.
|
||||
MemoryEffects::Effect *effect =
|
||||
StringSwitch<MemoryEffects::Effect *>(
|
||||
cast<StringAttr>(effectElement.get("effect")).getValue())
|
||||
.Case("allocate", MemoryEffects::Allocate::get())
|
||||
.Case("free", MemoryEffects::Free::get())
|
||||
.Case("read", MemoryEffects::Read::get())
|
||||
.Case("write", MemoryEffects::Write::get());
|
||||
|
||||
// Check for a non-default resource to use.
|
||||
SideEffects::Resource *resource = SideEffects::DefaultResource::get();
|
||||
if (effectElement.get("test_resource"))
|
||||
resource = TestResource::get();
|
||||
|
||||
// Check for a result to affect.
|
||||
if (effectElement.get("on_result"))
|
||||
effects.emplace_back(effect, getOperation()->getOpResults()[0], resource);
|
||||
else if (effectElement.get("on_operand"))
|
||||
effects.emplace_back(effect, &getOperation()->getOpOperands()[0],
|
||||
resource);
|
||||
else if (effectElement.get("on_argument"))
|
||||
effects.emplace_back(effect, getOperation()->getRegion(0).getArgument(0),
|
||||
resource);
|
||||
else if (Attribute ref = effectElement.get("on_reference"))
|
||||
effects.emplace_back(effect, cast<SymbolRefAttr>(ref), resource);
|
||||
else
|
||||
effects.emplace_back(effect, resource);
|
||||
}
|
||||
}
|
||||
|
||||
void SideEffectWithRegionOp::getEffects(
|
||||
SmallVectorImpl<TestEffects::EffectInstance> &effects) {
|
||||
testSideEffectOpGetEffect(getOperation(), effects);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// StringAttrPrettyNameOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -1027,7 +1070,7 @@ void ReadBufferOp::getEffects(
|
||||
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
|
||||
&effects) {
|
||||
// The buffer operand is read.
|
||||
effects.emplace_back(MemoryEffects::Read::get(), getBuffer(),
|
||||
effects.emplace_back(MemoryEffects::Read::get(), &getBufferMutable(),
|
||||
SideEffects::DefaultResource::get());
|
||||
// The buffer contents are dumped.
|
||||
effects.emplace_back(MemoryEffects::Write::get(),
|
||||
|
||||
@@ -2105,6 +2105,17 @@ def SideEffectOp : TEST_Op<"side_effect_op",
|
||||
let results = (outs AnyType:$result);
|
||||
}
|
||||
|
||||
def SideEffectWithRegionOp : TEST_Op<"side_effect_with_region_op",
|
||||
[DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
|
||||
DeclareOpInterfaceMethods<TestEffectOpInterface>]> {
|
||||
let arguments = (ins AnyType:$operand);
|
||||
let results = (outs AnyType:$result);
|
||||
let regions = (region AnyRegion:$region);
|
||||
let assemblyFormat = [{
|
||||
`(` $operand`)` $region attr-dict `:` type($operand) `->` type($result)
|
||||
}];
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Test CopyOpInterface
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -128,8 +128,8 @@ mlir::test::TestProduceSelfHandleOrForwardOperandOp::apply(
|
||||
void mlir::test::TestProduceSelfHandleOrForwardOperandOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
if (getOperand())
|
||||
transform::onlyReadsHandle(getOperand(), effects);
|
||||
transform::producesHandle(getRes(), effects);
|
||||
transform::onlyReadsHandle(getOperandMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
DiagnosedSilenceableFailure
|
||||
@@ -142,8 +142,8 @@ mlir::test::TestProduceValueHandleToSelfOperand::apply(
|
||||
|
||||
void mlir::test::TestProduceValueHandleToSelfOperand::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getIn(), effects);
|
||||
transform::producesHandle(getOut(), effects);
|
||||
transform::onlyReadsHandle(getInMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -160,8 +160,8 @@ mlir::test::TestProduceValueHandleToResult::applyToOne(
|
||||
|
||||
void mlir::test::TestProduceValueHandleToResult::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getIn(), effects);
|
||||
transform::producesHandle(getOut(), effects);
|
||||
transform::onlyReadsHandle(getInMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -181,8 +181,8 @@ mlir::test::TestProduceValueHandleToArgumentOfParentBlock::applyToOne(
|
||||
|
||||
void mlir::test::TestProduceValueHandleToArgumentOfParentBlock::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getIn(), effects);
|
||||
transform::producesHandle(getOut(), effects);
|
||||
transform::onlyReadsHandle(getInMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -199,9 +199,9 @@ mlir::test::TestConsumeOperand::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void mlir::test::TestConsumeOperand::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::consumesHandle(getOperand(), effects);
|
||||
transform::consumesHandle(getOperation()->getOpOperands(), effects);
|
||||
if (getSecondOperand())
|
||||
transform::consumesHandle(getSecondOperand(), effects);
|
||||
transform::consumesHandle(getSecondOperandMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ DiagnosedSilenceableFailure mlir::test::TestConsumeOperandOfOpKindOrFail::apply(
|
||||
|
||||
void mlir::test::TestConsumeOperandOfOpKindOrFail::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::consumesHandle(getOperand(), effects);
|
||||
transform::consumesHandle(getOperation()->getOpOperands(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ mlir::test::TestSucceedIfOperandOfOpKind::matchOperation(
|
||||
|
||||
void mlir::test::TestSucceedIfOperandOfOpKind::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getOperand(), effects);
|
||||
transform::onlyReadsHandle(getOperation()->getOpOperands(), effects);
|
||||
transform::onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ mlir::test::TestCheckIfTestExtensionPresentOp::apply(
|
||||
|
||||
void mlir::test::TestCheckIfTestExtensionPresentOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getOperand(), effects);
|
||||
transform::onlyReadsHandle(getOperation()->getOpOperands(), effects);
|
||||
transform::onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -302,8 +302,8 @@ DiagnosedSilenceableFailure mlir::test::TestRemapOperandPayloadToSelfOp::apply(
|
||||
|
||||
void mlir::test::TestRemapOperandPayloadToSelfOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getOperand(), effects);
|
||||
transform::producesHandle(getOut(), effects);
|
||||
transform::onlyReadsHandle(getOperation()->getOpOperands(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ DiagnosedSilenceableFailure mlir::test::TestEmitRemarkAndEraseOperandOp::apply(
|
||||
|
||||
void mlir::test::TestEmitRemarkAndEraseOperandOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::consumesHandle(getTarget(), effects);
|
||||
transform::consumesHandle(getTargetMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -425,8 +425,8 @@ mlir::test::TestCopyPayloadOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void mlir::test::TestCopyPayloadOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getHandle(), effects);
|
||||
transform::producesHandle(getCopy(), effects);
|
||||
transform::onlyReadsHandle(getHandleMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
transform::onlyReadsPayload(effects);
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ DiagnosedSilenceableFailure mlir::transform::TestDialectParamType::checkPayload(
|
||||
|
||||
void mlir::test::TestReportNumberOfTrackedHandlesNestedUnder::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
}
|
||||
|
||||
DiagnosedSilenceableFailure
|
||||
@@ -530,9 +530,8 @@ mlir::test::TestProduceParamOp::apply(transform::TransformRewriter &rewriter,
|
||||
|
||||
void mlir::test::TestProduceTransformParamOrForwardOperandOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getIn(), effects);
|
||||
transform::producesHandle(getOut(), effects);
|
||||
transform::producesHandle(getParam(), effects);
|
||||
transform::onlyReadsHandle(getInMutable(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
DiagnosedSilenceableFailure
|
||||
@@ -560,7 +559,7 @@ mlir::test::TestProduceTransformParamOrForwardOperandOp::applyToOne(
|
||||
|
||||
void mlir::test::TestProduceNullPayloadOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::producesHandle(getOut(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
DiagnosedSilenceableFailure mlir::test::TestProduceNullPayloadOp::apply(
|
||||
@@ -580,7 +579,7 @@ DiagnosedSilenceableFailure mlir::test::TestProduceEmptyPayloadOp::apply(
|
||||
|
||||
void mlir::test::TestProduceNullParamOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::producesHandle(getOut(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
DiagnosedSilenceableFailure mlir::test::TestProduceNullParamOp::apply(
|
||||
@@ -592,7 +591,7 @@ DiagnosedSilenceableFailure mlir::test::TestProduceNullParamOp::apply(
|
||||
|
||||
void mlir::test::TestProduceNullValueOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::producesHandle(getOut(), effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
DiagnosedSilenceableFailure mlir::test::TestProduceNullValueOp::apply(
|
||||
@@ -605,12 +604,15 @@ DiagnosedSilenceableFailure mlir::test::TestProduceNullValueOp::apply(
|
||||
void mlir::test::TestRequiredMemoryEffectsOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
if (getHasOperandEffect())
|
||||
transform::consumesHandle(getIn(), effects);
|
||||
transform::consumesHandle(getInMutable(), effects);
|
||||
|
||||
if (getHasResultEffect())
|
||||
transform::producesHandle(getOut(), effects);
|
||||
else
|
||||
transform::onlyReadsHandle(getOut(), effects);
|
||||
if (getHasResultEffect()) {
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
} else {
|
||||
effects.emplace_back(MemoryEffects::Read::get(),
|
||||
llvm::cast<OpResult>(getOut()),
|
||||
transform::TransformMappingResource::get());
|
||||
}
|
||||
|
||||
if (getModifiesPayload())
|
||||
transform::modifiesPayload(effects);
|
||||
@@ -625,14 +627,13 @@ DiagnosedSilenceableFailure mlir::test::TestRequiredMemoryEffectsOp::apply(
|
||||
|
||||
void mlir::test::TestTrackedRewriteOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getIn(), effects);
|
||||
transform::onlyReadsHandle(getInMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
void mlir::test::TestDummyPayloadOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
for (OpResult result : getResults())
|
||||
transform::producesHandle(result, effects);
|
||||
transform::producesHandle(getOperation()->getOpResults(), effects);
|
||||
}
|
||||
|
||||
LogicalResult mlir::test::TestDummyPayloadOp::verify() {
|
||||
@@ -719,7 +720,7 @@ void mlir::test::ApplyTestPatternsOp::populatePatterns(
|
||||
|
||||
void mlir::test::TestReEnterRegionOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::consumesHandle(getOperands(), effects);
|
||||
transform::consumesHandle(getOperation()->getOpOperands(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -782,8 +783,8 @@ DiagnosedSilenceableFailure mlir::test::TestNotifyPayloadOpReplacedOp::apply(
|
||||
|
||||
void mlir::test::TestNotifyPayloadOpReplacedOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getOriginal(), effects);
|
||||
transform::onlyReadsHandle(getReplacement(), effects);
|
||||
transform::onlyReadsHandle(getOriginalMutable(), effects);
|
||||
transform::onlyReadsHandle(getReplacementMutable(), effects);
|
||||
}
|
||||
|
||||
DiagnosedSilenceableFailure mlir::test::TestProduceInvalidIR::applyToOne(
|
||||
@@ -799,7 +800,7 @@ DiagnosedSilenceableFailure mlir::test::TestProduceInvalidIR::applyToOne(
|
||||
|
||||
void mlir::test::TestProduceInvalidIR::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
transform::onlyReadsHandle(getTarget(), effects);
|
||||
transform::onlyReadsHandle(getTargetMutable(), effects);
|
||||
transform::modifiesPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ struct SideEffectsPass
|
||||
effects.clear();
|
||||
op.getEffects(effects);
|
||||
|
||||
if (op->hasTrait<OpTrait::IsTerminator>()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check to see if this operation has any memory effects.
|
||||
if (effects.empty()) {
|
||||
op.emitRemark() << "operation has no memory effects";
|
||||
@@ -47,9 +51,14 @@ struct SideEffectsPass
|
||||
else if (isa<MemoryEffects::Write>(instance.getEffect()))
|
||||
diag << "'write'";
|
||||
|
||||
if (instance.getValue())
|
||||
diag << " on a value,";
|
||||
else if (SymbolRefAttr symbolRef = instance.getSymbolRef())
|
||||
if (instance.getValue()) {
|
||||
if (instance.getEffectValue<OpOperand *>())
|
||||
diag << " on a op operand,";
|
||||
else if (instance.getEffectValue<OpResult>())
|
||||
diag << " on a op result,";
|
||||
else if (instance.getEffectValue<BlockArgument>())
|
||||
diag << " on a block argument,";
|
||||
} else if (SymbolRefAttr symbolRef = instance.getSymbolRef())
|
||||
diag << " on a symbol '" << symbolRef << "',";
|
||||
|
||||
diag << " on resource '" << instance.getResource()->getName() << "'";
|
||||
|
||||
@@ -207,9 +207,8 @@ transform::TestFuseConsumerOp::apply(TransformRewriter &rewriter,
|
||||
|
||||
void transform::TestFuseConsumerOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
producesHandle(getConsumer(), effects);
|
||||
producesHandle(getFusedConsumer(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -285,9 +284,8 @@ transform::TestTileUsingForallOp::apply(TransformRewriter &rewriter,
|
||||
|
||||
void transform::TestTileUsingForallOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getTarget(), effects);
|
||||
producesHandle(getTiledOp(), effects);
|
||||
producesHandle(getLoops(), effects);
|
||||
consumesHandle(getTargetMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
@@ -375,9 +373,8 @@ transform::TestFuseUsingForallOp::apply(TransformRewriter &rewriter,
|
||||
|
||||
void transform::TestFuseUsingForallOp::getEffects(
|
||||
SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
|
||||
consumesHandle(getRootOp(), effects);
|
||||
producesHandle(getTiledOps(), effects);
|
||||
producesHandle(getLoops(), effects);
|
||||
consumesHandle(getRootOpMutable(), effects);
|
||||
producesHandle(getOperation()->getOpResults(), effects);
|
||||
modifiesPayload(effects);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,16 +25,28 @@ def SideEffectOpB : TEST_Op<"side_effect_op_b",
|
||||
[MemoryEffects<[MemWrite<CustomResource, 0>]>]>;
|
||||
|
||||
// CHECK: void SideEffectOpA::getEffects
|
||||
// CHECK: for (::mlir::Value value : getODSOperands(0))
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Read::get(), value, 0, false, ::mlir::SideEffects::DefaultResource::get());
|
||||
// CHECK: for (::mlir::Value value : getODSOperands(1))
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Write::get(), value, 1, true, ::mlir::SideEffects::DefaultResource::get());
|
||||
// CHECK: {
|
||||
// CHECK: auto valueRange = getODSOperandIndexAndLength(0);
|
||||
// CHECK: for (unsigned idx = valueRange.first; idx < valueRange.first + valueRange.second; idx++) {
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Read::get(), &getOperation()->getOpOperand(idx), 0, false, ::mlir::SideEffects::DefaultResource::get());
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: {
|
||||
// CHECK: auto valueRange = getODSOperandIndexAndLength(1);
|
||||
// CHECK: for (unsigned idx = valueRange.first; idx < valueRange.first + valueRange.second; idx++) {
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Write::get(), &getOperation()->getOpOperand(idx), 1, true, ::mlir::SideEffects::DefaultResource::get());
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Read::get(), getSymbolAttr(), 0, false, ::mlir::SideEffects::DefaultResource::get());
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Write::get(), getFlatSymbolAttr(), 0, false, ::mlir::SideEffects::DefaultResource::get());
|
||||
// CHECK: if (auto symbolRef = getOptionalSymbolAttr())
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Read::get(), symbolRef, 0, false, ::mlir::SideEffects::DefaultResource::get());
|
||||
// CHECK: for (::mlir::Value value : getODSResults(0))
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Allocate::get(), value, 0, false, CustomResource::get());
|
||||
// CHECK: {
|
||||
// CHECK: auto valueRange = getODSResultIndexAndLength(0);
|
||||
// CHECK: for (unsigned idx = valueRange.first; idx < valueRange.first + valueRange.second; idx++) {
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Allocate::get(), getOperation()->getOpResult(idx), 0, false, CustomResource::get());
|
||||
// CHECK: }
|
||||
// CHECK: }
|
||||
|
||||
// CHECK: void SideEffectOpB::getEffects
|
||||
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Write::get(), 0, false, CustomResource::get());
|
||||
|
||||
@@ -3423,12 +3423,18 @@ void OpEmitter::genSideEffectInterfaceMethods() {
|
||||
}
|
||||
} else {
|
||||
// Otherwise this is an operand/result, so we need to attach the Value.
|
||||
body << " for (::mlir::Value value : getODS"
|
||||
<< (location.kind == EffectKind::Operand ? "Operands" : "Results")
|
||||
<< "(" << location.index << "))\n "
|
||||
<< llvm::formatv(addEffectCode, effect, "value, ", stage,
|
||||
effectOnFullRegion, resource)
|
||||
.str();
|
||||
body << " {\n auto valueRange = getODS"
|
||||
<< (location.kind == EffectKind::Operand ? "Operand" : "Result")
|
||||
<< "IndexAndLength(" << location.index << ");\n"
|
||||
<< " for (unsigned idx = valueRange.first; idx < "
|
||||
"valueRange.first"
|
||||
<< " + valueRange.second; idx++) {\n "
|
||||
<< llvm::formatv(addEffectCode, effect,
|
||||
(location.kind == EffectKind::Operand
|
||||
? "&getOperation()->getOpOperand(idx), "
|
||||
: "getOperation()->getOpResult(idx), "),
|
||||
stage, effectOnFullRegion, resource)
|
||||
<< " }\n }\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user