[Mlir-commits] [mlir] b010a18 - [mlir][ODS] Allow parameters on side-effect resources (#213792)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Aug 3 16:50:52 PDT 2026
Author: Jeff Niu
Date: 2026-08-03T16:50:47-07:00
New Revision: b010a18d2b648cab83c83967ff26b8fde11acdc6
URL: https://github.com/llvm/llvm-project/commit/b010a18d2b648cab83c83967ff26b8fde11acdc6
DIFF: https://github.com/llvm/llvm-project/commit/b010a18d2b648cab83c83967ff26b8fde11acdc6.diff
LOG: [mlir][ODS] Allow parameters on side-effect resources (#213792)
Assisted-by: OpenAI Codex
---------
Co-authored-by: jeffniu-openai <jeffniu at openai.com>
Added:
Modified:
mlir/docs/Rationale/SideEffectsAndSpeculation.md
mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td
mlir/include/mlir/TableGen/SideEffects.h
mlir/lib/TableGen/SideEffects.cpp
mlir/test/IR/test-side-effects.mlir
mlir/test/lib/Dialect/Test/TestOps.td
mlir/test/lib/IR/TestSideEffects.cpp
mlir/test/mlir-tblgen/op-side-effects.td
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
Removed:
################################################################################
diff --git a/mlir/docs/Rationale/SideEffectsAndSpeculation.md b/mlir/docs/Rationale/SideEffectsAndSpeculation.md
index f2e9e12f6cfc9..b17c04359b940 100644
--- a/mlir/docs/Rationale/SideEffectsAndSpeculation.md
+++ b/mlir/docs/Rationale/SideEffectsAndSpeculation.md
@@ -86,6 +86,10 @@ effects on it can alias pointer-based memory; non-addressable resources (e.g.
runtime state) do not alias with any value-based memory location. The
canonical definition and API live in `mlir/Interfaces/SideEffectInterfaces.h`.
+Resources can attach arbitrary attributes to their effect instances. These
+attributes provide additional metadata about memory effects and can be used,
+for example, to distinguish how a resource is accessed.
+
**Scope and limitations.** This mechanism is deliberately *not* intended for
fine-grained regions with specific addresses or sizes, or for alias classes /
offset-based disambiguation. Those concerns are out of scope for the resource
diff --git a/mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td b/mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td
index 043829c24fda8..c1b7372b75a67 100644
--- a/mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td
+++ b/mlir/include/mlir/Interfaces/SideEffectInterfaceBase.td
@@ -22,9 +22,12 @@ include "mlir/IR/OpBase.td"
//===----------------------------------------------------------------------===//
// A generic resource that can be attached to a general base side effect.
-class Resource<string resourceName> {
+class Resource<string resourceName, code resourceParameters = [{}]> {
/// The resource that the associated effect is being applied to.
string name = resourceName;
+
+ /// The optional effect parameters attribute.
+ code parameters = resourceParameters;
}
// An intrinsic resource that lives in the ::mlir::SideEffects namespace.
@@ -177,6 +180,9 @@ class SideEffect<EffectOpInterfaceBase interface, string effectName,
/// The resource that the effect is being applied to.
string resource = resourceReference.name;
+ /// The optional effect parameters attribute.
+ code parameters = resourceReference.parameters;
+
/// The stage of side effects, we use it to describe the sequence in which
/// effects occur.
int stage = effectStage;
diff --git a/mlir/include/mlir/TableGen/SideEffects.h b/mlir/include/mlir/TableGen/SideEffects.h
index 5a9a34d4e427c..14faae457f272 100644
--- a/mlir/include/mlir/TableGen/SideEffects.h
+++ b/mlir/include/mlir/TableGen/SideEffects.h
@@ -35,6 +35,9 @@ class SideEffect : public Operator::VariableDecorator {
// Return the name of the resource class.
StringRef getResource() const;
+ // Return the effect parameters attribute.
+ StringRef getParameters() const;
+
// Return the stage of the effect happen.
int64_t getStage() const;
diff --git a/mlir/lib/TableGen/SideEffects.cpp b/mlir/lib/TableGen/SideEffects.cpp
index 55ad59d3d0d01..72595ee7f4794 100644
--- a/mlir/lib/TableGen/SideEffects.cpp
+++ b/mlir/lib/TableGen/SideEffects.cpp
@@ -36,6 +36,10 @@ StringRef SideEffect::getResource() const {
return def->getValueAsString("resource");
}
+StringRef SideEffect::getParameters() const {
+ return def->getValueAsString("parameters");
+}
+
int64_t SideEffect::getStage() const { return def->getValueAsInt("stage"); }
bool SideEffect::getEffectOnfullRegion() const {
diff --git a/mlir/test/IR/test-side-effects.mlir b/mlir/test/IR/test-side-effects.mlir
index f66937a9ec943..bc8801c8302dd 100644
--- a/mlir/test/IR/test-side-effects.mlir
+++ b/mlir/test/IR/test-side-effects.mlir
@@ -67,3 +67,9 @@ func.func @side_effect(%arg : index) {
func.return
}
+
+func.func @parameterized_side_effect(%arg : memref<4xf32>) {
+ // expected-remark at +1 {{found an instance of 'read' on op operand 0, on resource '<Test>' with parameters "test parameter"}}
+ "test.op_with_parameterized_effects"(%arg) : (memref<4xf32>) -> ()
+ func.return
+}
diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td
index db55b90c294e1..3b69e474d76ad 100644
--- a/mlir/test/lib/Dialect/Test/TestOps.td
+++ b/mlir/test/lib/Dialect/Test/TestOps.td
@@ -3313,6 +3313,8 @@ def TestDefaultAttrPrintOp : TEST_Op<"default_value_print"> {
//===----------------------------------------------------------------------===//
def TestResource : Resource<"TestResource">;
+def ParameterizedTestResource : Resource<"TestResource",
+ [{::mlir::StringAttr::get(getContext(), "test parameter")}]>;
def TestEffectsOpA : TEST_Op<"op_with_effects_a"> {
let arguments = (ins
@@ -3328,6 +3330,11 @@ def TestEffectsOpA : TEST_Op<"op_with_effects_a"> {
def TestEffectsOpB : TEST_Op<"op_with_effects_b",
[MemoryEffects<[MemWrite<TestResource, 0>]>]>;
+def TestParameterizedEffectsOp : TEST_Op<"op_with_parameterized_effects"> {
+ let arguments =
+ (ins Arg<AnyMemRef, "", [MemRead<ParameterizedTestResource>]>:$input);
+}
+
def TestEffectsRead : TEST_Op<"op_with_memread",
[MemoryEffects<[MemRead]>]> {
let results = (outs AnyInteger);
diff --git a/mlir/test/lib/IR/TestSideEffects.cpp b/mlir/test/lib/IR/TestSideEffects.cpp
index 000e7c204fd5f..7c6132c51f310 100644
--- a/mlir/test/lib/IR/TestSideEffects.cpp
+++ b/mlir/test/lib/IR/TestSideEffects.cpp
@@ -62,6 +62,8 @@ struct SideEffectsPass
diag << " on a symbol '" << symbolRef << "',";
diag << " on resource '" << instance.getResource()->getName() << "'";
+ if (Attribute parameters = instance.getParameters())
+ diag << " with parameters " << parameters;
}
});
diff --git a/mlir/test/mlir-tblgen/op-side-effects.td b/mlir/test/mlir-tblgen/op-side-effects.td
index f08b373605f33..ca24c7f9cf520 100644
--- a/mlir/test/mlir-tblgen/op-side-effects.td
+++ b/mlir/test/mlir-tblgen/op-side-effects.td
@@ -9,6 +9,8 @@ class TEST_Op<string mnemonic, list<Trait> traits = []> :
Op<TEST_Dialect, mnemonic, traits>;
def CustomResource : Resource<"CustomResource">;
+def ParameterizedResource : Resource<"CustomResource",
+ [{::mlir::StringAttr::get(getContext(), "parameter")}]>;
def SideEffectOpA : TEST_Op<"side_effect_op_a"> {
let arguments = (ins
@@ -24,6 +26,13 @@ def SideEffectOpA : TEST_Op<"side_effect_op_a"> {
def SideEffectOpB : TEST_Op<"side_effect_op_b",
[MemoryEffects<[MemWrite<CustomResource, 0>]>]>;
+def SideEffectOpC : TEST_Op<"side_effect_op_c"> {
+ let arguments = (ins Arg<AnyMemRef, "", [MemRead<ParameterizedResource>]>);
+}
+
+def SideEffectOpD : TEST_Op<"side_effect_op_d",
+ [MemoryEffects<[MemWrite<ParameterizedResource>]>]>;
+
// CHECK: void SideEffectOpA::getEffects
// CHECK: {
// CHECK: auto valueRange = getODSOperandIndexAndLength(0);
@@ -50,3 +59,9 @@ def SideEffectOpB : TEST_Op<"side_effect_op_b",
// CHECK: void SideEffectOpB::getEffects
// CHECK: effects.emplace_back(::mlir::MemoryEffects::Write::get(), 0, false, CustomResource::get());
+
+// CHECK-LABEL: void SideEffectOpC::getEffects
+// CHECK: "parameter"), 0, false, CustomResource::get());
+
+// CHECK-LABEL: void SideEffectOpD::getEffects
+// CHECK: "parameter"), 0, false, CustomResource::get());
diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index 4614459abb2b6..d7c119a31795a 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -3678,11 +3678,12 @@ void OpEmitter::genSideEffectInterfaceMethods() {
// The code used to add an effect instance.
// {0}: The effect class.
// {1}: Optional value or symbol reference.
- // {2}: The side effect stage.
- // {3}: Does this side effect act on every single value of resource.
- // {4}: The resource class.
+ // {2}: Optional parameters attribute.
+ // {3}: The side effect stage.
+ // {4}: Does this side effect act on every single value of resource.
+ // {5}: The resource class.
const char *addEffectCode =
- " effects.emplace_back({0}::get(), {1}{2}, {3}, {4}::get());\n";
+ " effects.emplace_back({0}::get(), {1}{2}{3}, {4}, {5}::get());\n";
for (auto &it : interfaceEffects) {
// Generate the 'getEffects' method.
@@ -3699,11 +3700,14 @@ void OpEmitter::genSideEffectInterfaceMethods() {
for (auto &location : it.second) {
StringRef effect = location.effect.getName();
StringRef resource = location.effect.getResource();
+ std::string parameters = location.effect.getParameters().str();
+ if (!parameters.empty())
+ parameters += ", ";
int stage = (int)location.effect.getStage();
bool effectOnFullRegion = (int)location.effect.getEffectOnfullRegion();
if (location.kind == EffectKind::Static) {
// A static instance has no attached value.
- body << llvm::formatv(addEffectCode, effect, "", stage,
+ body << llvm::formatv(addEffectCode, effect, "", parameters, stage,
effectOnFullRegion, resource)
.str();
} else if (location.kind == EffectKind::Symbol) {
@@ -3712,12 +3716,12 @@ void OpEmitter::genSideEffectInterfaceMethods() {
std::string argName = op.getGetterName(attr->name);
if (attr->attr.isOptional()) {
body << " if (auto symbolRef = " << argName << "Attr())\n "
- << llvm::formatv(addEffectCode, effect, "symbolRef, ", stage,
- effectOnFullRegion, resource)
+ << llvm::formatv(addEffectCode, effect, "symbolRef, ",
+ parameters, stage, effectOnFullRegion, resource)
.str();
} else {
body << llvm::formatv(addEffectCode, effect, argName + "Attr(), ",
- stage, effectOnFullRegion, resource)
+ parameters, stage, effectOnFullRegion, resource)
.str();
}
} else {
@@ -3732,7 +3736,7 @@ void OpEmitter::genSideEffectInterfaceMethods() {
(location.kind == EffectKind::Operand
? "&getOperation()->getOpOperand(idx), "
: "getOperation()->getOpResult(idx), "),
- stage, effectOnFullRegion, resource)
+ parameters, stage, effectOnFullRegion, resource)
<< " }\n }\n";
}
}
More information about the Mlir-commits
mailing list