diff --git a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td index c7fcb55120c82..f3bc3497500e7 100644 --- a/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td +++ b/mlir/include/mlir/Dialect/IRDL/IR/IRDLOps.td @@ -20,6 +20,7 @@ include "IRDLInterfaces.td" include "mlir/Interfaces/SideEffectInterfaces.td" include "mlir/Interfaces/InferTypeOpInterface.td" include "mlir/IR/SymbolInterfaces.td" +include "mlir/IR/BuiltinAttributes.td" class IRDL_Op traits = []> : Op; @@ -133,7 +134,7 @@ def IRDL_ParametersOp : IRDL_Op<"parameters", "Define the constraints on parameters of a type/attribute definition"; let description = [{ `irdl.parameters` defines the constraints on parameters of a type or - attribute definition. + attribute definition. Each parameter is named after an identifier. Example: @@ -143,17 +144,19 @@ def IRDL_ParametersOp : IRDL_Op<"parameters", %0 = irdl.is i32 %1 = irdl.is i64 %2 = irdl.any_of(%0, %1) - irdl.parameters(%2) + irdl.parameters(elem: %2) } } ``` The above program defines a type `complex` inside the dialect `cmath`. The - type has a single parameter that should be either `i32` or `i64`. + type has a single parameter `elem` that should be either `i32` or `i64`. }]; - let arguments = (ins Variadic:$args); - let assemblyFormat = " `(` $args `)` attr-dict "; + let arguments = (ins Variadic:$args, + StrArrayAttr:$names); + let assemblyFormat = " `` custom($args, $names) attr-dict "; + let hasVerifier = true; } //===----------------------------------------------------------------------===// @@ -198,16 +201,17 @@ def IRDL_OperationOp : IRDL_Op<"operation", let regions = (region SizedRegion<1>:$body); let assemblyFormat = "$sym_name attr-dict-with-keyword custom($body)"; + let hasRegionVerifier = true; } def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> { let summary = "Define the operands of an operation"; let description = [{ `irdl.operands` define the operands of the `irdl.operation` parent operation - definition. + definition. Each operand is named after an identifier. In the following example, `irdl.operands` defines the operands of the - `norm` operation: + `mul` operation: ```mlir irdl.dialect @cmath { @@ -217,8 +221,8 @@ def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> { irdl.operation @mul { %0 = irdl.any %1 = irdl.parametric @cmath::@complex<%0> - irdl.results(%1) - irdl.operands(%1, %1) + irdl.results(res: %1) + irdl.operands(lhs: %1, rhs: %1) } } ``` @@ -228,11 +232,11 @@ def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> { The operands can also be marked as variadic or optional: ```mlir - irdl.operands(%0, single %1, optional %2, variadic %3) + irdl.operands(foo: %0, bar: single %1, baz: optional %2, qux: variadic %3) ``` - Here, %0 and %1 are required single operands, %2 is an optional operand, - and %3 is a variadic operand. + Here, foo and bar are required single operands, baz is an optional operand, + and qux is a variadic operand. When more than one operand is marked as optional or variadic, the operation will expect a 'operandSegmentSizes' attribute that defines the number of @@ -240,9 +244,10 @@ def IRDL_OperandsOp : IRDL_Op<"operands", [HasParent<"OperationOp">]> { }]; let arguments = (ins Variadic:$args, - VariadicityArrayAttr:$variadicity); + StrArrayAttr:$names, + VariadicityArrayAttr:$variadicity); let assemblyFormat = - "`` custom($args, $variadicity) attr-dict"; + " `` custom($args, $names, $variadicity) attr-dict"; let hasVerifier = true; } @@ -250,21 +255,22 @@ def IRDL_ResultsOp : IRDL_Op<"results", [HasParent<"OperationOp">]> { let summary = "Define the results of an operation"; let description = [{ `irdl.results` define the results of the `irdl.operation` parent operation - definition. + definition. Each result is named after an identifier. In the following example, `irdl.results` defines the results of the - `norm` operation: + `get_values` operation: ```mlir irdl.dialect @cmath { irdl.type @complex { /* ... */ } + /// Returns the real and imaginary parts of a complex number. irdl.operation @get_values { %0 = irdl.any %1 = irdl.parametric @cmath::@complex<%0> - irdl.results(%0, %0) - irdl.operands(%1) + irdl.results(re: %0, im: %0) + irdl.operands(complex: %1) } } ``` @@ -274,11 +280,11 @@ def IRDL_ResultsOp : IRDL_Op<"results", [HasParent<"OperationOp">]> { The results can also be marked as variadic or optional: ```mlir - irdl.results(%0, single %1, optional %2, variadic %3) + irdl.results(foo: %0, bar: single %1, baz: optional %2, qux: variadic %3) ``` - Here, %0 and %1 are required single results, %2 is an optional result, - and %3 is a variadic result. + Here, foo and bar are required single results, baz is an optional result, + and qux is a variadic result. When more than one result is marked as optional or variadic, the operation will expect a 'resultSegmentSizes' attribute that defines the number of @@ -286,9 +292,10 @@ def IRDL_ResultsOp : IRDL_Op<"results", [HasParent<"OperationOp">]> { }]; let arguments = (ins Variadic:$args, + StrArrayAttr:$names, VariadicityArrayAttr:$variadicity); let assemblyFormat = - " `` custom($args, $variadicity) attr-dict"; + " `` custom($args, $names, $variadicity) attr-dict"; let hasVerifier = true; } @@ -335,7 +342,8 @@ def IRDL_RegionOp : IRDL_Op<"region", let summary = "Define a region of an operation"; let description = [{ The irdl.region construct defines a set of characteristics - that a region of an operation should satify. + that a region of an operation should satify. Each region is named after + an identifier. These characteristics include constraints for the entry block arguments of the region and the total number of blocks it contains. @@ -360,7 +368,7 @@ def IRDL_RegionOp : IRDL_Op<"region", %r2 = irdl.region(%v0, %v1) %r3 = irdl.region with size 3 - irdl.regions(%r0, %r1, %r2, %r3) + irdl.regions(foo: %r0, bar: %r1, baz: %r2, qux: %r3) } } ``` @@ -368,11 +376,11 @@ def IRDL_RegionOp : IRDL_Op<"region", The above snippet demonstrates an operation named `@op_with_regions`, which is constrained to have four regions. - * Region `%r0` doesn't have any constraints on the arguments + * Region `foo` doesn't have any constraints on the arguments or the number of blocks. - * Region `%r1` should have an empty set of arguments. - * Region `%r2` should have two arguments of types `i32` and `i64`. - * Region `%r3` should contain exactly three blocks. + * Region `bar` should have an empty set of arguments. + * Region `baz` should have two arguments of types `i32` and `i64`. + * Region `qux` should contain exactly three blocks. }]; let arguments = (ins Variadic:$entryBlockArgs, OptionalAttr:$numberOfBlocks, @@ -391,7 +399,8 @@ def IRDL_RegionsOp : IRDL_Op<"regions", [HasParent<"OperationOp">]> { let summary = "Define the regions of an operation"; let description = [{ `irdl.regions` defines the regions of an operation by accepting - values produced by `irdl.region` operation as arguments. + values produced by `irdl.region` operation as arguments. Each + region has an identifier as name. Example: @@ -401,18 +410,19 @@ def IRDL_RegionsOp : IRDL_Op<"regions", [HasParent<"OperationOp">]> { %r1 = irdl.region with size 3 %0 = irdl.any %r2 = irdl.region(%0) - irdl.regions(%r1, %r2) + irdl.regions(foo: %r1, bar: %r2) } } ``` In the snippet above the operation is constrained to have two regions. - The first region should contain three blocks. - The second region should have one region with one argument. + The first region (`foo`) should contain three blocks. + The second region (`bar`) should have one region with one argument. }]; - let arguments = (ins Variadic:$args); - let assemblyFormat = " `(` $args `)` attr-dict "; + let arguments = (ins Variadic:$args, StrArrayAttr:$names); + let assemblyFormat = " `` custom($args, $names) attr-dict "; + let hasVerifier = true; } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp index c5c44d97ce091..c0778d478619a 100644 --- a/mlir/lib/Dialect/IRDL/IR/IRDL.cpp +++ b/mlir/lib/Dialect/IRDL/IR/IRDL.cpp @@ -18,6 +18,9 @@ #include "mlir/IR/Operation.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SetOperations.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/TypeSwitch.h" #include "llvm/IR/Metadata.h" #include "llvm/Support/Casting.h" @@ -49,7 +52,7 @@ void IRDLDialect::initialize() { } //===----------------------------------------------------------------------===// -// Parsing/Printing +// Parsing/Printing/Verifying //===----------------------------------------------------------------------===// /// Parse a region, and add a single block if the region is empty. @@ -78,30 +81,106 @@ LogicalResult DialectOp::verify() { return success(); } -LogicalResult OperandsOp::verify() { - size_t numVariadicities = getVariadicity().size(); - size_t numOperands = getNumOperands(); +LogicalResult OperationOp::verifyRegions() { + // Stores pairs of value kinds and the list of names of values of this kind in + // the operation. + SmallVector>> valueNames; + + auto insertNames = [&](StringRef kind, ArrayAttr names) { + llvm::SmallDenseSet nameSet; + nameSet.reserve(names.size()); + for (auto name : names) + nameSet.insert(llvm::cast(name).getValue()); + valueNames.emplace_back(kind, std::move(nameSet)); + }; - if (numOperands != numVariadicities) - return emitOpError() - << "the number of operands and their variadicities must be " + for (Operation &op : getBody().getOps()) { + TypeSwitch(&op) + .Case( + [&](OperandsOp op) { insertNames("operands", op.getNames()); }) + .Case( + [&](ResultsOp op) { insertNames("results", op.getNames()); }) + .Case( + [&](RegionsOp op) { insertNames("regions", op.getNames()); }); + } + + // Verify that no two operand, result or region share the same name. + // The absence of duplicates within each value kind is checked by the + // associated operation's verifier. + for (size_t i : llvm::seq(valueNames.size())) { + for (size_t j : llvm::seq(i + 1, valueNames.size())) { + auto [lhs, lhsSet] = valueNames[i]; + auto &[rhs, rhsSet] = valueNames[j]; + llvm::set_intersect(lhsSet, rhsSet); + if (!lhsSet.empty()) + return emitOpError("contains a value named '") + << *lhsSet.begin() << "' for both its " << lhs << " and " << rhs; + } + } + + return success(); +} + +static LogicalResult verifyNames(Operation *op, StringRef kindName, + ArrayAttr names, size_t numOperands) { + if (numOperands != names.size()) + return op->emitOpError() + << "the number of " << kindName + << "s and their names must be " "the same, but got " - << numOperands << " and " << numVariadicities << " respectively"; + << numOperands << " and " << names.size() << " respectively"; + + DenseMap nameMap; + for (auto [i, name] : llvm::enumerate(names)) { + StringRef nameRef = llvm::cast(name).getValue(); + if (nameRef.empty()) + return op->emitOpError() + << "name of " << kindName << " #" << i << " is empty"; + if (!llvm::isAlpha(nameRef[0]) && nameRef[0] != '_') + return op->emitOpError() + << "name of " << kindName << " #" << i + << " must start with either a letter or an underscore"; + if (llvm::any_of(nameRef, + [](char c) { return !llvm::isAlnum(c) && c != '_'; })) + return op->emitOpError() + << "name of " << kindName << " #" << i + << " must contain only letters, digits and underscores"; + if (nameMap.contains(nameRef)) + return op->emitOpError() << "name of " << kindName << " #" << i + << " is a duplicate of the name of " << kindName + << " #" << nameMap[nameRef]; + nameMap.insert({nameRef, i}); + } return success(); } -LogicalResult ResultsOp::verify() { - size_t numVariadicities = getVariadicity().size(); - size_t numOperands = this->getNumOperands(); +LogicalResult ParametersOp::verify() { + return verifyNames(*this, "parameter", getNames(), getNumOperands()); +} + +template +static LogicalResult verifyOperandsResultsCommon(ValueListOp op, + StringRef kindName) { + size_t numVariadicities = op.getVariadicity().size(); + size_t numOperands = op.getNumOperands(); if (numOperands != numVariadicities) - return emitOpError() - << "the number of operands and their variadicities must be " + return op.emitOpError() + << "the number of " << kindName + << "s and their variadicities must be " "the same, but got " << numOperands << " and " << numVariadicities << " respectively"; - return success(); + return verifyNames(op, kindName, op.getNames(), numOperands); +} + +LogicalResult OperandsOp::verify() { + return verifyOperandsResultsCommon(*this, "operand"); +} + +LogicalResult ResultsOp::verify() { + return verifyOperandsResultsCommon(*this, "result"); } LogicalResult AttributesOp::verify() { @@ -196,56 +275,111 @@ parseValueWithVariadicity(OpAsmParser &p, return success(); } -/// Parse a list of values with their variadicities first. By default, the -/// variadicity is single. -/// -/// values-with-variadicity ::= -/// `(` (value-with-variadicity (`,` value-with-variadicity)*)? `)` -/// value-with-variadicity ::= ("single" | "optional" | "variadic")? ssa-value -static ParseResult parseValuesWithVariadicity( +static ParseResult parseNamedValueListImpl( OpAsmParser &p, SmallVectorImpl &operands, - VariadicityArrayAttr &variadicityAttr) { + ArrayAttr &valueNamesAttr, VariadicityArrayAttr *variadicityAttr) { Builder &builder = p.getBuilder(); MLIRContext *ctx = builder.getContext(); + SmallVector valueNames; SmallVector variadicities; // Parse a single value with its variadicity auto parseOne = [&] { + StringRef name; OpAsmParser::UnresolvedOperand operand; VariadicityAttr variadicity; - if (parseValueWithVariadicity(p, operand, variadicity)) + if (p.parseKeyword(&name) || p.parseColon()) return failure(); + + if (variadicityAttr) { + if (parseValueWithVariadicity(p, operand, variadicity)) + return failure(); + variadicities.push_back(variadicity); + } else { + if (p.parseOperand(operand)) + return failure(); + } + + valueNames.push_back(StringAttr::get(ctx, name)); operands.push_back(operand); - variadicities.push_back(variadicity); return success(); }; if (p.parseCommaSeparatedList(OpAsmParser::Delimiter::Paren, parseOne)) return failure(); - variadicityAttr = VariadicityArrayAttr::get(ctx, variadicities); + valueNamesAttr = ArrayAttr::get(ctx, valueNames); + if (variadicityAttr) + *variadicityAttr = VariadicityArrayAttr::get(ctx, variadicities); return success(); } -/// Print a list of values with their variadicities first. By default, the +/// Parse a list of named values. +/// +/// values ::= +/// `(` (named-value (`,` named-value)*)? `)` +/// named-value := bare-id `:` ssa-value +static ParseResult +parseNamedValueList(OpAsmParser &p, + SmallVectorImpl &operands, + ArrayAttr &valueNamesAttr) { + return parseNamedValueListImpl(p, operands, valueNamesAttr, nullptr); +} + +/// Parse a list of named values with their variadicities first. By default, the /// variadicity is single. /// /// values-with-variadicity ::= /// `(` (value-with-variadicity (`,` value-with-variadicity)*)? `)` -/// value-with-variadicity ::= ("single" | "optional" | "variadic")? ssa-value -static void printValuesWithVariadicity(OpAsmPrinter &p, Operation *op, - OperandRange operands, - VariadicityArrayAttr variadicityAttr) { +/// value-with-variadicity +/// ::= bare-id `:` ("single" | "optional" | "variadic")? ssa-value +static ParseResult parseNamedValueListWithVariadicity( + OpAsmParser &p, SmallVectorImpl &operands, + ArrayAttr &valueNamesAttr, VariadicityArrayAttr &variadicityAttr) { + return parseNamedValueListImpl(p, operands, valueNamesAttr, &variadicityAttr); +} + +static void printNamedValueListImpl(OpAsmPrinter &p, Operation *op, + OperandRange operands, + ArrayAttr valueNamesAttr, + VariadicityArrayAttr variadicityAttr) { p << "("; interleaveComma(llvm::seq(0, operands.size()), p, [&](int i) { - Variadicity variadicity = variadicityAttr[i].getValue(); - if (variadicity != Variadicity::single) { - p << stringifyVariadicity(variadicity) << " "; + p << llvm::cast(valueNamesAttr[i]).getValue() << ": "; + if (variadicityAttr) { + Variadicity variadicity = variadicityAttr[i].getValue(); + if (variadicity != Variadicity::single) { + p << stringifyVariadicity(variadicity) << " "; + } } p << operands[i]; }); p << ")"; } +/// Print a list of named values. +/// +/// values ::= +/// `(` (named-value (`,` named-value)*)? `)` +/// named-value := bare-id `:` ssa-value +static void printNamedValueList(OpAsmPrinter &p, Operation *op, + OperandRange operands, + ArrayAttr valueNamesAttr) { + printNamedValueListImpl(p, op, operands, valueNamesAttr, nullptr); +} + +/// Print a list of named values with their variadicities first. By default, the +/// variadicity is single. +/// +/// values-with-variadicity ::= +/// `(` (value-with-variadicity (`,` value-with-variadicity)*)? `)` +/// value-with-variadicity ::= +/// bare-id `:` ("single" | "optional" | "variadic")? ssa-value +static void printNamedValueListWithVariadicity( + OpAsmPrinter &p, Operation *op, OperandRange operands, + ArrayAttr valueNamesAttr, VariadicityArrayAttr variadicityAttr) { + printNamedValueListImpl(p, op, operands, valueNamesAttr, variadicityAttr); +} + static ParseResult parseAttributesOp(OpAsmParser &p, SmallVectorImpl &attrOperands, @@ -285,6 +419,10 @@ LogicalResult RegionOp::verify() { return success(); } +LogicalResult RegionsOp::verify() { + return verifyNames(*this, "region", getNames(), getNumOperands()); +} + #include "mlir/Dialect/IRDL/IR/IRDLInterfaces.cpp.inc" #define GET_TYPEDEF_CLASSES diff --git a/mlir/test/CAPI/irdl.c b/mlir/test/CAPI/irdl.c index b35345b664b14..ad52ece6a41ce 100644 --- a/mlir/test/CAPI/irdl.c +++ b/mlir/test/CAPI/irdl.c @@ -17,13 +17,13 @@ const char irdlDialect[] = "\ irdl.dialect @foo {\ irdl.operation @op {\ %i32 = irdl.is i32\ - irdl.results(%i32)\ + irdl.results(baz: %i32)\ }\ }\ irdl.dialect @bar {\ irdl.operation @op {\ %i32 = irdl.is i32\ - irdl.operands(%i32)\ + irdl.operands(baz: %i32)\ }\ }"; diff --git a/mlir/test/Dialect/IRDL/cmath.irdl.mlir b/mlir/test/Dialect/IRDL/cmath.irdl.mlir index 0b7e220ceb90c..1d6286ef5a4c1 100644 --- a/mlir/test/Dialect/IRDL/cmath.irdl.mlir +++ b/mlir/test/Dialect/IRDL/cmath.irdl.mlir @@ -8,26 +8,26 @@ module { // CHECK: %[[v0:[^ ]*]] = irdl.is f32 // CHECK: %[[v1:[^ ]*]] = irdl.is f64 // CHECK: %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]]) - // CHECK: irdl.parameters(%[[v2]]) + // CHECK: irdl.parameters(elem: %[[v2]]) // CHECK: } irdl.type @complex { %0 = irdl.is f32 %1 = irdl.is f64 %2 = irdl.any_of(%0, %1) - irdl.parameters(%2) + irdl.parameters(elem: %2) } // CHECK: irdl.operation @norm { // CHECK: %[[v0:[^ ]*]] = irdl.any // CHECK: %[[v1:[^ ]*]] = irdl.parametric @cmath::@complex<%[[v0]]> - // CHECK: irdl.operands(%[[v1]]) - // CHECK: irdl.results(%[[v0]]) + // CHECK: irdl.operands(complex: %[[v1]]) + // CHECK: irdl.results(norm: %[[v0]]) // CHECK: } irdl.operation @norm { %0 = irdl.any %1 = irdl.parametric @cmath::@complex<%0> - irdl.operands(%1) - irdl.results(%0) + irdl.operands(complex: %1) + irdl.results(norm: %0) } // CHECK: irdl.operation @mul { @@ -35,16 +35,16 @@ module { // CHECK: %[[v1:[^ ]*]] = irdl.is f64 // CHECK: %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]]) // CHECK: %[[v3:[^ ]*]] = irdl.parametric @cmath::@complex<%[[v2]]> - // CHECK: irdl.operands(%[[v3]], %[[v3]]) - // CHECK: irdl.results(%[[v3]]) + // CHECK: irdl.operands(lhs: %[[v3]], rhs: %[[v3]]) + // CHECK: irdl.results(res: %[[v3]]) // CHECK: } irdl.operation @mul { %0 = irdl.is f32 %1 = irdl.is f64 %2 = irdl.any_of(%0, %1) %3 = irdl.parametric @cmath::@complex<%2> - irdl.operands(%3, %3) - irdl.results(%3) + irdl.operands(lhs: %3, rhs: %3) + irdl.results(res: %3) } } diff --git a/mlir/test/Dialect/IRDL/cpred.irdl.mlir b/mlir/test/Dialect/IRDL/cpred.irdl.mlir index 129793e565d27..c0ce2b9023c30 100644 --- a/mlir/test/Dialect/IRDL/cpred.irdl.mlir +++ b/mlir/test/Dialect/IRDL/cpred.irdl.mlir @@ -7,8 +7,8 @@ module { irdl.type @type { %0 = irdl.c_pred "::llvm::isa<::mlir::IntegerAttr>($_self)" // CHECK: %{{.*}} = irdl.c_pred "::llvm::isa<::mlir::IntegerAttr>($_self)" - irdl.parameters(%0) - // CHECK: irdl.parameters(%{{.*}}) + irdl.parameters(foo: %0) + // CHECK: irdl.parameters(foo: %{{.*}}) } } } diff --git a/mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir b/mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir index cbcc248bf00b1..7c0b94e675a11 100644 --- a/mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir +++ b/mlir/test/Dialect/IRDL/cyclic-types.irdl.mlir @@ -9,14 +9,14 @@ irdl.dialect @testd { // CHECK: %[[v1:[^ ]*]] = irdl.parametric @testd::@self_referencing<%[[v0]]> // CHECK: %[[v2:[^ ]*]] = irdl.is i32 // CHECK: %[[v3:[^ ]*]] = irdl.any_of(%[[v1]], %[[v2]]) - // CHECK: irdl.parameters(%[[v3]]) + // CHECK: irdl.parameters(foo: %[[v3]]) // CHECK: } irdl.type @self_referencing { %0 = irdl.any %1 = irdl.parametric @testd::@self_referencing<%0> %2 = irdl.is i32 %3 = irdl.any_of(%1, %2) - irdl.parameters(%3) + irdl.parameters(foo: %3) } @@ -25,13 +25,13 @@ irdl.dialect @testd { // CHECK: %[[v1:[^ ]*]] = irdl.parametric @testd::@type2<%[[v0]]> // CHECK: %[[v2:[^ ]*]] = irdl.is i32 // CHECK: %[[v3:[^ ]*]] = irdl.any_of(%[[v1]], %[[v2]]) - // CHECK: irdl.parameters(%[[v3]]) + // CHECK: irdl.parameters(foo: %[[v3]]) irdl.type @type1 { %0 = irdl.any %1 = irdl.parametric @testd::@type2<%0> %2 = irdl.is i32 %3 = irdl.any_of(%1, %2) - irdl.parameters(%3) + irdl.parameters(foo: %3) } // CHECK: irdl.type @type2 { @@ -39,12 +39,12 @@ irdl.dialect @testd { // CHECK: %[[v1:[^ ]*]] = irdl.parametric @testd::@type1<%[[v0]]> // CHECK: %[[v2:[^ ]*]] = irdl.is i32 // CHECK: %[[v3:[^ ]*]] = irdl.any_of(%[[v1]], %[[v2]]) - // CHECK: irdl.parameters(%[[v3]]) + // CHECK: irdl.parameters(foo: %[[v3]]) irdl.type @type2 { %0 = irdl.any %1 = irdl.parametric @testd::@type1<%0> %2 = irdl.is i32 %3 = irdl.any_of(%1, %2) - irdl.parameters(%3) + irdl.parameters(foo: %3) } } diff --git a/mlir/test/Dialect/IRDL/invalid.irdl.mlir b/mlir/test/Dialect/IRDL/invalid.irdl.mlir index 93ad619358750..1e66161b800df 100644 --- a/mlir/test/Dialect/IRDL/invalid.irdl.mlir +++ b/mlir/test/Dialect/IRDL/invalid.irdl.mlir @@ -2,11 +2,139 @@ // Testing invalid IRDL IRs +irdl.dialect @testd { + irdl.type @type { + %0 = irdl.any + // expected-error@+1 {{expected valid keyword}} + irdl.parameters(%0) + } +} + +// ----- + +irdl.dialect @testd { + irdl.type @type { + %0 = irdl.any + // expected-error@+1 {{expected valid keyword}} + irdl.parameters(123: %0) + } +} + +// ----- + +irdl.dialect @testd { + irdl.type @type { + %0 = irdl.any + // expected-error@+1 {{name of parameter #0 must contain only letters, digits and underscores}} + irdl.parameters(test$test: %0) + } +} + +// ----- + +irdl.dialect @testd { + irdl.operation @op { + %0 = irdl.any + // expected-error@+1 {{name of result #0 must contain only letters, digits and underscores}} + irdl.results(test$test: %0) + } +} + +// ----- + +irdl.dialect @testd { + irdl.operation @op { + %0 = irdl.any + // expected-error@+1 {{name of operand #0 must contain only letters, digits and underscores}} + irdl.operands(test$test: %0) + } +} + +// ----- + +irdl.dialect @testd { + irdl.type @type { + %0 = irdl.any + // expected-error@+1 {{name of parameter #2 is a duplicate of the name of parameter #0}} + irdl.parameters(foo: %0, bar: %0, foo: %0) + } +} + +// ----- + +irdl.dialect @testd { + irdl.operation @op { + %0 = irdl.any + // expected-error@+1 {{name of result #2 is a duplicate of the name of result #0}} + irdl.results(foo: %0, bar: %0, foo: %0) + } +} + +// ----- + +irdl.dialect @testd { + irdl.operation @op { + %0 = irdl.any + // expected-error@+1 {{name of operand #2 is a duplicate of the name of operand #0}} + irdl.operands(foo: %0, bar: %0, foo: %0) + } +} + +// ----- + +irdl.dialect @testd { + // expected-error@+1 {{contains a value named 'foo' for both its operands and results}} + irdl.operation @op { + %0 = irdl.any + irdl.operands(foo: %0) + irdl.results(foo: %0) + } +} + +// ----- + +irdl.dialect @testd { + // expected-error@+1 {{contains a value named 'bar' for both its regions and results}} + irdl.operation @op { + %0 = irdl.any + %1 = irdl.region + irdl.regions(bar: %1) + irdl.results(bar: %0) + } +} + +// ----- + +irdl.dialect @testd { + // expected-error@+1 {{contains a value named 'baz' for both its regions and operands}} + irdl.operation @op { + %0 = irdl.any + %1 = irdl.region + irdl.regions(baz: %1) + irdl.operands(baz: %0) + } +} + +// ----- + +irdl.dialect @testd { + // expected-error@+1 {{contains a value named 'baz' for both its regions and results}} + irdl.operation @op { + %0 = irdl.any + %1 = irdl.region + irdl.regions(baz: %1) + irdl.operands(qux: %0) + irdl.results(baz: %0) + } +} + +// ----- + irdl.dialect @testd { irdl.type @type { // expected-error@+1 {{symbol '@foo' not found}} %0 = irdl.base @foo - irdl.parameters(%0) + irdl.parameters(foo: %0) } } @@ -16,7 +144,7 @@ irdl.dialect @testd { irdl.type @type { // expected-error@+1 {{the base type or attribute name should start with '!' or '#'}} %0 = irdl.base "builtin.integer" - irdl.parameters(%0) + irdl.parameters(foo: %0) } } @@ -26,7 +154,7 @@ irdl.dialect @testd { irdl.type @type { // expected-error@+1 {{the base type or attribute name should start with '!' or '#'}} %0 = irdl.base "" - irdl.parameters(%0) + irdl.parameters(foo: %0) } } @@ -36,7 +164,7 @@ irdl.dialect @testd { irdl.type @type { // expected-error@+1 {{the base type or attribute should be specified by either a name}} %0 = irdl.base - irdl.parameters(%0) + irdl.parameters(foo: %0) } } @@ -48,6 +176,6 @@ irdl.dialect @invalid_parametric { irdl.operation @foo { // expected-error@+1 {{symbol '@not_a_type_or_attr' does not refer to a type or attribute definition}} %param = irdl.parametric @not_a_type_or_attr<> - irdl.results(%param) + irdl.results(foo: %param) } } diff --git a/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir b/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir index 762f992e786d4..7c2efc6c96e41 100644 --- a/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir +++ b/mlir/test/Dialect/IRDL/regions-ops.irdl.mlir @@ -9,11 +9,41 @@ irdl.dialect @testRegionOpNegativeNumber { // ----- +irdl.dialect @testRegionsOpMissingName { + irdl.operation @op { + %r1 = irdl.region + // expected-error @below {{expected valid keyword}} + irdl.regions(%r1) + } +} + +// ----- + +irdl.dialect @testRegionsOpWrongName { + irdl.operation @op { + %r1 = irdl.region + // expected-error @below {{name of region #0 must contain only letters, digits and underscores}} + irdl.regions(test$test: %r1) + } +} + +// ----- + +irdl.dialect @testRegionsDuplicateName { + irdl.operation @op { + %r1 = irdl.region + // expected-error @below {{name of region #2 is a duplicate of the name of region #0}} + irdl.regions(foo: %r1, bar: %r1, foo: %r1) + } +} + +// ----- + irdl.dialect @testRegionsOpWrongOperation { irdl.operation @op { // expected-note @below {{prior use here}} %r1 = irdl.any // expected-error @below {{use of value '%r1' expects different type than prior uses: '!irdl.region' vs '!irdl.attribute'}} - irdl.regions(%r1) + irdl.regions(foo: %r1) } } diff --git a/mlir/test/Dialect/IRDL/test-type.irdl.mlir b/mlir/test/Dialect/IRDL/test-type.irdl.mlir index 1bcfb0b8e20be..1d471a673d8d4 100644 --- a/mlir/test/Dialect/IRDL/test-type.irdl.mlir +++ b/mlir/test/Dialect/IRDL/test-type.irdl.mlir @@ -11,23 +11,23 @@ module { // CHECK: %[[v1:[^ ]*]] = irdl.is i32 // CHECK: %[[v2:[^ ]*]] = irdl.is i64 // CHECK: %[[v3:[^ ]*]] = irdl.any_of(%[[v1]], %[[v2]]) - // CHECK: irdl.parameters(%[[v0]], %[[v3]]) + // CHECK: irdl.parameters(foo: %[[v0]], bar: %[[v3]]) // CHECK: } irdl.type @parametrized { %0 = irdl.any %1 = irdl.is i32 %2 = irdl.is i64 %3 = irdl.any_of(%1, %2) - irdl.parameters(%0, %3) + irdl.parameters(foo: %0, bar: %3) } // CHECK: irdl.operation @any { // CHECK: %[[v0:[^ ]*]] = irdl.any - // CHECK: irdl.results(%[[v0]]) + // CHECK: irdl.results(foo: %[[v0]]) // CHECK: } irdl.operation @any { %0 = irdl.any - irdl.results(%0) + irdl.results(foo: %0) } } } diff --git a/mlir/test/Dialect/IRDL/testd.irdl.mlir b/mlir/test/Dialect/IRDL/testd.irdl.mlir index aeb1a83747ecc..45156db867fcb 100644 --- a/mlir/test/Dialect/IRDL/testd.irdl.mlir +++ b/mlir/test/Dialect/IRDL/testd.irdl.mlir @@ -4,51 +4,51 @@ irdl.dialect @testd { // CHECK: irdl.type @parametric { // CHECK: %[[v0:[^ ]*]] = irdl.any - // CHECK: irdl.parameters(%[[v0]]) + // CHECK: irdl.parameters(foo: %[[v0]]) // CHECK: } irdl.type @parametric { %0 = irdl.any - irdl.parameters(%0) + irdl.parameters(foo: %0) } // CHECK: irdl.attribute @parametric_attr { // CHECK: %[[v0:[^ ]*]] = irdl.any - // CHECK: irdl.parameters(%[[v0]]) + // CHECK: irdl.parameters(foo: %[[v0]]) // CHECK: } irdl.attribute @parametric_attr { %0 = irdl.any - irdl.parameters(%0) + irdl.parameters(foo: %0) } // CHECK: irdl.type @attr_in_type_out { // CHECK: %[[v0:[^ ]*]] = irdl.any - // CHECK: irdl.parameters(%[[v0]]) + // CHECK: irdl.parameters(foo: %[[v0]]) // CHECK: } irdl.type @attr_in_type_out { %0 = irdl.any - irdl.parameters(%0) + irdl.parameters(foo: %0) } // CHECK: irdl.operation @eq { // CHECK: %[[v0:[^ ]*]] = irdl.is i32 - // CHECK: irdl.results(%[[v0]]) + // CHECK: irdl.results(foo: %[[v0]]) // CHECK: } irdl.operation @eq { %0 = irdl.is i32 - irdl.results(%0) + irdl.results(foo: %0) } // CHECK: irdl.operation @anyof { // CHECK: %[[v0:[^ ]*]] = irdl.is i32 // CHECK: %[[v1:[^ ]*]] = irdl.is i64 // CHECK: %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]]) - // CHECK: irdl.results(%[[v2]]) + // CHECK: irdl.results(foo: %[[v2]]) // CHECK: } irdl.operation @anyof { %0 = irdl.is i32 %1 = irdl.is i64 %2 = irdl.any_of(%0, %1) - irdl.results(%2) + irdl.results(foo: %2) } // CHECK: irdl.operation @all_of { @@ -56,32 +56,32 @@ irdl.dialect @testd { // CHECK: %[[v1:[^ ]*]] = irdl.is i64 // CHECK: %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]]) // CHECK: %[[v3:[^ ]*]] = irdl.all_of(%[[v2]], %[[v1]]) - // CHECK: irdl.results(%[[v3]]) + // CHECK: irdl.results(foo: %[[v3]]) // CHECK: } irdl.operation @all_of { %0 = irdl.is i32 %1 = irdl.is i64 %2 = irdl.any_of(%0, %1) %3 = irdl.all_of(%2, %1) - irdl.results(%3) + irdl.results(foo: %3) } // CHECK: irdl.operation @any { // CHECK: %[[v0:[^ ]*]] = irdl.any - // CHECK: irdl.results(%[[v0]]) + // CHECK: irdl.results(foo: %[[v0]]) // CHECK: } irdl.operation @any { %0 = irdl.any - irdl.results(%0) + irdl.results(foo: %0) } // CHECK: irdl.operation @dyn_type_base { // CHECK: %[[v1:[^ ]*]] = irdl.base @testd::@parametric - // CHECK: irdl.results(%[[v1]]) + // CHECK: irdl.results(foo: %[[v1]]) // CHECK: } irdl.operation @dyn_type_base { %0 = irdl.base @testd::@parametric - irdl.results(%0) + irdl.results(foo: %0) } // CHECK: irdl.operation @dyn_attr_base { @@ -95,11 +95,11 @@ irdl.dialect @testd { // CHECK: irdl.operation @named_type_base { // CHECK: %[[v1:[^ ]*]] = irdl.base "!builtin.integer" - // CHECK: irdl.results(%[[v1]]) + // CHECK: irdl.results(foo: %[[v1]]) // CHECK: } irdl.operation @named_type_base { %0 = irdl.base "!builtin.integer" - irdl.results(%0) + irdl.results(foo: %0) } // CHECK: irdl.operation @named_attr_base { @@ -116,27 +116,27 @@ irdl.dialect @testd { // CHECK: %[[v1:[^ ]*]] = irdl.is i64 // CHECK: %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]]) // CHECK: %[[v3:[^ ]*]] = irdl.parametric @testd::@parametric<%[[v2]]> - // CHECK: irdl.results(%[[v3]]) + // CHECK: irdl.results(foo: %[[v3]]) // CHECK: } irdl.operation @dynparams { %0 = irdl.is i32 %1 = irdl.is i64 %2 = irdl.any_of(%0, %1) %3 = irdl.parametric @testd::@parametric<%2> - irdl.results(%3) + irdl.results(foo: %3) } // CHECK: irdl.operation @constraint_vars { // CHECK: %[[v0:[^ ]*]] = irdl.is i32 // CHECK: %[[v1:[^ ]*]] = irdl.is i64 // CHECK: %[[v2:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]]) - // CHECK: irdl.results(%[[v2]], %[[v2]]) + // CHECK: irdl.results(foo: %[[v2]], bar: %[[v2]]) // CHECK: } irdl.operation @constraint_vars { %0 = irdl.is i32 %1 = irdl.is i64 %2 = irdl.any_of(%0, %1) - irdl.results(%2, %2) + irdl.results(foo: %2, bar: %2) } // CHECK: irdl.operation @attrs { @@ -160,7 +160,7 @@ irdl.dialect @testd { // CHECK: %[[r1:[^ ]*]] = irdl.region(%[[v0]], %[[v1]]) // CHECK: %[[r2:[^ ]*]] = irdl.region with size 3 // CHECK: %[[r3:[^ ]*]] = irdl.region() - // CHECK: irdl.regions(%[[r0]], %[[r1]], %[[r2]], %[[r3]]) + // CHECK: irdl.regions(foo: %[[r0]], bar: %[[r1]], baz: %[[r2]], qux: %[[r3]]) // CHECK: } irdl.operation @regions { %r0 = irdl.region @@ -170,20 +170,20 @@ irdl.dialect @testd { %r2 = irdl.region with size 3 %r3 = irdl.region() - irdl.regions(%r0, %r1, %r2, %r3) + irdl.regions(foo: %r0, bar: %r1, baz: %r2, qux: %r3) } // CHECK: irdl.operation @region_and_operand { // CHECK: %[[v0:[^ ]*]] = irdl.any // CHECK: %[[r0:[^ ]*]] = irdl.region(%[[v0]]) - // CHECK: irdl.operands(%[[v0]]) - // CHECK: irdl.regions(%[[r0]]) + // CHECK: irdl.operands(foo: %[[v0]]) + // CHECK: irdl.regions(bar: %[[r0]]) // CHECK: } irdl.operation @region_and_operand { %v0 = irdl.any %r0 = irdl.region(%v0) - irdl.operands(%v0) - irdl.regions(%r0) + irdl.operands(foo: %v0) + irdl.regions(bar: %r0) } } diff --git a/mlir/test/Dialect/IRDL/variadics-error.irdl.mlir b/mlir/test/Dialect/IRDL/variadics-error.irdl.mlir index 67fa94ea8b742..3e29dd837916b 100644 --- a/mlir/test/Dialect/IRDL/variadics-error.irdl.mlir +++ b/mlir/test/Dialect/IRDL/variadics-error.irdl.mlir @@ -5,7 +5,7 @@ irdl.dialect @errors { %0 = irdl.is i32 // expected-error@+1 {{'irdl.operands' op the number of operands and their variadicities must be the same, but got 2 and 1 respectively}} - "irdl.operands"(%0, %0) <{variadicity = #irdl}> : (!irdl.attribute, !irdl.attribute) -> () + "irdl.operands"(%0, %0) <{names = ["foo", "bar"], variadicity = #irdl}> : (!irdl.attribute, !irdl.attribute) -> () } } @@ -16,7 +16,7 @@ irdl.dialect @errors { %0 = irdl.is i32 // expected-error@+1 {{'irdl.operands' op the number of operands and their variadicities must be the same, but got 1 and 2 respectively}} - "irdl.operands"(%0) <{variadicity = #irdl}> : (!irdl.attribute) -> () + "irdl.operands"(%0) <{names = ["foo"], variadicity = #irdl}> : (!irdl.attribute) -> () } } @@ -26,8 +26,8 @@ irdl.dialect @errors { irdl.operation @results { %0 = irdl.is i32 - // expected-error@+1 {{'irdl.results' op the number of operands and their variadicities must be the same, but got 2 and 1 respectively}} - "irdl.results"(%0, %0) <{variadicity = #irdl}> : (!irdl.attribute, !irdl.attribute) -> () + // expected-error@+1 {{'irdl.results' op the number of results and their variadicities must be the same, but got 2 and 1 respectively}} + "irdl.results"(%0, %0) <{names = ["foo", "bar"], variadicity = #irdl}> : (!irdl.attribute, !irdl.attribute) -> () } } @@ -37,7 +37,7 @@ irdl.dialect @errors { irdl.operation @results2 { %0 = irdl.is i32 - // expected-error@+1 {{'irdl.results' op the number of operands and their variadicities must be the same, but got 1 and 2 respectively}} - "irdl.results"(%0) <{variadicity = #irdl}> : (!irdl.attribute) -> () + // expected-error@+1 {{'irdl.results' op the number of results and their variadicities must be the same, but got 1 and 2 respectively}} + "irdl.results"(%0) <{names = ["foo"], variadicity = #irdl}> : (!irdl.attribute) -> () } } diff --git a/mlir/test/Dialect/IRDL/variadics.irdl.mlir b/mlir/test/Dialect/IRDL/variadics.irdl.mlir index 64c5e1878f08e..5118320f6d2e8 100644 --- a/mlir/test/Dialect/IRDL/variadics.irdl.mlir +++ b/mlir/test/Dialect/IRDL/variadics.irdl.mlir @@ -5,98 +5,98 @@ irdl.dialect @testvar { // CHECK-LABEL: irdl.operation @single_operand { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i32 - // CHECK-NEXT: irdl.operands(%[[v0]]) + // CHECK-NEXT: irdl.operands(foo: %[[v0]]) // CHECK-NEXT: } irdl.operation @single_operand { %0 = irdl.is i32 - irdl.operands(single %0) + irdl.operands(foo: single %0) } // CHECK-LABEL: irdl.operation @var_operand { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i16 // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32 // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i64 - // CHECK-NEXT: irdl.operands(%[[v0]], variadic %[[v1]], %[[v2]]) + // CHECK-NEXT: irdl.operands(foo: %[[v0]], bar: variadic %[[v1]], baz: %[[v2]]) // CHECK-NEXT: } irdl.operation @var_operand { %0 = irdl.is i16 %1 = irdl.is i32 %2 = irdl.is i64 - irdl.operands(%0, variadic %1, %2) + irdl.operands(foo: %0, bar: variadic %1, baz: %2) } // CHECK-LABEL: irdl.operation @opt_operand { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i16 // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32 // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i64 - // CHECK-NEXT: irdl.operands(%[[v0]], optional %[[v1]], %[[v2]]) + // CHECK-NEXT: irdl.operands(foo: %[[v0]], bar: optional %[[v1]], baz: %[[v2]]) // CHECK-NEXT: } irdl.operation @opt_operand { %0 = irdl.is i16 %1 = irdl.is i32 %2 = irdl.is i64 - irdl.operands(%0, optional %1, %2) + irdl.operands(foo: %0, bar: optional %1, baz: %2) } // CHECK-LABEL: irdl.operation @var_and_opt_operand { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i16 // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32 // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i64 - // CHECK-NEXT: irdl.operands(variadic %[[v0]], optional %[[v1]], %[[v2]]) + // CHECK-NEXT: irdl.operands(foo: variadic %[[v0]], bar: optional %[[v1]], baz: %[[v2]]) // CHECK-NEXT: } irdl.operation @var_and_opt_operand { %0 = irdl.is i16 %1 = irdl.is i32 %2 = irdl.is i64 - irdl.operands(variadic %0, optional %1, %2) + irdl.operands(foo: variadic %0, bar: optional %1, baz: %2) } // CHECK-LABEL: irdl.operation @single_result { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i32 - // CHECK-NEXT: irdl.results(%[[v0]]) + // CHECK-NEXT: irdl.results(foo: %[[v0]]) // CHECK-NEXT: } irdl.operation @single_result { %0 = irdl.is i32 - irdl.results(single %0) + irdl.results(foo: single %0) } // CHECK-LABEL: irdl.operation @var_result { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i16 // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32 // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i64 - // CHECK-NEXT: irdl.results(%[[v0]], variadic %[[v1]], %[[v2]]) + // CHECK-NEXT: irdl.results(foo: %[[v0]], bar: variadic %[[v1]], baz: %[[v2]]) // CHECK-NEXT: } irdl.operation @var_result { %0 = irdl.is i16 %1 = irdl.is i32 %2 = irdl.is i64 - irdl.results(%0, variadic %1, %2) + irdl.results(foo: %0, bar: variadic %1, baz: %2) } // CHECK-LABEL: irdl.operation @opt_result { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i16 // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32 // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i64 - // CHECK-NEXT: irdl.results(%[[v0]], optional %[[v1]], %[[v2]]) + // CHECK-NEXT: irdl.results(foo: %[[v0]], bar: optional %[[v1]], baz: %[[v2]]) // CHECK-NEXT: } irdl.operation @opt_result { %0 = irdl.is i16 %1 = irdl.is i32 %2 = irdl.is i64 - irdl.results(%0, optional %1, %2) + irdl.results(foo: %0, bar: optional %1, baz: %2) } // CHECK-LABEL: irdl.operation @var_and_opt_result { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i16 // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32 // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i64 - // CHECK-NEXT: irdl.results(variadic %[[v0]], optional %[[v1]], %[[v2]]) + // CHECK-NEXT: irdl.results(foo: variadic %[[v0]], bar: optional %[[v1]], baz: %[[v2]]) // CHECK-NEXT: } irdl.operation @var_and_opt_result { %0 = irdl.is i16 %1 = irdl.is i32 %2 = irdl.is i64 - irdl.results(variadic %0, optional %1, %2) + irdl.results(foo: variadic %0, bar: optional %1, baz: %2) } } diff --git a/mlir/test/Dialect/Transform/irdl.mlir b/mlir/test/Dialect/Transform/irdl.mlir index ae68d96c4314f..6c8c0bf50191a 100644 --- a/mlir/test/Dialect/Transform/irdl.mlir +++ b/mlir/test/Dialect/Transform/irdl.mlir @@ -9,7 +9,7 @@ module attributes {transform.with_named_sequence} { %0 = irdl.is i32 %1 = irdl.is i64 %2 = irdl.any_of(%0, %1) - irdl.results(%2) + irdl.results(foo: %2) } } } diff --git a/mlir/test/tblgen-to-irdl/CMathDialect.td b/mlir/test/tblgen-to-irdl/CMathDialect.td index abda7ca41e9db..3ed700c497410 100644 --- a/mlir/test/tblgen-to-irdl/CMathDialect.td +++ b/mlir/test/tblgen-to-irdl/CMathDialect.td @@ -27,7 +27,7 @@ def CMath_ComplexType : CMath_Type<"ComplexType", "complex"> { // CHECK: irdl.operation @identity { // CHECK-NEXT: %0 = irdl.base @cmath::@"!complex" -// CHECK-NEXT: irdl.results(%0) +// CHECK-NEXT: irdl.results(out: %0) // CHECK-NEXT: } def CMath_IdentityOp : CMath_Op<"identity"> { let results = (outs CMath_ComplexType:$out); @@ -37,8 +37,8 @@ def CMath_IdentityOp : CMath_Op<"identity"> { // CHECK-NEXT: %0 = irdl.base @cmath::@"!complex" // CHECK-NEXT: %1 = irdl.base @cmath::@"!complex" // CHECK-NEXT: %2 = irdl.base @cmath::@"!complex" -// CHECK-NEXT: irdl.operands(%0, %1) -// CHECK-NEXT: irdl.results(%2) +// CHECK-NEXT: irdl.operands(in1: %0, in2: %1) +// CHECK-NEXT: irdl.results(out: %2) // CHECK-NEXT: } def CMath_MulOp : CMath_Op<"mul"> { let arguments = (ins CMath_ComplexType:$in1, CMath_ComplexType:$in2); @@ -48,8 +48,8 @@ def CMath_MulOp : CMath_Op<"mul"> { // CHECK: irdl.operation @norm { // CHECK-NEXT: %0 = irdl.any // CHECK-NEXT: %1 = irdl.base @cmath::@"!complex" -// CHECK-NEXT: irdl.operands(%0) -// CHECK-NEXT: irdl.results(%1) +// CHECK-NEXT: irdl.operands(in: %0) +// CHECK-NEXT: irdl.results(out: %1) // CHECK-NEXT: } def CMath_NormOp : CMath_Op<"norm"> { let arguments = (ins AnyType:$in); diff --git a/mlir/test/tblgen-to-irdl/TestDialect.td b/mlir/test/tblgen-to-irdl/TestDialect.td index 7f4815d865b60..913b9b1b759e2 100644 --- a/mlir/test/tblgen-to-irdl/TestDialect.td +++ b/mlir/test/tblgen-to-irdl/TestDialect.td @@ -38,7 +38,7 @@ def Test_AndOp : Test_Op<"and"> { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.base @test::@"!singleton_a" // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.any // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.all_of(%[[v0]], %[[v1]]) -// CHECK-NEXT: irdl.operands(%[[v2]]) +// CHECK-NEXT: irdl.operands(in: %[[v2]]) // CHECK-NEXT: } @@ -48,7 +48,7 @@ def Test_AnyOp : Test_Op<"any"> { } // CHECK-LABEL: irdl.operation @any { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.any -// CHECK-NEXT: irdl.operands(%[[v0]]) +// CHECK-NEXT: irdl.operands(in: %[[v0]]) // CHECK-NEXT: } // Check attributes are converted correctly. @@ -77,7 +77,7 @@ def Test_ConfinedOp : Test_Op<"confined"> { // CHECK-NEXT: %[[v5:[^ ]*]] = irdl.c_pred "(::llvm::cast<::mlir::VectorType>($_self).getRank() > 0)" // CHECK-NEXT: %[[v6:[^ ]*]] = irdl.all_of(%[[v4]], %[[v5]]) // CHECK-NEXT: %[[v7:[^ ]*]] = irdl.all_of(%[[v3]], %[[v6]]) -// CHECK-NEXT: irdl.operands(%[[v2]], %[[v7]]) +// CHECK-NEXT: irdl.operands(tensor: %[[v2]], vector: %[[v7]]) // CHECK-NEXT: } // Check generic integer types are converted correctly. @@ -91,7 +91,28 @@ def Test_Integers : Test_Op<"integers"> { // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is ui8 // CHECK-NEXT: %[[v3:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]], %[[v2]]) // CHECK-NEXT: %[[v4:[^ ]*]] = irdl.base "!builtin.integer" -// CHECK-NEXT: irdl.operands(%[[v3]], %[[v4]]) +// CHECK-NEXT: irdl.operands(any_int: %[[v3]], any_integer: %[[v4]]) +// CHECK-NEXT: } + +// Check that IRDL names are properly generated when needed. +def Test_NamesOp : Test_Op<"names"> { + let arguments = (ins I32:$a, + I32:$_hello, + I32:$unnamed0, + I32); + let regions = (region AnyRegion:$unnamed1); + let results = (outs I32:$unnamed2); +} +// CHECK-LABEL: irdl.operation @names { +// CHECK-NEXT: %[[v0:[^ ]*]] = irdl.is i32 +// CHECK-NEXT: %[[v1:[^ ]*]] = irdl.is i32 +// CHECK-NEXT: %[[v2:[^ ]*]] = irdl.is i32 +// CHECK-NEXT: %[[v3:[^ ]*]] = irdl.is i32 +// CHECK-NEXT: %[[v4:[^ ]*]] = irdl.is i32 +// CHECK-NEXT: %[[reg:[^ ]*]] = irdl.region +// CHECK-NEXT: irdl.operands(a: %[[v0]], _hello: %[[v1]], unnamed0: %[[v2]], unnamed3: %[[v3]]) +// CHECK-NEXT: irdl.results(unnamed2: %[[v4]]) +// CHECK-NEXT: irdl.regions(unnamed1: %[[reg]]) // CHECK-NEXT: } // Check that AnyTypeOf is converted correctly. @@ -103,7 +124,7 @@ def Test_OrOp : Test_Op<"or"> { // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.base @test::@"!singleton_b" // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.base @test::@"!singleton_c" // CHECK-NEXT: %[[v3:[^ ]*]] = irdl.any_of(%[[v0]], %[[v1]], %[[v2]]) -// CHECK-NEXT: irdl.operands(%[[v3]]) +// CHECK-NEXT: irdl.operands(in: %[[v3]]) // CHECK-NEXT: } // Check regions are converted correctly. @@ -114,7 +135,7 @@ def Test_RegionsOp : Test_Op<"regions"> { // CHECK-LABEL: irdl.operation @regions { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.region // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.region with size 1 -// CHECK-NEXT: irdl.regions(%[[v0]], %[[v1]]) +// CHECK-NEXT: irdl.regions(any_region: %[[v0]], single_block_region: %[[v1]]) // CHECK-NEXT: } // Check that various types are converted correctly. @@ -148,5 +169,5 @@ def Test_VariadicityOp : Test_Op<"variadicity"> { // CHECK-NEXT: %[[v0:[^ ]*]] = irdl.base @test::@"!singleton_a" // CHECK-NEXT: %[[v1:[^ ]*]] = irdl.base @test::@"!singleton_b" // CHECK-NEXT: %[[v2:[^ ]*]] = irdl.base @test::@"!singleton_c" -// CHECK-NEXT: irdl.operands(variadic %[[v0]], optional %[[v1]], %[[v2]]) +// CHECK-NEXT: irdl.operands(variadic: variadic %[[v0]], optional: optional %[[v1]], required: %[[v2]]) // CHECK-NEXT: } diff --git a/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp b/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp index 4e354e535dd3a..c9f6dd35de44e 100644 --- a/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp +++ b/mlir/tools/tblgen-to-irdl/OpDefinitionsGen.cpp @@ -23,6 +23,7 @@ #include "mlir/TableGen/GenNameParser.h" #include "mlir/TableGen/Interfaces.h" #include "mlir/TableGen/Operator.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/raw_ostream.h" @@ -394,13 +395,42 @@ irdl::OperationOp createIRDLOperation(OpBuilder &builder, Block &opBlock = op.getBody().emplaceBlock(); OpBuilder consBuilder = OpBuilder::atBlockBegin(&opBlock); + SmallDenseSet usedNames; + for (auto &namedCons : tblgenOp.getOperands()) + usedNames.insert(namedCons.name); + for (auto &namedCons : tblgenOp.getResults()) + usedNames.insert(namedCons.name); + for (auto &namedReg : tblgenOp.getRegions()) + usedNames.insert(namedReg.name); + + size_t generateCounter = 0; + auto generateName = [&](StringRef prefix) -> StringAttr { + SmallString<16> candidate; + do { + candidate.clear(); + raw_svector_ostream candidateStream(candidate); + candidateStream << prefix << generateCounter; + generateCounter++; + } while (usedNames.contains(candidate)); + return StringAttr::get(ctx, candidate); + }; + auto normalizeName = [&](StringRef name) -> StringAttr { + if (name == "") + return generateName("unnamed"); + return StringAttr::get(ctx, name); + }; + auto getValues = [&](tblgen::Operator::const_value_range namedCons) { SmallVector operands; + SmallVector names; SmallVector variadicity; + for (const NamedTypeConstraint &namedCons : namedCons) { auto operand = createTypeConstraint(consBuilder, namedCons.constraint); operands.push_back(operand); + names.push_back(normalizeName(namedCons.name)); + irdl::VariadicityAttr var; if (namedCons.isOptional()) var = consBuilder.getAttr( @@ -414,11 +444,13 @@ irdl::OperationOp createIRDLOperation(OpBuilder &builder, variadicity.push_back(var); } - return std::make_tuple(operands, variadicity); + return std::make_tuple(operands, names, variadicity); }; - auto [operands, operandVariadicity] = getValues(tblgenOp.getOperands()); - auto [results, resultVariadicity] = getValues(tblgenOp.getResults()); + auto [operands, operandNames, operandVariadicity] = + getValues(tblgenOp.getOperands()); + auto [results, resultNames, resultVariadicity] = + getValues(tblgenOp.getResults()); SmallVector attributes; SmallVector attrNames; @@ -430,23 +462,28 @@ irdl::OperationOp createIRDLOperation(OpBuilder &builder, } SmallVector regions; + SmallVector regionNames; for (auto namedRegion : tblgenOp.getRegions()) { regions.push_back( createRegionConstraint(consBuilder, namedRegion.constraint)); + regionNames.push_back(normalizeName(namedRegion.name)); } // Create the operands and results operations. if (!operands.empty()) consBuilder.create(UnknownLoc::get(ctx), operands, + ArrayAttr::get(ctx, operandNames), operandVariadicity); if (!results.empty()) consBuilder.create(UnknownLoc::get(ctx), results, + ArrayAttr::get(ctx, resultNames), resultVariadicity); if (!attributes.empty()) consBuilder.create(UnknownLoc::get(ctx), attributes, ArrayAttr::get(ctx, attrNames)); if (!regions.empty()) - consBuilder.create(UnknownLoc::get(ctx), regions); + consBuilder.create(UnknownLoc::get(ctx), regions, + ArrayAttr::get(ctx, regionNames)); return op; }