From 2c1ae801e1b66a09a15028ae4ba614e0911eec00 Mon Sep 17 00:00:00 2001 From: donald chen Date: Wed, 19 Jun 2024 22:10:34 +0800 Subject: [PATCH] [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 --- flang/lib/Optimizer/Dialect/FIROps.cpp | 12 +- flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp | 8 +- .../Transforms/ScheduleOrderedAssignments.cpp | 16 +- flang/test/HLFIR/memory-effects.fir | 117 +++++------- .../transform/Ch2/lib/MyExtension.cpp | 2 +- .../transform/Ch3/lib/MyExtension.cpp | 2 +- .../transform/Ch4/lib/MyExtension.cpp | 5 +- .../mlir/Dialect/Affine/IR/AffineOps.h | 22 ++- .../mlir/Dialect/MemRef/IR/MemRefOps.td | 13 +- .../Transform/Interfaces/MatchInterfaces.h | 8 +- .../Interfaces/TransformInterfaces.h | 16 +- .../mlir/Interfaces/SideEffectInterfaces.h | 82 +++++++-- mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 8 +- .../TransformOps/AffineTransformOps.cpp | 6 +- .../Bufferization/IR/BufferizationOps.cpp | 2 +- .../BufferizationTransformOps.cpp | 4 +- .../Func/TransformOps/FuncTransformOps.cpp | 10 +- mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 4 +- mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp | 37 ++-- .../Linalg/TransformOps/LinalgMatchOps.cpp | 6 +- .../TransformOps/LinalgTransformOps.cpp | 78 ++++---- .../TransformOps/MemRefTransformOps.cpp | 7 +- .../NVGPU/TransformOps/NVGPUTransformOps.cpp | 4 +- .../SCF/TransformOps/SCFTransformOps.cpp | 4 +- .../lib/Dialect/Transform/IR/TransformOps.cpp | 77 ++++---- .../IRDLExtension/IRDLExtensionOps.cpp | 4 +- .../Interfaces/TransformInterfaces.cpp | 46 +++-- .../LoopExtension/LoopExtensionOps.cpp | 2 +- .../PDLExtension/PDLExtensionOps.cpp | 4 +- mlir/lib/Dialect/Vector/IR/VectorOps.cpp | 4 +- mlir/lib/Interfaces/SideEffectInterfaces.cpp | 174 ++++++++++++++++-- .../Dialect/Bufferization/side-effects.mlir | 7 +- mlir/test/IR/test-side-effects.mlir | 86 +++++---- mlir/test/lib/Dialect/Test/TestOpDefs.cpp | 51 ++++- mlir/test/lib/Dialect/Test/TestOps.td | 11 ++ .../TestTransformDialectExtension.cpp | 75 ++++---- mlir/test/lib/IR/TestSideEffects.cpp | 15 +- .../TestTilingInterfaceTransformOps.cpp | 15 +- mlir/test/mlir-tblgen/op-side-effects.td | 24 ++- mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 18 +- 40 files changed, 688 insertions(+), 398 deletions(-) diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index 7b5f4fd28489..84711c540658 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -1058,9 +1058,9 @@ void fir::BoxRankOp::getEffects( llvm::SmallVectorImpl< mlir::SideEffects::EffectInstance> &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> &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()); } diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp index bf0acc21d24b..cbe789fed116 100644 --- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp @@ -45,7 +45,7 @@ getIntrinsicEffects(mlir::Operation *self, "hlfir intrinsic ops only produce 1 result"); if (mlir::isa(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> // } - 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()); } } diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp index 2c840ce4ffe8..efe59b8ef988 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/ScheduleOrderedAssignments.cpp @@ -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(region.back().back())) - return yield.getEntity(); + return &yield.getEntityMutable(); if (auto elementalAddr = mlir::dyn_cast(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 &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(); } //===----------------------------------------------------------------------===// diff --git a/flang/test/HLFIR/memory-effects.fir b/flang/test/HLFIR/memory-effects.fir index 66659829284f..cac887ebe67d 100644 --- a/flang/test/HLFIR/memory-effects.fir +++ b/flang/test/HLFIR/memory-effects.fir @@ -3,214 +3,186 @@ func.func @concat(%arg0: !fir.ref>, %arg1: !fir.ref>) { // 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 ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %0 = hlfir.concat %arg0, %arg1 len %c30 : (!fir.ref>, !fir.ref>, index) -> (!hlfir.expr>) -// 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>>, %arg1: i32) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %all = hlfir.all %arg0 dim %arg1 : (!fir.ref>>, i32) -> !hlfir.expr> -// 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>>, %arg1: i32) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %all = hlfir.any %arg0 dim %arg1 : (!fir.ref>>, i32) -> !hlfir.expr> -// 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>>, %arg1: i32) { -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %all = hlfir.count %arg0 dim %arg1 : (!fir.ref>>, i32) -> i32 -// expected-remark@+1 {{operation has no memory effects}} return } func.func @product_no_effects(%arg0: !hlfir.expr) { // expected-remark@+1 {{operation has no memory effects}} %product = hlfir.product %arg0 : (!hlfir.expr) -> f32 -// expected-remark@+1 {{operation has no memory effects}} return } func.func @product_effects(%arg0: !fir.ref>, %arg1: i32) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %product = hlfir.product %arg0 dim %arg1 : (!fir.ref>, i32) -> !hlfir.expr<2xf32> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @set_length_read(%arg0: !fir.ref>, %arg1: index) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %0 = hlfir.set_length %arg0 len %arg1 : (!fir.ref>, index) -> !hlfir.expr> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @sum_no_effects(%arg0: !hlfir.expr) { // expected-remark@+1 {{operation has no memory effects}} %sum = hlfir.sum %arg0 : (!hlfir.expr) -> f32 -// expected-remark@+1 {{operation has no memory effects}} return } func.func @sum_effects(%arg0: !fir.ref>, %arg1: i32) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %sum = hlfir.sum %arg0 dim %arg1 : (!fir.ref>, i32) -> !hlfir.expr<2xf32> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @maxval_no_effects(%arg0: !hlfir.expr) { // expected-remark@+1 {{operation has no memory effects}} %maxval = hlfir.maxval %arg0 : (!hlfir.expr) -> f32 -// expected-remark@+1 {{operation has no memory effects}} return } func.func @maxval_effects(%arg0: !fir.ref>, %arg1: i32) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %maxval = hlfir.maxval %arg0 dim %arg1 : (!fir.ref>, i32) -> !hlfir.expr<2xf32> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @minval_no_effects(%arg0: !hlfir.expr) { // expected-remark@+1 {{operation has no memory effects}} %minval = hlfir.minval %arg0 : (!hlfir.expr) -> f32 -// expected-remark@+1 {{operation has no memory effects}} return } func.func @minval_effects(%arg0: !fir.ref>, %arg1: i32) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %minval = hlfir.minval %arg0 dim %arg1 : (!fir.ref>, i32) -> !hlfir.expr<2xf32> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @minloc_effects_simple(%arg0: !hlfir.expr) { -// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource ''}} %minloc = hlfir.minloc %arg0 : (!hlfir.expr) -> !hlfir.expr -// expected-remark@+1 {{operation has no memory effects}} return } func.func @minloc_effects(%arg0: !fir.ref>, %arg1: i32) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %minloc = hlfir.minloc %arg0 dim %arg1 : (!fir.ref>, i32) -> !hlfir.expr<2xi32> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @maxloc_effects_simple(%arg0: !hlfir.expr) { -// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource ''}} %maxloc = hlfir.maxloc %arg0 : (!hlfir.expr) -> !hlfir.expr -// expected-remark@+1 {{operation has no memory effects}} return } func.func @maxloc_effects(%arg0: !fir.ref>, %arg1: i32) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %maxloc = hlfir.maxloc %arg0 dim %arg1 : (!fir.ref>, i32) -> !hlfir.expr<2xi32> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @dot_product_no_effects(%arg0: !hlfir.expr, %arg1: !hlfir.expr) { // expected-remark@+1 {{operation has no memory effects}} %0 = hlfir.dot_product %arg0 %arg1 : (!hlfir.expr, !hlfir.expr) -> f32 -// expected-remark@+1 {{operation has no memory effects}} return } func.func @dot_product_effects(%arg0: !fir.ref>, %arg1: !fir.ref>) { // 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 ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %0 = hlfir.dot_product %arg0 %arg1 : (!fir.ref>, !fir.ref>) -> f32 -// expected-remark@+1 {{operation has no memory effects}} return } func.func @matmul_no_reads(%arg0: !hlfir.expr, %arg1: !hlfir.expr) { -// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource ''}} %0 = hlfir.matmul %arg0 %arg1 : (!hlfir.expr, !hlfir.expr) -> !hlfir.expr -// expected-remark@+1 {{operation has no memory effects}} return } func.func @matmul_reads(%arg0: !fir.ref>, %arg1: !fir.ref>) { -// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource ''}} // 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 ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %0 = hlfir.matmul %arg0 %arg1 : (!fir.ref>, !fir.ref>) -> !hlfir.expr<10x10xf32> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @transpose_no_reads(%arg0: !hlfir.expr) { -// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource ''}} %0 = hlfir.transpose %arg0 : (!hlfir.expr) -> !hlfir.expr -// expected-remark@+1 {{operation has no memory effects}} return } func.func @transpose_read(%arg0: !fir.ref>) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %0 = hlfir.transpose %arg0 : (!fir.ref>) -> !hlfir.expr<5x10xf32> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @matmul_transpose_no_reads(%arg0: !hlfir.expr, %arg1: !hlfir.expr) { -// expected-remark@+1 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+1 {{found an instance of 'allocate' on a op result, on resource ''}} %0 = hlfir.matmul_transpose %arg0 %arg1 : (!hlfir.expr, !hlfir.expr) -> !hlfir.expr -// expected-remark@+1 {{operation has no memory effects}} return } func.func @matmul_transpose_reads(%arg0: !fir.ref>, %arg1: !fir.ref>) { -// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource ''}} // 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 ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %0 = hlfir.matmul_transpose %arg0 %arg1 : (!fir.ref>, !fir.ref>) -> !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, !fir.ref, i1) // expected-remark@+1 {{found an instance of 'free' on resource ''}} hlfir.end_associate %0#1, %0#2 : !fir.ref, i1 -// expected-remark@+1 {{operation has no memory effects}} return } func.func @as_expr_read(%arg0: !fir.ref>) { -// expected-remark@+2 {{found an instance of 'allocate' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'allocate' on a op result, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %0 = hlfir.as_expr %arg0 : (!fir.ref>) -> !hlfir.expr // expected-remark@+1 {{found an instance of 'free' on resource ''}} hlfir.destroy %0 : !hlfir.expr -// expected-remark@+1 {{operation has no memory effects}} return } func.func @char_extremum(%arg0: !fir.ref>, %arg1: !fir.ref>) { -// expected-remark@+3 {{found an instance of 'allocate' on a value, on resource ''}} +// expected-remark@+3 {{found an instance of 'allocate' on a op result, on resource ''}} // 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 ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} %0 = hlfir.char_extremum min, %arg0, %arg1 : (!fir.ref>, !fir.ref>) -> !hlfir.expr> -// expected-remark@+1 {{operation has no memory effects}} return } func.func @copy_in(%box: !fir.box>, %temp: !fir.ref>>>, %is_present: i1) { // expected-remark@+3 {{found an instance of 'allocate' on resource ''}} -// expected-remark@+2 {{found an instance of 'read' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'write' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'read' on a op operand, on resource ''}} +// expected-remark@+1 {{found an instance of 'write' on a op operand, on resource ''}} %0:2 = hlfir.copy_in %box to %temp : (!fir.box>, !fir.ref>>>) -> (!fir.box>, i1) -// expected-remark@+1 {{operation has no memory effects}} return } func.func @copy_out(%box: !fir.box>, %temp: !fir.ref>>>, %was_copied: i1) { // expected-remark@+2 {{found an instance of 'free' on resource ''}} -// expected-remark@+1 {{found an instance of 'read' on a value, on resource ''}} +// expected-remark@+1 {{found an instance of 'read' on a op operand, on resource ''}} hlfir.copy_out %temp, %was_copied : (!fir.ref>>>, i1) -> () // expected-remark@+3 {{found an instance of 'free' on resource ''}} -// expected-remark@+2 {{found an instance of 'read' on a value, on resource ''}} -// expected-remark@+1 {{found an instance of 'write' on a value, on resource ''}} +// expected-remark@+2 {{found an instance of 'read' on a op operand, on resource ''}} +// expected-remark@+1 {{found an instance of 'write' on a op operand, on resource ''}} hlfir.copy_out %temp, %was_copied to %box : (!fir.ref>>>, i1, !fir.box>) -> () -// expected-remark@+1 {{operation has no memory effects}} return } diff --git a/mlir/examples/transform/Ch2/lib/MyExtension.cpp b/mlir/examples/transform/Ch2/lib/MyExtension.cpp index b2955a905b88..68d538a09801 100644 --- a/mlir/examples/transform/Ch2/lib/MyExtension.cpp +++ b/mlir/examples/transform/Ch2/lib/MyExtension.cpp @@ -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); diff --git a/mlir/examples/transform/Ch3/lib/MyExtension.cpp b/mlir/examples/transform/Ch3/lib/MyExtension.cpp index 2e4388d4cc22..f7a99423a52e 100644 --- a/mlir/examples/transform/Ch3/lib/MyExtension.cpp +++ b/mlir/examples/transform/Ch3/lib/MyExtension.cpp @@ -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); diff --git a/mlir/examples/transform/Ch4/lib/MyExtension.cpp b/mlir/examples/transform/Ch4/lib/MyExtension.cpp index 83e2dcd750bb..079073679fc4 100644 --- a/mlir/examples/transform/Ch4/lib/MyExtension.cpp +++ b/mlir/examples/transform/Ch4/lib/MyExtension.cpp @@ -160,9 +160,8 @@ mlir::transform::HasOperandSatisfyingOp::apply( void mlir::transform::HasOperandSatisfyingOp::getEffects( llvm::SmallVectorImpl &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 diff --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h index f070d0488619..5c75e102c3d4 100644 --- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h +++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h @@ -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(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(*(*this)->getInherentAttr(getSrcMapAttrStrName())); + return cast( + *(*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(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(*(*this)->getInherentAttr(getDstMapAttrStrName())); + return cast( + *(*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(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(*(*this)->getInherentAttr(getTagMapAttrStrName())); + return cast( + *(*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(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(*(*this)->getInherentAttr(getTagMapAttrStrName())); + return cast( + *(*this)->getInherentAttr(getTagMapAttrStrName())); } /// Returns the tag memref index for this DMA operation. diff --git a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td index df40e7a17a15..2ff9d612a5ef 100644 --- a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td +++ b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td @@ -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(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(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> & 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> & effects) { - effects.emplace_back(MemoryEffects::Read::get(), getTagMemRef(), + effects.emplace_back(MemoryEffects::Read::get(), &getTagMemRefMutable(), SideEffects::DefaultResource::get()); } }]; diff --git a/mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.h b/mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.h index ad3e375c326f..43abfbd6c070 100644 --- a/mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.h +++ b/mlir/include/mlir/Dialect/Transform/Interfaces/MatchInterfaces.h @@ -102,8 +102,8 @@ public: } void getEffects(SmallVectorImpl &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 &effects) { - onlyReadsHandle(this->getOperation()->getOperands(), effects); - producesHandle(this->getOperation()->getResults(), effects); + onlyReadsHandle(this->getOperation()->getOpOperands(), effects); + producesHandle(this->getOperation()->getOpResults(), effects); onlyReadsPayload(effects); } }; diff --git a/mlir/include/mlir/Dialect/Transform/Interfaces/TransformInterfaces.h b/mlir/include/mlir/Dialect/Transform/Interfaces/TransformInterfaces.h index 21795753ac5f..b8353043ee09 100644 --- a/mlir/include/mlir/Dialect/Transform/Interfaces/TransformInterfaces.h +++ b/mlir/include/mlir/Dialect/Transform/Interfaces/TransformInterfaces.h @@ -1261,11 +1261,13 @@ struct PayloadIRResource /// - consumes = Read + Free, /// - produces = Allocate + Write, /// - onlyReads = Read. -void consumesHandle(ValueRange handles, +void consumesHandle(MutableArrayRef handles, SmallVectorImpl &effects); -void producesHandle(ValueRange handles, +void producesHandle(ResultRange handles, SmallVectorImpl &effects); -void onlyReadsHandle(ValueRange handles, +void producesHandle(MutableArrayRef handles, + SmallVectorImpl &effects); +void onlyReadsHandle(MutableArrayRef handles, SmallVectorImpl &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 &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 &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(t); diff --git a/mlir/include/mlir/Interfaces/SideEffectInterfaces.h b/mlir/include/mlir/Interfaces/SideEffectInterfaces.h index ec4e36263bbe..aef7ec622fe4 100644 --- a/mlir/include/mlir/Interfaces/SideEffectInterfaces.h +++ b/mlir/include/mlir/Interfaces/SideEffectInterfaces.h @@ -145,12 +145,19 @@ public: Resource *resource = DefaultResource::get()) : effect(effect), resource(resource), stage(stage), effectOnFullRegion(effectOnFullRegion) {} - EffectInstance(EffectT *effect, Value value, + template ::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 ::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 ::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 ::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(); + if (!value || llvm::isa_and_present(value)) { + return Value(); + } + if (OpOperand *operand = llvm::dyn_cast_if_present(value)) { + return operand->get(); + } + if (OpResult result = llvm::dyn_cast_if_present(value)) { + return result; + } + return cast_if_present(value); + } + + /// Returns the OpOperand effect is applied on, or nullptr if there isn't a + /// known value being effected. + template ::value, + bool> = true> + T getEffectValue() const { + return value ? dyn_cast_if_present(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 value; + /// The Symbol, OpOperand, OpResult or BlockArgument that the effect applies + /// to. This is optionally null. + PointerUnion 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 {}; // 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 -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 +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 +bool hasSingleEffect(Operation *op, ValueTy value); + +/// Returns true if `op` has an effect of type `EffectTy`. template -bool hasEffect(Operation *op, Value value = nullptr); +bool hasEffect(Operation *op); + +/// Returns true if `op` has an effect of type `EffectTy` on `value`. +template +bool hasEffect(Operation *op, Value value); + +/// Returns true if `op` has an effect of type `EffectTy` on `value` of type +/// `ValueTy`. +template +bool hasEffect(Operation *op, ValueTy value); /// Return true if the given operation is unused, and has no side effects on /// memory that prevent erasing. diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp index 6baed92d208f..a40ffd53f9d7 100644 --- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp +++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp @@ -1707,11 +1707,11 @@ LogicalResult AffineDmaStartOp::fold(ArrayRef cstOperands, void AffineDmaStartOp::getEffects( SmallVectorImpl> &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 cstOperands, void AffineDmaWaitOp::getEffects( SmallVectorImpl> &effects) { - effects.emplace_back(MemoryEffects::Read::get(), getTagMemRef(), + effects.emplace_back(MemoryEffects::Read::get(), &getTagMemRefMutable(), SideEffects::DefaultResource::get()); } diff --git a/mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp b/mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp index e8bfd4421f5c..6457655cfe41 100644 --- a/mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp +++ b/mlir/lib/Dialect/Affine/TransformOps/AffineTransformOps.cpp @@ -142,9 +142,9 @@ SimplifyBoundedAffineOpsOp::apply(transform::TransformRewriter &rewriter, void SimplifyBoundedAffineOpsOp::getEffects( SmallVectorImpl &effects) { - consumesHandle(getTarget(), effects); - for (Value v : getBoundedValues()) - onlyReadsHandle(v, effects); + consumesHandle(getTargetMutable(), effects); + for (OpOperand &operand : getBoundedValuesMutable()) + onlyReadsHandle(operand, effects); modifiesPayload(effects); } diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp b/mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp index 3b7b412842bf..04a8ff30ee94 100644 --- a/mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp +++ b/mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp @@ -728,7 +728,7 @@ void MaterializeInDestinationOp::getEffects( SmallVectorImpl> &effects) { if (isa(getDest().getType())) - effects.emplace_back(MemoryEffects::Write::get(), getDest(), + effects.emplace_back(MemoryEffects::Write::get(), &getDestMutable(), SideEffects::DefaultResource::get()); } diff --git a/mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp b/mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp index cbb36639a338..e10c7bd914e3 100644 --- a/mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp +++ b/mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp @@ -36,7 +36,7 @@ DiagnosedSilenceableFailure transform::BufferLoopHoistingOp::applyToOne( void transform::BufferLoopHoistingOp::getEffects( SmallVectorImpl &effects) { - onlyReadsHandle(getTarget(), effects); + onlyReadsHandle(getTargetMutable(), effects); modifiesPayload(effects); } @@ -110,7 +110,7 @@ transform::OneShotBufferizeOp::apply(transform::TransformRewriter &rewriter, void transform::EliminateEmptyTensorsOp::getEffects( SmallVectorImpl &effects) { - onlyReadsHandle(getTarget(), effects); + onlyReadsHandle(getTargetMutable(), effects); modifiesPayload(effects); } diff --git a/mlir/lib/Dialect/Func/TransformOps/FuncTransformOps.cpp b/mlir/lib/Dialect/Func/TransformOps/FuncTransformOps.cpp index 1e262736226f..b632b25d0cc6 100644 --- a/mlir/lib/Dialect/Func/TransformOps/FuncTransformOps.cpp +++ b/mlir/lib/Dialect/Func/TransformOps/FuncTransformOps.cpp @@ -216,14 +216,14 @@ LogicalResult transform::CastAndCallOp::verify() { void transform::CastAndCallOp::getEffects( SmallVectorImpl &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); } diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp index fff6d4d75781..d1280aceeb7b 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp @@ -825,7 +825,7 @@ Type GEPOp::getResultPtrElementType() { void LoadOp::getEffects( SmallVectorImpl> &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> &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 diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp index b79afebfa815..7b6256050e77 100644 --- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp +++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp @@ -1123,28 +1123,23 @@ static void getGenericEffectsImpl( SmallVectorImpl> &effects, LinalgOp linalgOp) { - SmallVector inputOperands = linalgOp.getDpsInputs(); - for (auto [index, operand] : llvm::enumerate(inputOperands)) { + for (auto [index, operand] : llvm::enumerate(linalgOp.getDpsInputs())) { if (!llvm::isa(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(operand.getType())) + for (OpOperand &operand : linalgOp.getDpsInitsMutable()) { + if (!llvm::isa(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> &effects) { - for (Value operand : getDpsInputs()) { + for (auto [index, operand] : llvm::enumerate(getDpsInputs())) { if (!llvm::isa(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(operand.getType())) + + for (OpOperand &operand : getDpsInitsMutable()) { + if (!llvm::isa(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()); } diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp index 768df0953fc5..be4ab361083b 100644 --- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp +++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp @@ -115,9 +115,9 @@ DiagnosedSilenceableFailure transform::MatchStructuredOp::matchOperation( void transform::MatchStructuredOp::getEffects( SmallVectorImpl &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 &effects) { - onlyReadsHandle(getHandles(), effects); + onlyReadsHandle(getHandlesMutable(), effects); onlyReadsPayload(effects); } diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp index 2807b3ce42ab..bc02788f9c44 100644 --- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp +++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp @@ -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 &effects) { - onlyReadsHandle(getTarget(), effects); + onlyReadsHandle(getTargetMutable(), effects); modifiesPayload(effects); } @@ -1040,9 +1039,9 @@ transform::FuseIntoContainingOp::apply(transform::TransformRewriter &rewriter, void transform::FuseIntoContainingOp::getEffects( SmallVectorImpl &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 &effects) { - onlyReadsHandle(getTarget(), effects); - producesHandle(getResults(), effects); + onlyReadsHandle(getTargetMutable(), effects); + producesHandle(getOperation()->getOpResults(), effects); if (isa(getLowSize().getType())) onlyReadsPayload(effects); else @@ -1478,9 +1477,9 @@ transform::PackOp::apply(transform::TransformRewriter &rewriter, void transform::PackOp::getEffects( SmallVectorImpl &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 PackGreedilyOp::getMixedMatmulPackedSizes() { void transform::PackGreedilyOp::getEffects( SmallVectorImpl &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 &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 &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 &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 &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 transform::TileUsingForOp::getMixedSizes() { void transform::TileUsingForOp::getEffects( SmallVectorImpl &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 &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 &effects) { - consumesHandle(getTarget(), effects); - onlyReadsHandle(getVectorSizes(), effects); + consumesHandle(getTargetMutable(), effects); + onlyReadsHandle(getVectorSizesMutable(), effects); modifiesPayload(effects); } diff --git a/mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp b/mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp index 3c9475c2d143..8469e84c668c 100644 --- a/mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp +++ b/mlir/lib/Dialect/MemRef/TransformOps/MemRefTransformOps.cpp @@ -181,9 +181,8 @@ transform::MemRefAllocaToGlobalOp::apply(transform::TransformRewriter &rewriter, void transform::MemRefAllocaToGlobalOp::getEffects( SmallVectorImpl &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 &effects) { - transform::onlyReadsHandle(getTarget(), effects); + transform::onlyReadsHandle(getTargetMutable(), effects); transform::modifiesPayload(effects); } void transform::MemRefEraseDeadAllocAndStoresOp::build(OpBuilder &builder, diff --git a/mlir/lib/Dialect/NVGPU/TransformOps/NVGPUTransformOps.cpp b/mlir/lib/Dialect/NVGPU/TransformOps/NVGPUTransformOps.cpp index 4e256aea0be3..7d3d868b326c 100644 --- a/mlir/lib/Dialect/NVGPU/TransformOps/NVGPUTransformOps.cpp +++ b/mlir/lib/Dialect/NVGPU/TransformOps/NVGPUTransformOps.cpp @@ -134,8 +134,8 @@ transform::ApplyNVGPUToNVVMConversionPatternsOp::verifyTypeConverter( void transform::CreateAsyncGroupsOp::getEffects( SmallVectorImpl &effects) { - transform::consumesHandle(getTarget(), effects); - transform::producesHandle(getResult(), effects); + transform::consumesHandle(getTargetMutable(), effects); + transform::producesHandle(getOperation()->getOpResults(), effects); transform::modifiesPayload(effects); } diff --git a/mlir/lib/Dialect/SCF/TransformOps/SCFTransformOps.cpp b/mlir/lib/Dialect/SCF/TransformOps/SCFTransformOps.cpp index 15b8aca5e267..6919de393b66 100644 --- a/mlir/lib/Dialect/SCF/TransformOps/SCFTransformOps.cpp +++ b/mlir/lib/Dialect/SCF/TransformOps/SCFTransformOps.cpp @@ -330,7 +330,7 @@ DiagnosedSilenceableFailure transform::LoopPromoteIfOneIterationOp::applyToOne( void transform::LoopPromoteIfOneIterationOp::getEffects( SmallVectorImpl &effects) { - consumesHandle(getTarget(), effects); + consumesHandle(getTargetMutable(), effects); modifiesPayload(effects); } @@ -415,7 +415,7 @@ DiagnosedSilenceableFailure transform::TakeAssumedBranchOp::applyToOne( void transform::TakeAssumedBranchOp::getEffects( SmallVectorImpl &effects) { - onlyReadsHandle(getTarget(), effects); + onlyReadsHandle(getTargetMutable(), effects); modifiesPayload(effects); } diff --git a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp index 1a7ec030f0eb..1efe708a5e34 100644 --- a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp +++ b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp @@ -211,8 +211,8 @@ transform::AlternativesOp::apply(transform::TransformRewriter &rewriter, void transform::AlternativesOp::getEffects( SmallVectorImpl &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &effects) { - transform::onlyReadsHandle(getTarget(), effects); + transform::onlyReadsHandle(getTargetMutable(), effects); } //===----------------------------------------------------------------------===// @@ -2839,5 +2840,5 @@ void transform::VerifyOp::getEffects( void transform::YieldOp::getEffects( SmallVectorImpl &effects) { - onlyReadsHandle(getOperands(), effects); + onlyReadsHandle(getOperandsMutable(), effects); } diff --git a/mlir/lib/Dialect/Transform/IRDLExtension/IRDLExtensionOps.cpp b/mlir/lib/Dialect/Transform/IRDLExtension/IRDLExtensionOps.cpp index 9cc579e65edf..93b0bc591ca0 100644 --- a/mlir/lib/Dialect/Transform/IRDLExtension/IRDLExtensionOps.cpp +++ b/mlir/lib/Dialect/Transform/IRDLExtension/IRDLExtensionOps.cpp @@ -50,8 +50,8 @@ IRDLCollectMatchingOp::apply(TransformRewriter &rewriter, void IRDLCollectMatchingOp::getEffects( SmallVectorImpl &effects) { - onlyReadsHandle(getRoot(), effects); - producesHandle(getMatched(), effects); + onlyReadsHandle(getRootMutable(), effects); + producesHandle(getOperation()->getOpResults(), effects); onlyReadsPayload(effects); } diff --git a/mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp b/mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp index b6a35e23a5d1..ff02cb2372b4 100644 --- a/mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp +++ b/mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp @@ -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 &effects) { SmallVector 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 operands, SmallVectorImpl &effects) { for (Operation &op : block) { auto iface = dyn_cast(&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 nestedEffects; @@ -1635,8 +1636,8 @@ remapArgumentEffects(Block &block, ValueRange operands, void transform::detail::getPotentialTopLevelEffects( Operation *operation, Value root, Block &body, SmallVectorImpl &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 &effects) { producesHandle(op->getResults(), effects); bool hasPayloadOperands = false; - for (Value operand : op->getOperands()) { + for (OpOperand &operand : op->getOpOperands()) { onlyReadsHandle(operand, effects); if (llvm::isa(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 handles, SmallVectorImpl &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 &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 handles, + SmallVectorImpl &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 handles, SmallVectorImpl &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()); } } diff --git a/mlir/lib/Dialect/Transform/LoopExtension/LoopExtensionOps.cpp b/mlir/lib/Dialect/Transform/LoopExtension/LoopExtensionOps.cpp index c992fd15946f..34d6221d15fb 100644 --- a/mlir/lib/Dialect/Transform/LoopExtension/LoopExtensionOps.cpp +++ b/mlir/lib/Dialect/Transform/LoopExtension/LoopExtensionOps.cpp @@ -31,6 +31,6 @@ DiagnosedSilenceableFailure transform::HoistLoopInvariantSubsetsOp::applyToOne( void transform::HoistLoopInvariantSubsetsOp::getEffects( SmallVectorImpl &effects) { - transform::onlyReadsHandle(getTarget(), effects); + transform::onlyReadsHandle(getTargetMutable(), effects); transform::modifiesPayload(effects); } diff --git a/mlir/lib/Dialect/Transform/PDLExtension/PDLExtensionOps.cpp b/mlir/lib/Dialect/Transform/PDLExtension/PDLExtensionOps.cpp index 5585afc1caaf..85f61245eb73 100644 --- a/mlir/lib/Dialect/Transform/PDLExtension/PDLExtensionOps.cpp +++ b/mlir/lib/Dialect/Transform/PDLExtension/PDLExtensionOps.cpp @@ -158,8 +158,8 @@ transform::PDLMatchOp::apply(transform::TransformRewriter &rewriter, void transform::PDLMatchOp::getEffects( SmallVectorImpl &effects) { - onlyReadsHandle(getRoot(), effects); - producesHandle(getMatched(), effects); + onlyReadsHandle(getRootMutable(), effects); + producesHandle(getOperation()->getOpResults(), effects); onlyReadsPayload(effects); } diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp index 89805d90ea1b..6734c80f2760 100644 --- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp +++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp @@ -4232,7 +4232,7 @@ void TransferReadOp::getEffects( SmallVectorImpl> &effects) { if (llvm::isa(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> &effects) { if (llvm::isa(getShapedType())) - effects.emplace_back(MemoryEffects::Write::get(), getSource(), + effects.emplace_back(MemoryEffects::Write::get(), &getSourceMutable(), SideEffects::DefaultResource::get()); } diff --git a/mlir/lib/Interfaces/SideEffectInterfaces.cpp b/mlir/lib/Interfaces/SideEffectInterfaces.cpp index 967225333ae0..c9feb001a198 100644 --- a/mlir/lib/Interfaces/SideEffectInterfaces.cpp +++ b/mlir/lib/Interfaces/SideEffectInterfaces.cpp @@ -103,6 +103,28 @@ static bool wouldOpBeTriviallyDeadImpl(Operation *rootOp) { return true; } +template +bool mlir::hasSingleEffect(Operation *op) { + auto memOp = dyn_cast(op); + if (!memOp) + return false; + SmallVector, 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(effect.getEffect()); + if (!hasSingleEffectOnVal) + return false; + } + return hasSingleEffectOnVal; +} +template bool mlir::hasSingleEffect(Operation *); +template bool mlir::hasSingleEffect(Operation *); +template bool mlir::hasSingleEffect(Operation *); +template bool mlir::hasSingleEffect(Operation *); + template bool mlir::hasSingleEffect(Operation *op, Value value) { auto memOp = dyn_cast(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(effect.getEffect()); if (!hasSingleEffectOnVal) @@ -125,10 +146,84 @@ bool mlir::hasSingleEffect(Operation *op, Value value) { } template bool mlir::hasSingleEffect(Operation *, - Value); -template bool mlir::hasSingleEffect(Operation *, Value); -template bool mlir::hasSingleEffect(Operation *, Value); -template bool mlir::hasSingleEffect(Operation *, Value); + Value value); +template bool mlir::hasSingleEffect(Operation *, + Value value); +template bool mlir::hasSingleEffect(Operation *, + Value value); +template bool mlir::hasSingleEffect(Operation *, + Value value); + +template +bool mlir::hasSingleEffect(Operation *op, ValueTy value) { + auto memOp = dyn_cast(op); + if (!memOp) + return false; + SmallVector, 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() != value) + continue; + hasSingleEffectOnVal = isa(effect.getEffect()); + if (!hasSingleEffectOnVal) + return false; + } + return hasSingleEffectOnVal; +} + +template bool +mlir::hasSingleEffect(Operation *, + OpOperand *); +template bool +mlir::hasSingleEffect(Operation *, + OpOperand *); +template bool +mlir::hasSingleEffect(Operation *, + OpOperand *); +template bool +mlir::hasSingleEffect(Operation *, + OpOperand *); +template bool +mlir::hasSingleEffect(Operation *, OpResult); +template bool mlir::hasSingleEffect(Operation *, + OpResult); +template bool mlir::hasSingleEffect(Operation *, + OpResult); +template bool mlir::hasSingleEffect(Operation *, + OpResult); +template bool +mlir::hasSingleEffect(Operation *, + BlockArgument); +template bool +mlir::hasSingleEffect(Operation *, + BlockArgument); +template bool +mlir::hasSingleEffect(Operation *, + BlockArgument); +template bool +mlir::hasSingleEffect(Operation *, + BlockArgument); + +template +bool mlir::hasEffect(Operation *op) { + auto memOp = dyn_cast(op); + if (!memOp) + return false; + SmallVector, 4> effects; + memOp.getEffects(effects); + return llvm::any_of(effects, [&](MemoryEffects::EffectInstance &effect) { + return isa(effect.getEffect()); + }); +} +template bool mlir::hasEffect(Operation *); +template bool mlir::hasEffect(Operation *); +template bool mlir::hasEffect(Operation *); +template bool mlir::hasEffect(Operation *); +template bool +mlir::hasEffect(Operation *); template bool mlir::hasEffect(Operation *op, Value value) { @@ -138,17 +233,70 @@ bool mlir::hasEffect(Operation *op, Value value) { SmallVector, 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(effect.getEffect()); }); } -template bool mlir::hasEffect(Operation *, Value); -template bool mlir::hasEffect(Operation *, Value); -template bool mlir::hasEffect(Operation *, Value); -template bool mlir::hasEffect(Operation *, Value); +template bool mlir::hasEffect(Operation *, + Value value); +template bool mlir::hasEffect(Operation *, Value value); +template bool mlir::hasEffect(Operation *, Value value); +template bool mlir::hasEffect(Operation *, Value value); template bool -mlir::hasEffect(Operation *, Value); +mlir::hasEffect(Operation *, + Value value); + +template +bool mlir::hasEffect(Operation *op, ValueTy value) { + auto memOp = dyn_cast(op); + if (!memOp) + return false; + SmallVector, 4> effects; + memOp.getEffects(effects); + return llvm::any_of(effects, [&](MemoryEffects::EffectInstance &effect) { + if (effect.getEffectValue() != value) + return false; + return isa(effect.getEffect()); + }); +} +template bool +mlir::hasEffect(Operation *, OpOperand *); +template bool mlir::hasEffect(Operation *, + OpOperand *); +template bool mlir::hasEffect(Operation *, + OpOperand *); +template bool mlir::hasEffect(Operation *, + OpOperand *); +template bool +mlir::hasEffect( + Operation *, OpOperand *); + +template bool mlir::hasEffect(Operation *, + OpResult); +template bool mlir::hasEffect(Operation *, + OpResult); +template bool mlir::hasEffect(Operation *, + OpResult); +template bool mlir::hasEffect(Operation *, + OpResult); +template bool +mlir::hasEffect( + Operation *, OpResult); + +template bool +mlir::hasEffect(Operation *, + BlockArgument); +template bool +mlir::hasEffect(Operation *, BlockArgument); +template bool +mlir::hasEffect(Operation *, BlockArgument); +template bool +mlir::hasEffect(Operation *, + BlockArgument); +template bool +mlir::hasEffect( + Operation *, BlockArgument); bool mlir::wouldOpBeTriviallyDead(Operation *op) { if (op->mightHaveTrait()) diff --git a/mlir/test/Dialect/Bufferization/side-effects.mlir b/mlir/test/Dialect/Bufferization/side-effects.mlir index 680219a48b45..841490e9f323 100644 --- a/mlir/test/Dialect/Bufferization/side-effects.mlir +++ b/mlir/test/Dialect/Bufferization/side-effects.mlir @@ -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 ''}} - // expected-remark @below {{found an instance of 'write' on a value, on resource ''}} - // expected-remark @below {{found an instance of 'allocate' on a value, on resource ''}} + // expected-remark @below {{found an instance of 'read' on a op operand, on resource ''}} + // expected-remark @below {{found an instance of 'write' on a op result, on resource ''}} + // expected-remark @below {{found an instance of 'allocate' on a op result, on resource ''}} %0 = bufferization.clone %arg0 : memref<2xi32> to memref<2xi32> - // expected-remark @below {{operation has no memory effects}} return %0 : memref<2xi32> } diff --git a/mlir/test/IR/test-side-effects.mlir b/mlir/test/IR/test-side-effects.mlir index 947faff99d26..efce4856041a 100644 --- a/mlir/test/IR/test-side-effects.mlir +++ b/mlir/test/IR/test-side-effects.mlir @@ -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 ''}} + // expected-remark@+1 {{found an instance of 'free' on resource ''}} + %1 = "test.side_effect_op"() {effects = [ + {effect="read"}, {effect="free"} + ]} : () -> i32 + + // expected-remark@+1 {{found an instance of 'write' on resource ''}} + %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 ''}} + %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.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 ''}} -// expected-remark@+1 {{found an instance of 'free' on resource ''}} -%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 ''}} + %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 ''}} -%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 ''}} + %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 ''}} -%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 ''}} + %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.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 +} diff --git a/mlir/test/lib/Dialect/Test/TestOpDefs.cpp b/mlir/test/lib/Dialect/Test/TestOpDefs.cpp index b058a8e1abbc..9b36748b54db 100644 --- a/mlir/test/lib/Dialect/Test/TestOpDefs.cpp +++ b/mlir/test/lib/Dialect/Test/TestOpDefs.cpp @@ -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(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(ref), resource); else @@ -363,6 +361,51 @@ void SideEffectOp::getEffects( testSideEffectOpGetEffect(getOperation(), effects); } +void SideEffectWithRegionOp::getEffects( + SmallVectorImpl &effects) { + // Check for an effects attribute on the op instance. + ArrayAttr effectsAttr = (*this)->getAttrOfType("effects"); + if (!effectsAttr) + return; + + for (Attribute element : effectsAttr) { + DictionaryAttr effectElement = cast(element); + + // Get the specific memory effect. + MemoryEffects::Effect *effect = + StringSwitch( + cast(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(ref), resource); + else + effects.emplace_back(effect, resource); + } +} + +void SideEffectWithRegionOp::getEffects( + SmallVectorImpl &effects) { + testSideEffectOpGetEffect(getOperation(), effects); +} + //===----------------------------------------------------------------------===// // StringAttrPrettyNameOp //===----------------------------------------------------------------------===// @@ -1027,7 +1070,7 @@ void ReadBufferOp::getEffects( SmallVectorImpl> &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(), diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index 9d7e0a7928ab..cce926d2cf63 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -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, + DeclareOpInterfaceMethods]> { + 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 //===----------------------------------------------------------------------===// diff --git a/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp b/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp index 2b39668035bc..b8a4b9470d73 100644 --- a/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp +++ b/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp @@ -128,8 +128,8 @@ mlir::test::TestProduceSelfHandleOrForwardOperandOp::apply( void mlir::test::TestProduceSelfHandleOrForwardOperandOp::getEffects( SmallVectorImpl &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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(getOut()), + transform::TransformMappingResource::get()); + } if (getModifiesPayload()) transform::modifiesPayload(effects); @@ -625,14 +627,13 @@ DiagnosedSilenceableFailure mlir::test::TestRequiredMemoryEffectsOp::apply( void mlir::test::TestTrackedRewriteOp::getEffects( SmallVectorImpl &effects) { - transform::onlyReadsHandle(getIn(), effects); + transform::onlyReadsHandle(getInMutable(), effects); transform::modifiesPayload(effects); } void mlir::test::TestDummyPayloadOp::getEffects( SmallVectorImpl &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 &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 &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 &effects) { - transform::onlyReadsHandle(getTarget(), effects); + transform::onlyReadsHandle(getTargetMutable(), effects); transform::modifiesPayload(effects); } diff --git a/mlir/test/lib/IR/TestSideEffects.cpp b/mlir/test/lib/IR/TestSideEffects.cpp index 8e13dd975139..7e01509d5568 100644 --- a/mlir/test/lib/IR/TestSideEffects.cpp +++ b/mlir/test/lib/IR/TestSideEffects.cpp @@ -29,6 +29,10 @@ struct SideEffectsPass effects.clear(); op.getEffects(effects); + if (op->hasTrait()) { + 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(instance.getEffect())) diag << "'write'"; - if (instance.getValue()) - diag << " on a value,"; - else if (SymbolRefAttr symbolRef = instance.getSymbolRef()) + if (instance.getValue()) { + if (instance.getEffectValue()) + diag << " on a op operand,"; + else if (instance.getEffectValue()) + diag << " on a op result,"; + else if (instance.getEffectValue()) + diag << " on a block argument,"; + } else if (SymbolRefAttr symbolRef = instance.getSymbolRef()) diag << " on a symbol '" << symbolRef << "',"; diag << " on resource '" << instance.getResource()->getName() << "'"; diff --git a/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp b/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp index 833fb3cc65b8..8f206d907727 100644 --- a/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp +++ b/mlir/test/lib/Interfaces/TilingInterface/TestTilingInterfaceTransformOps.cpp @@ -207,9 +207,8 @@ transform::TestFuseConsumerOp::apply(TransformRewriter &rewriter, void transform::TestFuseConsumerOp::getEffects( SmallVectorImpl &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 &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 &effects) { - consumesHandle(getRootOp(), effects); - producesHandle(getTiledOps(), effects); - producesHandle(getLoops(), effects); + consumesHandle(getRootOpMutable(), effects); + producesHandle(getOperation()->getOpResults(), effects); modifiesPayload(effects); } diff --git a/mlir/test/mlir-tblgen/op-side-effects.td b/mlir/test/mlir-tblgen/op-side-effects.td index 09612db90589..f08b373605f3 100644 --- a/mlir/test/mlir-tblgen/op-side-effects.td +++ b/mlir/test/mlir-tblgen/op-side-effects.td @@ -25,16 +25,28 @@ def SideEffectOpB : TEST_Op<"side_effect_op_b", [MemoryEffects<[MemWrite]>]>; // 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()); diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp index adda7ce6fc6c..3146e65a1d96 100644 --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -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"; } } }