[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