[Mlir-commits] [mlir] [MLIR][Transform] apply_registered_pass: support ListOptions as params (PR #144026)
Rolf Morel
llvmlistbot at llvm.org
Fri Jun 13 00:21:43 PDT 2025
https://github.com/rolfmorel created https://github.com/llvm/llvm-project/pull/144026
Interpret the multiple values associated to a param as a comma-separated list, i.e. as the analog of a ListOption on a pass.
>From 99e4520ee48c39360b03220297e6fb6f0f3e29db Mon Sep 17 00:00:00 2001
From: Rolf Morel <rolf.morel at intel.com>
Date: Fri, 13 Jun 2025 00:13:42 -0700
Subject: [PATCH] [MLIR][Transform] apply_registered_pass: support ListOptions
as params
Interpret the multiple values associated to a param as a
comma-separated list, i.e. as the analog of a ListOption on a pass.
---
.../lib/Dialect/Transform/IR/TransformOps.cpp | 28 +++++-----
.../Transform/test-pass-application.mlir | 52 ++++++++++++-------
2 files changed, 45 insertions(+), 35 deletions(-)
diff --git a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp
index 582d082153bef..bfe6416987629 100644
--- a/mlir/lib/Dialect/Transform/IR/TransformOps.cpp
+++ b/mlir/lib/Dialect/Transform/IR/TransformOps.cpp
@@ -791,6 +791,12 @@ transform::ApplyRegisteredPassOp::apply(transform::TransformRewriter &rewriter,
std::string options;
llvm::raw_string_ostream optionsStream(options); // For "printing" attrs.
+ auto appendValueAttr = [&](Attribute valueAttr) {
+ if (auto strAttr = dyn_cast<StringAttr>(valueAttr))
+ optionsStream << strAttr.getValue().str();
+ else
+ valueAttr.print(optionsStream, /*elideType=*/true);
+ };
OperandRange dynamicOptions = getDynamicOptions();
for (auto [idx, namedAttribute] : llvm::enumerate(getOptions())) {
@@ -799,7 +805,6 @@ transform::ApplyRegisteredPassOp::apply(transform::TransformRewriter &rewriter,
optionsStream << namedAttribute.getName().str(); // Append the key.
optionsStream << "="; // And the key-value separator.
- Attribute valueAttrToAppend;
if (auto paramOperandIndex =
dyn_cast<transform::ParamOperandAttr>(namedAttribute.getValue())) {
// The corresponding value attribute is passed in via a param.
@@ -810,22 +815,15 @@ transform::ApplyRegisteredPassOp::apply(transform::TransformRewriter &rewriter,
"should be the same as the number of options passed as params");
ArrayRef<Attribute> dynamicOption =
state.getParams(dynamicOptions[dynamicOptionIdx]);
- if (dynamicOption.size() != 1)
- return emitSilenceableError()
- << "options passed as a param must have "
- "a single value associated, param "
- << dynamicOptionIdx << " associates " << dynamicOption.size();
- valueAttrToAppend = dynamicOption[0];
+ // Append all attributes associated to the param, separated by commas.
+ for (auto [idx, associatedAttr] : llvm::enumerate(dynamicOption)) {
+ if (idx > 0)
+ optionsStream << ",";
+ appendValueAttr(associatedAttr);
+ }
} else {
// Value is a static attribute.
- valueAttrToAppend = namedAttribute.getValue();
- }
-
- // Append string representation of value attribute.
- if (auto strAttr = dyn_cast<StringAttr>(valueAttrToAppend)) {
- optionsStream << strAttr.getValue().str();
- } else {
- valueAttrToAppend.print(optionsStream, /*elideType=*/true);
+ appendValueAttr(namedAttribute.getValue());
}
}
optionsStream.flush();
diff --git a/mlir/test/Dialect/Transform/test-pass-application.mlir b/mlir/test/Dialect/Transform/test-pass-application.mlir
index 1d1be9eda3496..407dfa3823436 100644
--- a/mlir/test/Dialect/Transform/test-pass-application.mlir
+++ b/mlir/test/Dialect/Transform/test-pass-application.mlir
@@ -164,6 +164,38 @@ module attributes {transform.with_named_sequence} {
// -----
+// CHECK-LABEL: func private @valid_dynamic_pass_list_option()
+module {
+ func.func @valid_dynamic_pass_list_option() {
+ return
+ }
+
+ // CHECK: func @a()
+ func.func @a() {
+ return
+ }
+ // CHECK: func @b()
+ func.func @b() {
+ return
+ }
+}
+
+module attributes {transform.with_named_sequence} {
+ transform.named_sequence @__transform_main(%arg1: !transform.any_op) {
+ %1 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op
+ %2 = transform.get_parent_op %1 { deduplicate } : (!transform.any_op) -> !transform.any_op
+ %symbol_a = transform.param.constant "a" -> !transform.any_param
+ %symbol_b = transform.param.constant "b" -> !transform.any_param
+ %multiple_symbol_names = transform.merge_handles %symbol_a, %symbol_b : !transform.any_param
+ transform.apply_registered_pass "symbol-privatize"
+ with options = { exclude = %multiple_symbol_names } to %2
+ : (!transform.any_op, !transform.any_param) -> !transform.any_op
+ transform.yield
+ }
+}
+
+// -----
+
func.func @invalid_options_as_str() {
return
}
@@ -262,26 +294,6 @@ module attributes {transform.with_named_sequence} {
// -----
-func.func @too_many_pass_option_params() {
- return
-}
-
-module attributes {transform.with_named_sequence} {
- transform.named_sequence @__transform_main(%arg1: !transform.any_op) {
- %1 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op
- %x = transform.param.constant true -> !transform.any_param
- %y = transform.param.constant false -> !transform.any_param
- %topdown_options = transform.merge_handles %x, %y : !transform.any_param
- // expected-error @below {{options passed as a param must have a single value associated, param 0 associates 2}}
- transform.apply_registered_pass "canonicalize"
- with options = { "top-down" = %topdown_options } to %1
- : (!transform.any_op, !transform.any_param) -> !transform.any_op
- transform.yield
- }
-}
-
-// -----
-
module attributes {transform.with_named_sequence} {
// expected-error @below {{trying to schedule a pass on an unsupported operation}}
// expected-note @below {{target op}}
More information about the Mlir-commits
mailing list