diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h --- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h +++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h @@ -126,7 +126,7 @@ llvm::StringRef name = {}, mlir::ValueRange shape = {}, mlir::ValueRange lenParams = {}, - llvm::ArrayRef attrs = {}); + llvm::mlir::AttributeRange attrs = {}); /// Create an unnamed and untracked temporary on the stack. mlir::Value createTemporary(mlir::Location loc, mlir::Type type, @@ -135,13 +135,13 @@ } mlir::Value createTemporary(mlir::Location loc, mlir::Type type, - llvm::ArrayRef attrs) { + llvm::mlir::AttributeRange attrs) { return createTemporary(loc, type, llvm::StringRef{}, {}, {}, attrs); } mlir::Value createTemporary(mlir::Location loc, mlir::Type type, llvm::StringRef name, - llvm::ArrayRef attrs) { + llvm::mlir::AttributeRange attrs) { return createTemporary(loc, type, name, {}, {}, attrs); } @@ -270,14 +270,12 @@ public: IfBuilder(fir::IfOp ifOp, FirOpBuilder &builder) : ifOp{ifOp}, builder{builder} {} - template - IfBuilder &genThen(CC func) { + template IfBuilder &genThen(CC func) { builder.setInsertionPointToStart(&ifOp.thenRegion().front()); func(); return *this; } - template - IfBuilder &genElse(CC func) { + template IfBuilder &genElse(CC func) { assert(!ifOp.elseRegion().empty() && "must have else region"); builder.setInsertionPointToStart(&ifOp.elseRegion().front()); func(); diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -34,7 +34,7 @@ def fir_OneResultOpBuilder : OpBuilder<(ins "mlir::Type":$resultType, "mlir::ValueRange":$operands, - CArg<"llvm::ArrayRef", "{}">:$attributes), + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes), [{ if (resultType) $_state.addTypes(resultType); @@ -214,15 +214,15 @@ OpBuilder<(ins "mlir::Type":$in_type, "llvm::StringRef":$uniq_name, "llvm::StringRef":$bindc_name, CArg<"mlir::ValueRange", "{}">:$typeparams, CArg<"mlir::ValueRange", "{}">:$shape, - CArg<"llvm::ArrayRef", "{}">:$attributes)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes)>, OpBuilder<(ins "mlir::Type":$in_type, "llvm::StringRef":$uniq_name, CArg<"mlir::ValueRange", "{}">:$typeparams, CArg<"mlir::ValueRange", "{}">:$shape, - CArg<"llvm::ArrayRef", "{}">:$attributes)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes)>, OpBuilder<(ins "mlir::Type":$in_type, CArg<"mlir::ValueRange", "{}">:$typeparams, CArg<"mlir::ValueRange", "{}">:$shape, - CArg<"llvm::ArrayRef", "{}">:$attributes)>]; + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes)>]; let verifier = "return ::verify(*this);"; @@ -522,7 +522,7 @@ "llvm::ArrayRef":$compareOperands, "llvm::ArrayRef":$destinations, CArg<"llvm::ArrayRef", "{}">:$destOperands, - CArg<"llvm::ArrayRef", "{}">:$attributes), + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes), [{ $_state.addOperands(selector); llvm::SmallVector ivalues; @@ -715,13 +715,13 @@ "llvm::ArrayRef":$cmpOperands, "llvm::ArrayRef":$destinations, CArg<"llvm::ArrayRef", "{}">:$destOperands, - CArg<"llvm::ArrayRef", "{}">:$attributes)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes)>, OpBuilder<(ins "mlir::Value":$selector, "llvm::ArrayRef":$compareAttrs, "llvm::ArrayRef":$cmpOpList, "llvm::ArrayRef":$destinations, CArg<"llvm::ArrayRef", "{}">:$destOperands, - CArg<"llvm::ArrayRef", "{}">:$attributes)>]; + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes)>]; let parser = "return parseSelectCase(parser, result);"; @@ -759,7 +759,7 @@ "llvm::ArrayRef":$typeOperands, "llvm::ArrayRef":$destinations, CArg<"llvm::ArrayRef", "{}">:$destOperands, - CArg<"llvm::ArrayRef", "{}">:$attributes)>]; + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes)>]; let parser = "return parseSelectType(parser, result);"; @@ -2133,7 +2133,7 @@ "mlir::Value":$step, CArg<"bool", "false">:$unordered, CArg<"bool", "false">:$finalCountValue, CArg<"mlir::ValueRange", "llvm::None">:$iterArgs, - CArg<"llvm::ArrayRef", "{}">:$attributes)> + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes)> ]; let extraClassDeclaration = [{ @@ -2277,7 +2277,7 @@ "mlir::Value":$step, "mlir::Value":$iterate, CArg<"bool", "false">:$finalCountValue, CArg<"mlir::ValueRange", "llvm::None">:$iterArgs, - CArg<"llvm::ArrayRef", "{}">:$attributes)> + CArg<"llvm::mlir::AttributeRange", "{}">:$attributes)> ]; let extraClassDeclaration = [{ @@ -2755,23 +2755,23 @@ let skipDefaultBuilders = 1; let builders = [ OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type, - CArg<"llvm::ArrayRef", "{}">:$attrs)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "bool":$isConstant, "mlir::Type":$type, - CArg<"llvm::ArrayRef", "{}">:$attrs)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type, CArg<"mlir::StringAttr", "{}">:$linkage, - CArg<"llvm::ArrayRef", "{}">:$attrs)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "bool":$isConstant, "mlir::Type":$type, CArg<"mlir::StringAttr", "{}">:$linkage, - CArg<"llvm::ArrayRef", "{}">:$attrs)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type, "mlir::Attribute":$initVal, CArg<"mlir::StringAttr", "{}">:$linkage, - CArg<"llvm::ArrayRef", "{}">:$attrs)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attrs)>, OpBuilder<(ins "llvm::StringRef":$name, "bool":$isConstant, "mlir::Type":$type, "mlir::Attribute":$initVal, CArg<"mlir::StringAttr", "{}">:$linkage, - CArg<"llvm::ArrayRef", "{}">:$attrs)>, + CArg<"llvm::mlir::AttributeRange", "{}">:$attrs)>, ]; let extraClassDeclaration = [{ @@ -2879,7 +2879,7 @@ let skipDefaultBuilders = 1; let builders = [ OpBuilder<(ins "llvm::StringRef":$name, "mlir::Type":$type, - CArg<"llvm::ArrayRef", "{}">:$attrs), + CArg<"llvm::mlir::AttributeRange", "{}">:$attrs), [{ $_state.addAttribute(mlir::SymbolTable::getSymbolAttrName(), $_builder.getStringAttr(name)); diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h --- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h +++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h @@ -52,12 +52,12 @@ /// FuncOp is created, and that new FuncOp is returned. mlir::FuncOp createFuncOp(mlir::Location loc, mlir::ModuleOp module, llvm::StringRef name, mlir::FunctionType type, - llvm::ArrayRef attrs = {}); + llvm::mlir::AttributeRange attrs = {}); /// Get or create a GlobalOp in a module. fir::GlobalOp createGlobalOp(mlir::Location loc, mlir::ModuleOp module, llvm::StringRef name, mlir::Type type, - llvm::ArrayRef attrs = {}); + llvm::mlir::AttributeRange attrs = {}); /// Attribute to mark Fortran entities with the CONTIGUOUS attribute. constexpr llvm::StringRef getContiguousAttrName() { return "fir.contiguous"; } diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp --- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp +++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp @@ -197,7 +197,7 @@ fir::FirOpBuilder::createTemporary(mlir::Location loc, mlir::Type type, llvm::StringRef name, mlir::ValueRange shape, mlir::ValueRange lenParams, - llvm::ArrayRef attrs) { + llvm::mlir::AttributeRange attrs) { llvm::SmallVector dynamicShape = elideExtentsAlreadyInType(type, shape); llvm::SmallVector dynamicLength = diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -169,7 +169,7 @@ mlir::OperationState &result, mlir::Type inType, llvm::StringRef uniqName, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { auto nameAttr = builder.getStringAttr(uniqName); build(builder, result, wrapAllocaResultType(inType), inType, nameAttr, {}, /*pinned=*/false, typeparams, shape); @@ -180,7 +180,7 @@ mlir::OperationState &result, mlir::Type inType, llvm::StringRef uniqName, bool pinned, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { auto nameAttr = builder.getStringAttr(uniqName); build(builder, result, wrapAllocaResultType(inType), inType, nameAttr, {}, pinned, typeparams, shape); @@ -191,7 +191,7 @@ mlir::OperationState &result, mlir::Type inType, llvm::StringRef uniqName, llvm::StringRef bindcName, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { auto nameAttr = uniqName.empty() ? mlir::StringAttr{} : builder.getStringAttr(uniqName); auto bindcAttr = @@ -206,7 +206,7 @@ llvm::StringRef uniqName, llvm::StringRef bindcName, bool pinned, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { auto nameAttr = uniqName.empty() ? mlir::StringAttr{} : builder.getStringAttr(uniqName); auto bindcAttr = @@ -219,7 +219,7 @@ void fir::AllocaOp::build(mlir::OpBuilder &builder, mlir::OperationState &result, mlir::Type inType, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { build(builder, result, wrapAllocaResultType(inType), inType, {}, {}, /*pinned=*/false, typeparams, shape); result.addAttributes(attributes); @@ -229,7 +229,7 @@ mlir::OperationState &result, mlir::Type inType, bool pinned, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { build(builder, result, wrapAllocaResultType(inType), inType, {}, {}, pinned, typeparams, shape); result.addAttributes(attributes); @@ -276,7 +276,7 @@ mlir::OperationState &result, mlir::Type inType, llvm::StringRef uniqName, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { auto nameAttr = builder.getStringAttr(uniqName); build(builder, result, wrapAllocMemResultType(inType), inType, nameAttr, {}, typeparams, shape); @@ -287,7 +287,7 @@ mlir::OperationState &result, mlir::Type inType, llvm::StringRef uniqName, llvm::StringRef bindcName, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { auto nameAttr = builder.getStringAttr(uniqName); auto bindcAttr = builder.getStringAttr(bindcName); build(builder, result, wrapAllocMemResultType(inType), inType, nameAttr, @@ -298,7 +298,7 @@ void fir::AllocMemOp::build(mlir::OpBuilder &builder, mlir::OperationState &result, mlir::Type inType, mlir::ValueRange typeparams, mlir::ValueRange shape, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { build(builder, result, wrapAllocMemResultType(inType), inType, {}, {}, typeparams, shape); result.addAttributes(attributes); @@ -470,8 +470,7 @@ //===----------------------------------------------------------------------===// // Template function used for both array_fetch and array_update verification. -template -mlir::Type validArraySubobject(A op) { +template mlir::Type validArraySubobject(A op) { auto ty = op.sequence().getType(); return fir::applyPathToType(ty, op.indices()); } @@ -646,8 +645,7 @@ // CmpOp //===----------------------------------------------------------------------===// -template -static void printCmpOp(OpAsmPrinter &p, OPTY op) { +template static void printCmpOp(OpAsmPrinter &p, OPTY op) { p << ' '; auto predSym = mlir::arith::symbolizeCmpFPredicate( op->template getAttrOfType( @@ -1233,7 +1231,7 @@ void fir::GlobalOp::build(mlir::OpBuilder &builder, OperationState &result, StringRef name, bool isConstant, Type type, Attribute initialVal, StringAttr linkage, - ArrayRef attrs) { + AttributeRange attrs) { result.addRegion(); result.addAttribute(typeAttrName(result.name), mlir::TypeAttr::get(type)); result.addAttribute(mlir::SymbolTable::getSymbolAttrName(), @@ -1251,31 +1249,30 @@ void fir::GlobalOp::build(mlir::OpBuilder &builder, OperationState &result, StringRef name, Type type, Attribute initialVal, - StringAttr linkage, ArrayRef attrs) { + StringAttr linkage, AttributeRange attrs) { build(builder, result, name, /*isConstant=*/false, type, {}, linkage, attrs); } void fir::GlobalOp::build(mlir::OpBuilder &builder, OperationState &result, StringRef name, bool isConstant, Type type, - StringAttr linkage, ArrayRef attrs) { + StringAttr linkage, AttributeRange attrs) { build(builder, result, name, isConstant, type, {}, linkage, attrs); } void fir::GlobalOp::build(mlir::OpBuilder &builder, OperationState &result, StringRef name, Type type, StringAttr linkage, - ArrayRef attrs) { + AttributeRange attrs) { build(builder, result, name, /*isConstant=*/false, type, {}, linkage, attrs); } void fir::GlobalOp::build(mlir::OpBuilder &builder, OperationState &result, StringRef name, bool isConstant, Type type, - ArrayRef attrs) { + AttributeRange attrs) { build(builder, result, name, isConstant, type, StringAttr{}, attrs); } void fir::GlobalOp::build(mlir::OpBuilder &builder, OperationState &result, - StringRef name, Type type, - ArrayRef attrs) { + StringRef name, Type type, AttributeRange attrs) { build(builder, result, name, /*isConstant=*/false, type, attrs); } @@ -1535,7 +1532,7 @@ mlir::Value ub, mlir::Value step, mlir::Value iterate, bool finalCountValue, mlir::ValueRange iterArgs, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { result.addOperands({lb, ub, step, iterate}); if (finalCountValue) { result.addTypes(builder.getIndexType()); @@ -1861,7 +1858,7 @@ mlir::OperationState &result, mlir::Value lb, mlir::Value ub, mlir::Value step, bool unordered, bool finalCountValue, mlir::ValueRange iterArgs, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { result.addOperands({lb, ub, step}); result.addOperands(iterArgs); if (finalCountValue) { @@ -2287,8 +2284,7 @@ getMutableSuccessorOperands(unsigned pos, mlir::MutableOperandRange operands, StringRef offsetAttr) { Operation *owner = operands.getOwner(); - NamedAttribute targetOffsetAttr = - *owner->getAttrDictionary().getNamed(offsetAttr); + NamedAttribute targetOffsetAttr = *owner->getNamed(offsetAttr); return getSubOperands( pos, operands, targetOffsetAttr.second.cast(), mlir::MutableOperandRange::OperandSegment(pos, targetOffsetAttr)); @@ -2486,7 +2482,7 @@ llvm::ArrayRef cmpOperands, llvm::ArrayRef destinations, llvm::ArrayRef destOperands, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { result.addOperands(selector); result.addAttribute(getCasesAttr(), builder.getArrayAttr(compareAttrs)); llvm::SmallVector operOffs; @@ -2539,7 +2535,7 @@ llvm::ArrayRef cmpOpList, llvm::ArrayRef destinations, llvm::ArrayRef destOperands, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { llvm::SmallVector cmpOpers; auto iter = cmpOpList.begin(); for (auto &attr : compareAttrs) { @@ -2750,7 +2746,7 @@ llvm::ArrayRef typeOperands, llvm::ArrayRef destinations, llvm::ArrayRef destOperands, - llvm::ArrayRef attributes) { + llvm::mlir::AttributeRange attributes) { result.addOperands(selector); result.addAttribute(getCasesAttr(), builder.getArrayAttr(typeOperands)); const auto count = destinations.size(); @@ -3195,7 +3191,7 @@ mlir::FuncOp fir::createFuncOp(mlir::Location loc, mlir::ModuleOp module, StringRef name, mlir::FunctionType type, - llvm::ArrayRef attrs) { + llvm::mlir::AttributeRange attrs) { if (auto f = module.lookupSymbol(name)) return f; mlir::OpBuilder modBuilder(module.getBodyRegion()); @@ -3207,7 +3203,7 @@ fir::GlobalOp fir::createGlobalOp(mlir::Location loc, mlir::ModuleOp module, StringRef name, mlir::Type type, - llvm::ArrayRef attrs) { + llvm::mlir::AttributeRange attrs) { if (auto g = module.lookupSymbol(name)) return g; mlir::OpBuilder modBuilder(module.getBodyRegion()); diff --git a/mlir/docs/DeclarativeRewrites.md b/mlir/docs/DeclarativeRewrites.md --- a/mlir/docs/DeclarativeRewrites.md +++ b/mlir/docs/DeclarativeRewrites.md @@ -236,8 +236,8 @@ several `build()` methods generated for it. One of them has aggregated parameters for result types, operands, and attributes in the signature: `void COp::build(..., ArrayRef resultTypes, Array operands, -ArrayRef attr)`. The pattern in the above calls this `build()` -method for constructing the `COp`. +AttributeRange attr)`. The pattern in the above calls this `build()` method for +constructing the `COp`. In general, arguments in the result pattern will be passed directly to the `build()` method to leverage the auto-generated `build()` method, list them in diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -354,8 +354,8 @@ Both operation traits, [interfaces](Interfaces.md/#utilizing-the-ods-framework), and constraints involving multiple operands/attributes/results are provided as -the third template parameter to the `Op` class. They should be deriving from -the `OpTrait` class. See [Constraints](#constraints) for more information. +the third template parameter to the `Op` class. They should be deriving from the +`OpTrait` class. See [Constraints](#constraints) for more information. ### Builder methods @@ -389,7 +389,7 @@ static void build(OpBuilder &odsBuilder, OperationState &odsState, ArrayRef resultTypes, ValueRange operands, - ArrayRef attributes); + AttributeRange attributes); // Each result-type/operand/attribute has a separate parameter. The parameters // for attributes are of mlir::Attribute types. @@ -416,7 +416,7 @@ // All operands/attributes have aggregate parameters. // Generated if return type can be inferred. static void build(OpBuilder &odsBuilder, OperationState &odsState, - ValueRange operands, ArrayRef attributes); + ValueRange operands, AttributeRange attributes); // (And manually specified builders depending on the specific op.) ``` @@ -561,7 +561,7 @@ Verification code will be automatically generated for [constraints](#constraints) specified on various entities of the op. To perform -_additional_ verification, you can use +*additional* verification, you can use ```tablegen let verifier = [{ @@ -830,13 +830,14 @@ ##### Unit Attributes -In MLIR, the [`unit` Attribute](Dialects/Builtin.md/#unitattr) is special in that it -only has one possible value, i.e. it derives meaning from its existence. When a -unit attribute is used to anchor an optional group and is not the first element -of the group, the presence of the unit attribute can be directly correlated with -the presence of the optional group itself. As such, in these situations the unit -attribute will not be printed or present in the output and will be automatically -inferred when parsing by the presence of the optional group itself. +In MLIR, the [`unit` Attribute](Dialects/Builtin.md/#unitattr) is special in +that it only has one possible value, i.e. it derives meaning from its existence. +When a unit attribute is used to anchor an optional group and is not the first +element of the group, the presence of the unit attribute can be directly +correlated with the presence of the optional group itself. As such, in these +situations the unit attribute will not be printed or present in the output and +will be automatically inferred when parsing by the presence of the optional +group itself. For example, the following operation: @@ -999,7 +1000,7 @@ #### Operand adaptors -For each operation, we automatically generate an _operand adaptor_. This class +For each operation, we automatically generate an *operand adaptor*. This class solves the problem of accessing operands provided as a list of `Value`s without using "magic" constants. The operand adaptor takes a reference to an array of `Value` and provides methods with the same names as those in the operation class @@ -1116,11 +1117,11 @@ information of the current operation. * `$_self` will be replaced with the entity this predicate is attached to. E.g., `BoolAttr` is an attribute constraint that wraps a - `CPred<"$_self.isa()">`. Then for `BoolAttr:$attr`,`$_self` will be - replaced by `$attr`. For type constraints, it's a little bit special since - we want the constraints on each type definition reads naturally and we want - to attach type constraints directly to an operand/result, `$_self` will be - replaced by the operand/result's type. E.g., for `F32` in `F32:$operand`, + `CPred<"$_self.isa()">`. Then for `BoolAttr:$attr`,`$_self` will + be replaced by `$attr`. For type constraints, it's a little bit special + since we want the constraints on each type definition reads naturally and we + want to attach type constraints directly to an operand/result, `$_self` will + be replaced by the operand/result's type. E.g., for `F32` in `F32:$operand`, its `$_self` will be expanded as `operand(...).getType()`. TODO: Reconsider the leading symbol for special placeholders. Eventually we want @@ -1199,9 +1200,9 @@ bitwidth. ODS attributes are defined as having a storage type (corresponding to a backing -`mlir::Attribute` that _stores_ the attribute), a return type (corresponding to -the C++ _return_ type of the generated helper getters) as well as a method -to convert between the internal storage and the helper method. +`mlir::Attribute` that *stores* the attribute), a return type (corresponding to +the C++ *return* type of the generated helper getters) as well as a method to +convert between the internal storage and the helper method. ### Attribute decorators @@ -1429,10 +1430,10 @@ ## Type Definitions -MLIR defines the `TypeDef` class hierarchy to enable generation of data types from -their specifications. A type is defined by specializing the `TypeDef` class with -concrete contents for all the fields it requires. For example, an integer type -could be defined as: +MLIR defines the `TypeDef` class hierarchy to enable generation of data types +from their specifications. A type is defined by specializing the `TypeDef` class +with concrete contents for all the fields it requires. For example, an integer +type could be defined as: ```tablegen // All of the types will extend this class. @@ -1680,10 +1681,10 @@ This builder is identical to the one that will be automatically generated for `MyType`. The `context` parameter is implicitly added by the generator, and is -used when building the Type instance (with `Base::get`). The distinction -here is that we can provide the implementation of this `get` method. With this -style of builder definition only the declaration is generated, the implementor -of `MyType` will need to provide a definition of `MyType::get`. +used when building the Type instance (with `Base::get`). The distinction here is +that we can provide the implementation of this `get` method. With this style of +builder definition only the declaration is generated, the implementor of +`MyType` will need to provide a definition of `MyType::get`. The second builder will generate the declaration of a builder method that looks like: diff --git a/mlir/examples/toy/Ch5/mlir/LowerToAffineLoops.cpp b/mlir/examples/toy/Ch5/mlir/LowerToAffineLoops.cpp --- a/mlir/examples/toy/Ch5/mlir/LowerToAffineLoops.cpp +++ b/mlir/examples/toy/Ch5/mlir/LowerToAffineLoops.cpp @@ -110,7 +110,8 @@ // Generate an adaptor for the remapped operands of the BinaryOp. This // allows for using the nice named accessors that are generated by the // ODS. - typename BinaryOp::Adaptor binaryAdaptor(memRefOperands); + typename BinaryOp::Adaptor binaryAdaptor(builder.getContext(), + memRefOperands); // Generate loads for the element of 'lhs' and 'rhs' at the inner // loop. @@ -253,7 +254,8 @@ // Generate an adaptor for the remapped operands of the // TransposeOp. This allows for using the nice named // accessors that are generated by the ODS. - toy::TransposeOpAdaptor transposeAdaptor(memRefOperands); + toy::TransposeOpAdaptor transposeAdaptor( + builder.getContext(), memRefOperands); Value input = transposeAdaptor.input(); // Transpose the elements by generating a load from the diff --git a/mlir/examples/toy/Ch6/mlir/LowerToAffineLoops.cpp b/mlir/examples/toy/Ch6/mlir/LowerToAffineLoops.cpp --- a/mlir/examples/toy/Ch6/mlir/LowerToAffineLoops.cpp +++ b/mlir/examples/toy/Ch6/mlir/LowerToAffineLoops.cpp @@ -110,7 +110,8 @@ // Generate an adaptor for the remapped operands of the BinaryOp. This // allows for using the nice named accessors that are generated by the // ODS. - typename BinaryOp::Adaptor binaryAdaptor(memRefOperands); + typename BinaryOp::Adaptor binaryAdaptor(builder.getContext(), + memRefOperands); // Generate loads for the element of 'lhs' and 'rhs' at the inner // loop. @@ -253,7 +254,8 @@ // Generate an adaptor for the remapped operands of the // TransposeOp. This allows for using the nice named // accessors that are generated by the ODS. - toy::TransposeOpAdaptor transposeAdaptor(memRefOperands); + toy::TransposeOpAdaptor transposeAdaptor( + builder.getContext(), memRefOperands); Value input = transposeAdaptor.input(); // Transpose the elements by generating a load from the diff --git a/mlir/examples/toy/Ch7/mlir/LowerToAffineLoops.cpp b/mlir/examples/toy/Ch7/mlir/LowerToAffineLoops.cpp --- a/mlir/examples/toy/Ch7/mlir/LowerToAffineLoops.cpp +++ b/mlir/examples/toy/Ch7/mlir/LowerToAffineLoops.cpp @@ -110,7 +110,8 @@ // Generate an adaptor for the remapped operands of the BinaryOp. This // allows for using the nice named accessors that are generated by the // ODS. - typename BinaryOp::Adaptor binaryAdaptor(memRefOperands); + typename BinaryOp::Adaptor binaryAdaptor(builder.getContext(), + memRefOperands); // Generate loads for the element of 'lhs' and 'rhs' at the inner // loop. @@ -253,7 +254,8 @@ // Generate an adaptor for the remapped operands of the // TransposeOp. This allows for using the nice named // accessors that are generated by the ODS. - toy::TransposeOpAdaptor transposeAdaptor(memRefOperands); + toy::TransposeOpAdaptor transposeAdaptor( + builder.getContext(), memRefOperands); Value input = transposeAdaptor.input(); // Transpose the elements by generating a load from the diff --git a/mlir/include/mlir/Conversion/LLVMCommon/Pattern.h b/mlir/include/mlir/Conversion/LLVMCommon/Pattern.h --- a/mlir/include/mlir/Conversion/LLVMCommon/Pattern.h +++ b/mlir/include/mlir/Conversion/LLVMCommon/Pattern.h @@ -142,8 +142,8 @@ /// Wrappers around the RewritePattern methods that pass the derived op type. void rewrite(Operation *op, ArrayRef operands, ConversionPatternRewriter &rewriter) const final { - rewrite(cast(op), OpAdaptor(operands, op->getAttrDictionary()), - rewriter); + rewrite(cast(op), + OpAdaptor(getContext(), operands, op->getAttrs()), rewriter); } LogicalResult match(Operation *op) const final { return match(cast(op)); @@ -152,7 +152,7 @@ matchAndRewrite(Operation *op, ArrayRef operands, ConversionPatternRewriter &rewriter) const final { return matchAndRewrite(cast(op), - OpAdaptor(operands, op->getAttrDictionary()), + OpAdaptor(getContext(), operands, op->getAttrs()), rewriter); } @@ -168,7 +168,7 @@ matchAndRewrite(SourceOp op, ArrayRef operands, ConversionPatternRewriter &rewriter) const { if (succeeded(match(op))) { - rewrite(op, OpAdaptor(operands, op->getAttrDictionary()), rewriter); + rewrite(op, OpAdaptor(getContext(), operands, op->getAttrs()), rewriter); return success(); } return failure(); diff --git a/mlir/include/mlir/Dialect/Async/IR/AsyncOps.td b/mlir/include/mlir/Dialect/Async/IR/AsyncOps.td --- a/mlir/include/mlir/Dialect/Async/IR/AsyncOps.td +++ b/mlir/include/mlir/Dialect/Async/IR/AsyncOps.td @@ -140,7 +140,7 @@ let builders = [ OpBuilder<(ins "Value":$operand, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, ]; let extraClassDeclaration = [{ diff --git a/mlir/include/mlir/Dialect/GPU/GPUOps.td b/mlir/include/mlir/Dialect/GPU/GPUOps.td --- a/mlir/include/mlir/Dialect/GPU/GPUOps.td +++ b/mlir/include/mlir/Dialect/GPU/GPUOps.td @@ -202,7 +202,7 @@ OpBuilder<(ins "StringRef":$name, "FunctionType":$type, CArg<"TypeRange", "{}">:$workgroupAttributions, CArg<"TypeRange", "{}">:$privateAttributions, - CArg<"ArrayRef", "{}">:$attrs)> + CArg<"AttributeRange", "{}">:$attrs)> ]; let extraClassDeclaration = [{ diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -68,7 +68,7 @@ def LLVM_OneResultOpBuilder : OpBuilder<(ins "Type":$resultType, "ValueRange":$operands, - CArg<"ArrayRef", "{}">:$attributes), + CArg<"AttributeRange", "{}">:$attributes), [{ if (resultType) $_state.addTypes(resultType); $_state.addOperands(operands); @@ -79,7 +79,7 @@ def LLVM_ZeroResultOpBuilder : OpBuilder<(ins "ValueRange":$operands, - CArg<"ArrayRef", "{}">:$attributes), + CArg<"AttributeRange", "{}">:$attributes), [{ $_state.addOperands(operands); for (auto namedAttr : attributes) { @@ -91,7 +91,7 @@ // to indicate no result. def LLVM_VoidResultTypeOpBuilder : OpBuilder<(ins "Type":$resultType, "ValueRange":$operands, - CArg<"ArrayRef", "{}">:$attributes), + CArg<"AttributeRange", "{}">:$attributes), [{ assert(isCompatibleType(resultType) && "result must be an LLVM type"); assert(resultType.isa() && @@ -103,7 +103,7 @@ // Opaque builder used for terminator operations that contain successors. def LLVM_TerminatorPassthroughOpBuilder : OpBuilder<(ins "ValueRange":$operands, "SuccessorRange":$destinations, - CArg<"ArrayRef", "{}">:$attributes), + CArg<"AttributeRange", "{}">:$attributes), [{ $_state.addOperands(operands); $_state.addSuccessors(destinations); @@ -515,7 +515,7 @@ let results = (outs Variadic); let builders = [ OpBuilder<(ins "LLVMFuncOp":$func, "ValueRange":$operands, - CArg<"ArrayRef", "{}">:$attributes), [{ + CArg<"AttributeRange", "{}">:$attributes), [{ Type resultType = func.getType().getReturnType(); if (!resultType.isa()) $_state.addTypes(resultType); @@ -544,7 +544,7 @@ }]; let builders = [ OpBuilder<(ins "Value":$vector, "Value":$position, - CArg<"ArrayRef", "{}">:$attrs)>]; + CArg<"AttributeRange", "{}">:$attrs)>]; let verifier = [{ return ::verify(*this); }]; let parser = [{ return parseExtractElementOp(parser, result); }]; let printer = [{ printExtractElementOp(p, *this); }]; @@ -600,7 +600,7 @@ }]; let builders = [ OpBuilder<(ins "Value":$v1, "Value":$v2, "ArrayAttr":$mask, - CArg<"ArrayRef", "{}">:$attrs)>]; + CArg<"AttributeRange", "{}">:$attrs)>]; let verifier = [{ auto type1 = v1().getType(); auto type2 = v2().getType(); @@ -873,7 +873,7 @@ let builders = [ OpBuilder<(ins "GlobalOp":$global, - CArg<"ArrayRef", "{}">:$attrs), + CArg<"AttributeRange", "{}">:$attrs), [{ build($_builder, $_state, LLVM::LLVMPointerType::get(global.getType(), global.addr_space()), @@ -881,7 +881,7 @@ $_state.addAttributes(attrs); }]>, OpBuilder<(ins "LLVMFuncOp":$func, - CArg<"ArrayRef", "{}">:$attrs), + CArg<"AttributeRange", "{}">:$attrs), [{ build($_builder, $_state, LLVM::LLVMPointerType::get(func.getType()), func.getName()); @@ -1122,7 +1122,7 @@ CArg<"uint64_t", "0">:$alignment, CArg<"unsigned", "0">:$addrSpace, CArg<"bool", "false">:$dsoLocal, - CArg<"ArrayRef", "{}">:$attrs)> + CArg<"AttributeRange", "{}">:$attrs)> ]; let extraClassDeclaration = [{ @@ -1258,7 +1258,7 @@ OpBuilder<(ins "StringRef":$name, "Type":$type, CArg<"Linkage", "Linkage::External">:$linkage, CArg<"bool", "false">:$dsoLocal, - CArg<"ArrayRef", "{}">:$attrs, + CArg<"AttributeRange", "{}">:$attrs, CArg<"ArrayRef", "{}">:$argAttrs)> ]; diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td --- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td +++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgOps.td @@ -123,7 +123,7 @@ build($_builder, $_state, ValueRange{}, staticShape, elementType); }]>, OpBuilder<(ins "ArrayRef":$sizes, "Type":$elementType, - CArg<"ArrayRef", "{}">:$attrs)> + CArg<"AttributeRange", "{}">:$attrs)> ]; let hasCanonicalizer = 1; @@ -313,17 +313,17 @@ OpBuilder<(ins "Value":$source, "ArrayRef":$staticLow, "ArrayRef":$staticHigh, "ValueRange":$low, "ValueRange":$high, CArg<"bool", "false">:$nofold, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a PadTensorOp with all dynamic entries. OpBuilder<(ins "Value":$source, "ValueRange":$low, "ValueRange":$high, CArg<"bool", "false">:$nofold, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a PadTensorOp with mixed static and dynamic entries and custom // result type. If the type passed is nullptr, it is inferred. OpBuilder<(ins "Type":$resultType, "Value":$source, "ArrayRef":$low, "ArrayRef":$high, CArg<"bool", "false">:$nofold, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, ]; let hasCanonicalizer = 1; @@ -365,10 +365,10 @@ // `src` and `reassociation`. OpBuilder<(ins "Value":$src, "ArrayRef":$reassociation, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, OpBuilder<(ins "Value":$src, "ArrayRef":$reassociation, - CArg<"ArrayRef", "{}">:$attrs), + CArg<"AttributeRange", "{}">:$attrs), [{ auto reassociationMaps = convertReassociationMapsToIndices($_builder, reassociation); @@ -379,7 +379,7 @@ // be either a contracting or expanding reshape. OpBuilder<(ins "Type":$resultType, "Value":$src, "ArrayRef":$reassociation, - CArg<"ArrayRef", "{}">:$attrs), + CArg<"AttributeRange", "{}">:$attrs), [{ build($_builder, $_state, resultType, src, attrs); $_state.addAttribute("reassociation", @@ -387,7 +387,7 @@ }]>, OpBuilder<(ins "Type":$resultType, "Value":$src, "ArrayRef":$reassociation, - CArg<"ArrayRef", "{}">:$attrs), + CArg<"AttributeRange", "{}">:$attrs), [{ auto reassociationMaps = convertReassociationMapsToIndices($_builder, reassociation); diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td b/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td --- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td +++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td @@ -122,7 +122,7 @@ OpBuilder<(ins "Value":$input, "Value":$output, CArg<"AffineMap", "AffineMap()">:$inputPermutation, CArg<"AffineMap", "AffineMap()">:$outputPermutation, - CArg<"ArrayRef", "{}">:$attrs)>]; + CArg<"AttributeRange", "{}">:$attrs)>]; let extraClassDeclaration = structuredOpsDecls # [{ ValueRange inputs() { return getOperands().take_front(); } @@ -338,21 +338,21 @@ "ArrayRef":$iteratorTypes, "StringRef":$doc, "StringRef":$libraryCall, CArg<"function_ref", "nullptr">, - CArg<"ArrayRef", "{}">:$attributes)>, + CArg<"AttributeRange", "{}">:$attributes)>, OpBuilder<(ins "ValueRange":$inputs, "ValueRange":$outputBuffers, "ArrayRef":$indexingMaps, "ArrayRef":$iteratorTypes, "StringRef":$doc, "StringRef":$libraryCall, CArg<"function_ref", "nullptr">, - CArg<"ArrayRef", "{}">:$attributes)>, + CArg<"AttributeRange", "{}">:$attributes)>, OpBuilder<(ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs, "ValueRange":$outputs, "ArrayRef":$indexingMaps, "ArrayRef":$iteratorTypes, CArg<"function_ref", "nullptr">, - CArg<"ArrayRef", "{}">:$attributes)>, + CArg<"AttributeRange", "{}">:$attributes)>, OpBuilder<(ins "ValueRange":$inputs, "ValueRange":$outputBuffers, "ArrayRef":$indexingMaps, "ArrayRef":$iteratorTypes, CArg<"function_ref", "nullptr">, - CArg<"ArrayRef", "{}">:$attributes)> + CArg<"AttributeRange", "{}">:$attributes)> ]; let extraClassDeclaration = structuredOpsBaseDecls # [{ diff --git a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td --- a/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td +++ b/mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td @@ -1053,17 +1053,17 @@ OpBuilder<(ins "MemRefType":$resultType, "Value":$source, "OpFoldResult":$offset, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a ReinterpretCastOp with static entries. OpBuilder<(ins "MemRefType":$resultType, "Value":$source, "int64_t":$offset, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a ReinterpretCastOp with dynamic entries. OpBuilder<(ins "MemRefType":$resultType, "Value":$source, "Value":$offset, "ValueRange":$sizes, "ValueRange":$strides, - CArg<"ArrayRef", "{}">:$attrs)> + CArg<"AttributeRange", "{}">:$attrs)> ]; let extraClassDeclaration = extraBaseClassDeclaration # [{ @@ -1170,10 +1170,10 @@ // `src` and `reassociation`. OpBuilder<(ins "Value":$src, "ArrayRef":$reassociation, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, OpBuilder<(ins "Value":$src, "ArrayRef":$reassociation, - CArg<"ArrayRef", "{}">:$attrs), + CArg<"AttributeRange", "{}">:$attrs), [{ auto reassociationMaps = convertReassociationMapsToIndices($_builder, reassociation); @@ -1184,7 +1184,7 @@ // be either a contracting or expanding reshape. OpBuilder<(ins "Type":$resultType, "Value":$src, "ArrayRef":$reassociation, - CArg<"ArrayRef", "{}">:$attrs), + CArg<"AttributeRange", "{}">:$attrs), [{ build($_builder, $_state, resultType, src, attrs); $_state.addAttribute("reassociation", @@ -1192,7 +1192,7 @@ }]>, OpBuilder<(ins "Type":$resultType, "Value":$src, "ArrayRef":$reassociation, - CArg<"ArrayRef", "{}">:$attrs), + CArg<"AttributeRange", "{}">:$attrs), [{ auto reassociationMaps = convertReassociationMapsToIndices($_builder, reassociation); @@ -1528,32 +1528,32 @@ // result type. If the type passed is nullptr, it is inferred. OpBuilder<(ins "Value":$source, "ArrayRef":$offsets, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a SubViewOp with mixed static and dynamic entries and inferred // result type. OpBuilder<(ins "MemRefType":$resultType, "Value":$source, "ArrayRef":$offsets, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a SubViewOp with static entries and custom result type. If the // type passed is nullptr, it is inferred. OpBuilder<(ins "Value":$source, "ArrayRef":$offsets, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a SubViewOp with static entries and inferred result type. OpBuilder<(ins "MemRefType":$resultType, "Value":$source, "ArrayRef":$offsets, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a SubViewOp with dynamic entries and custom result type. If the // type passed is nullptr, it is inferred. OpBuilder<(ins "Value":$source, "ValueRange":$offsets, "ValueRange":$sizes, "ValueRange":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a SubViewOp with dynamic entries and inferred result type. OpBuilder<(ins "MemRefType":$resultType, "Value":$source, "ValueRange":$offsets, "ValueRange":$sizes, "ValueRange":$strides, - CArg<"ArrayRef", "{}">:$attrs)> + CArg<"AttributeRange", "{}">:$attrs)> ]; let extraClassDeclaration = extraBaseClassDeclaration # [{ @@ -1719,7 +1719,7 @@ let builders = [ OpBuilder<(ins "Value":$in, "AffineMapAttr":$permutation, - CArg<"ArrayRef", "{}">:$attrs)>]; + CArg<"AttributeRange", "{}">:$attrs)>]; let extraClassDeclaration = [{ static StringRef getPermutationAttrName() { return "permutation"; } diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -117,7 +117,7 @@ let regions = (region AnyRegion:$region); let builders = [ - OpBuilder<(ins CArg<"ArrayRef", "{}">:$attributes)> + OpBuilder<(ins CArg<"AttributeRange", "{}">:$attributes)> ]; let parser = [{ return parseParallelOp(parser, result); }]; let printer = [{ return printParallelOp(p, *this); }]; @@ -238,7 +238,7 @@ let builders = [ OpBuilder<(ins "ValueRange":$lowerBound, "ValueRange":$upperBound, "ValueRange":$step, - CArg<"ArrayRef", "{}">:$attributes)>, + CArg<"AttributeRange", "{}">:$attributes)>, OpBuilder<(ins "TypeRange":$resultTypes, "ValueRange":$lowerBound, "ValueRange":$upperBound, "ValueRange":$step, "ValueRange":$privateVars, "ValueRange":$firstprivateVars, @@ -249,7 +249,7 @@ "IntegerAttr":$ordered_val, "StringAttr":$order_val, "UnitAttr":$inclusive, CArg<"bool", "true">:$buildBody)>, OpBuilder<(ins "TypeRange":$resultTypes, "ValueRange":$operands, - CArg<"ArrayRef", "{}">:$attributes)> + CArg<"AttributeRange", "{}">:$attributes)> ]; let regions = (region AnyRegion:$region); diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMemoryOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMemoryOps.td --- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMemoryOps.td +++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMemoryOps.td @@ -354,7 +354,7 @@ let builders = [ OpBuilder<(ins "Value":$ptr, "Value":$value, - CArg<"ArrayRef", "{}">:$namedAttrs), + CArg<"AttributeRange", "{}">:$namedAttrs), [{ $_state.addOperands(ptr); $_state.addOperands(value); diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVStructureOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVStructureOps.td --- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVStructureOps.td +++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVStructureOps.td @@ -300,7 +300,7 @@ let builders = [ OpBuilder<(ins "StringRef":$name, "FunctionType":$type, CArg<"spirv::FunctionControl", "spirv::FunctionControl::None">:$control, - CArg<"ArrayRef", "{}">:$attrs)>]; + CArg<"AttributeRange", "{}">:$attrs)>]; let hasOpcode = 0; @@ -398,7 +398,7 @@ if (initializer) $_state.addAttribute(initializerAttrName($_state.name), initializer); }]>, - OpBuilder<(ins "TypeAttr":$type, "ArrayRef":$namedAttrs), + OpBuilder<(ins "TypeAttr":$type, "AttributeRange":$namedAttrs), [{ $_state.addAttribute("type", type); $_state.addAttributes(namedAttrs); diff --git a/mlir/include/mlir/Dialect/Shape/IR/ShapeOps.td b/mlir/include/mlir/Dialect/Shape/IR/ShapeOps.td --- a/mlir/include/mlir/Dialect/Shape/IR/ShapeOps.td +++ b/mlir/include/mlir/Dialect/Shape/IR/ShapeOps.td @@ -217,7 +217,7 @@ // TODO: This should really be automatic. Figure out how to not need this defined. static ::mlir::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::llvm::Optional<::mlir::Location> location, ::mlir::ValueRange operands, - ::mlir::DictionaryAttr attributes, ::mlir::RegionRange regions, + ::mlir::AttributeRange attributes, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type>&inferredReturnTypes) { inferredReturnTypes.push_back(::mlir::IntegerType::get(context, /*width=*/1)); @@ -295,7 +295,7 @@ // TODO: This should really be automatic. Figure out how to not need this defined. static ::mlir::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::llvm::Optional<::mlir::Location> location, ::mlir::ValueRange operands, - ::mlir::DictionaryAttr attributes, ::mlir::RegionRange regions, + ::mlir::AttributeRange attributes, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type>&inferredReturnTypes) { inferredReturnTypes.push_back(::mlir::IntegerType::get(context, /*width=*/1)); @@ -925,7 +925,7 @@ // TODO: This should really be automatic. Figure out how to not need this defined. static ::mlir::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::llvm::Optional<::mlir::Location> location, ::mlir::ValueRange operands, - ::mlir::DictionaryAttr attributes, ::mlir::RegionRange regions, + ::mlir::AttributeRange attributes, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type>&inferredReturnTypes) { inferredReturnTypes.push_back(::mlir::shape::WitnessType::get(context)); return success(); @@ -959,7 +959,7 @@ // TODO: This should really be automatic. Figure out how to not need this defined. static ::mlir::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::llvm::Optional<::mlir::Location> location, ::mlir::ValueRange operands, - ::mlir::DictionaryAttr attributes, ::mlir::RegionRange regions, + ::mlir::AttributeRange attributes, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type>&inferredReturnTypes) { inferredReturnTypes.push_back(::mlir::shape::WitnessType::get(context)); return success(); diff --git a/mlir/include/mlir/Dialect/Tensor/IR/TensorOps.td b/mlir/include/mlir/Dialect/Tensor/IR/TensorOps.td --- a/mlir/include/mlir/Dialect/Tensor/IR/TensorOps.td +++ b/mlir/include/mlir/Dialect/Tensor/IR/TensorOps.td @@ -225,22 +225,22 @@ // inferred result type. OpBuilder<(ins "Value":$source, "ArrayRef":$offsets, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build an ExtractSliceOp with mixed static and dynamic entries and custom // result type. If the type passed is nullptr, it is inferred. OpBuilder<(ins "RankedTensorType":$resultType, "Value":$source, "ArrayRef":$offsets, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build an ExtractSliceOp with dynamic entries and custom result type. If // the type passed is nullptr, it is inferred. OpBuilder<(ins "Value":$source, "ValueRange":$offsets, "ValueRange":$sizes, "ValueRange":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build an ExtractSliceOp with dynamic entries and inferred result type. OpBuilder<(ins "RankedTensorType":$resultType, "Value":$source, "ValueRange":$offsets, "ValueRange":$sizes, "ValueRange":$strides, - CArg<"ArrayRef", "{}">:$attrs)> + CArg<"AttributeRange", "{}">:$attrs)> ]; let extraClassDeclaration = extraBaseClassDeclaration # [{ @@ -500,11 +500,11 @@ OpBuilder<(ins "Value":$source, "Value":$dest, "ArrayRef":$offsets, "ArrayRef":$sizes, "ArrayRef":$strides, - CArg<"ArrayRef", "{}">:$attrs)>, + CArg<"AttributeRange", "{}">:$attrs)>, // Build a InsertSliceOp with dynamic entries. OpBuilder<(ins "Value":$source, "Value":$dest, "ValueRange":$offsets, "ValueRange":$sizes, "ValueRange":$strides, - CArg<"ArrayRef", "{}">:$attrs)> + CArg<"AttributeRange", "{}">:$attrs)> ]; let extraClassDeclaration = extraBaseClassDeclaration # [{ diff --git a/mlir/include/mlir/IR/AttributeRange.h b/mlir/include/mlir/IR/AttributeRange.h new file mode 100644 --- /dev/null +++ b/mlir/include/mlir/IR/AttributeRange.h @@ -0,0 +1,179 @@ +#ifndef MLIR_IR_ATTRIBUTERANGE_H_ +#define MLIR_IR_ATTRIBUTERANGE_H_ + +#include "mlir/IR/Attributes.h" +#include "mlir/IR/Identifier.h" +#include "llvm/ADT/STLExtras.h" + +namespace mlir { +class DictionaryAttr; +class NamedAttrList; +namespace detail { +class OpAttributeList; +} // end namespace detail + +namespace impl { +template +std::pair +lookupAttributeSorted(IteratorT first, IteratorT last, StringRef name) { + auto length = std::distance(first, last); + using diff_t = decltype(length); + + while (length > 0) { + diff_t half = length / 2; + IteratorT mid = first + half; + auto c = mid->first.strref().compare(name); + if (c < 0) { + first = mid; + ++first; + length = length - half - 1; + } else if (c > 0) { + length = half; + } else { + return {mid, true}; + } + } + return {first, false}; +} + +template +std::pair +lookupAttributeSorted(IteratorT first, IteratorT last, Identifier name) { + auto it = std::find_if(first, last, [name](const NamedAttribute &attr) { + return attr.first == name; + }); + return {it, it != last}; +} + +namespace detail { +const NamedAttribute *lookupAttributeBig(ArrayRef attrs, + Identifier name); +inline const NamedAttribute * +lookupAttributeSmall(ArrayRef attrs, Identifier name) { + for (auto *it = attrs.begin(), *e = attrs.end(); it != e; ++it) { + if (it->first == name) + return it; + } + return nullptr; +} + +constexpr unsigned kSmallAttrList = 16; +} // end namespace detail + +inline const NamedAttribute * +lookupAttributeSpecial(ArrayRef attrs, Identifier name) { + return attrs.size() >= detail::kSmallAttrList + ? detail::lookupAttributeBig(attrs, name) + : detail::lookupAttributeSmall(attrs, name); +} + +inline const NamedAttribute * +lookupAttributeSubrange(ArrayRef attrs, Identifier name, + unsigned left, unsigned right) { + for (auto *it = attrs.begin() + left, *e = attrs.end() - right; + it != e; ++it) { + if (it->first == name) + return it; + } + return nullptr; +} + +template +std::pair +lookupAttributeUnsorted(IteratorT first, IteratorT last, StringRef name) { + auto it = std::find_if(first, last, [name](const NamedAttribute &attr) { + return attr.first == name; + }); + return {it, it != last}; +} + +template +std::pair +lookupAttributeUnsorted(IteratorT first, IteratorT last, Identifier name) { + return lookupAttributeSorted(first, last, name); +} +} // end namespace impl + +class AttributeRange : public ArrayRef { +public: + using Base = ArrayRef; + + AttributeRange(ArrayRef value = {}, bool sorted = false) + : Base(value), sorted(sorted) {} + + /// Conversion to AttributeRange from other ranges and containers of + /// NamedAttribute. + AttributeRange(const SmallVectorImpl &attrs, + bool sorted = false) + : Base(attrs), sorted(sorted) {} + AttributeRange(const std::vector &attrs, + bool sorted = false) + : Base(attrs), sorted(sorted) {} + AttributeRange(const llvm::NoneType) : AttributeRange() {} + AttributeRange(std::initializer_list attrs, bool sorted = false) + : Base(attrs), sorted(sorted) {} + AttributeRange(const NamedAttribute &attr) : Base(attr), sorted(false) {} + + /// Conversion to sorted AttributeRange from ranges and containers that are + /// known to be sorted. + AttributeRange(const NamedAttrList &attrs); + AttributeRange(DictionaryAttr attrs); + AttributeRange(const detail::OpAttributeList &attrs); + + bool isSorted() const { return sorted; } + + SmallVector toVector() const { + return llvm::to_vector::value>(*this); + } + +private: + std::pair lookupAttribute(StringRef name) const { + return isSorted() ? impl::lookupAttributeSorted(begin(), end(), name) + : impl::lookupAttributeUnsorted(begin(), end(), name); + } + const NamedAttribute *lookupAttrId(Identifier name) const { + return isSorted() && size() >= impl::detail::kSmallAttrList + ? impl::detail::lookupAttributeBig(*this, name) + : impl::detail::lookupAttributeSmall(*this, name); + } + +public: + /// Read-only dictionary-like operations. + Attribute get(StringRef name) const { + auto result = lookupAttribute(name); + return result.second ? result.first->second : Attribute(); + } + Attribute get(Identifier name) const { + auto *ptr = lookupAttrId(name); + return ptr ? ptr->second : Attribute(); + } + template + AttributeT getAs(NameT name) const { + return get(name).template dyn_cast_or_null(); + } + Optional getNamed(StringRef name) const { + auto result = lookupAttribute(name); + return result.second ? *result.first : Optional(); + } + Optional getNamed(Identifier name) const { + auto *ptr = lookupAttrId(name); + return ptr ? *ptr : Optional(); + } + + bool operator==(const AttributeRange &other) const { return equals(other); } + +private: + /// An attribute range created from a sorted NamedAttrList, DictionaryAttr, + /// or OpAttributeList is known to be sorted. Any operation that involves a + /// name lookup can be faster. + bool sorted = false; +}; + +inline llvm::hash_code hash_value(AttributeRange attrs) { + return llvm::hash_combine_range(attrs.begin(), attrs.end()); +} + +} // end namespace mlir + +#endif // MLIR_IR_ATTRIBUTERANGE_H_ diff --git a/mlir/include/mlir/IR/Builders.h b/mlir/include/mlir/IR/Builders.h --- a/mlir/include/mlir/IR/Builders.h +++ b/mlir/include/mlir/IR/Builders.h @@ -81,8 +81,7 @@ NoneType getNoneType(); /// Get or construct an instance of the type 'ty' with provided arguments. - template - Ty getType(Args... args) { + template Ty getType(Args... args) { return Ty::get(context, args...); } @@ -91,7 +90,7 @@ UnitAttr getUnitAttr(); BoolAttr getBoolAttr(bool value); - DictionaryAttr getDictionaryAttr(ArrayRef value); + DictionaryAttr getDictionaryAttr(AttributeRange value); IntegerAttr getIntegerAttr(Type type, int64_t value); IntegerAttr getIntegerAttr(Type type, const APInt &value); FloatAttr getFloatAttr(Type type, double value); @@ -480,8 +479,7 @@ Operation *cloneWithoutRegions(Operation &op) { return insert(op.cloneWithoutRegions()); } - template - OpT cloneWithoutRegions(OpT op) { + template OpT cloneWithoutRegions(OpT op) { return cast(cloneWithoutRegions(*op.getOperation())); } diff --git a/mlir/include/mlir/IR/BuiltinAttributes.h b/mlir/include/mlir/IR/BuiltinAttributes.h --- a/mlir/include/mlir/IR/BuiltinAttributes.h +++ b/mlir/include/mlir/IR/BuiltinAttributes.h @@ -9,6 +9,7 @@ #ifndef MLIR_IR_BUILTINATTRIBUTES_H #define MLIR_IR_BUILTINATTRIBUTES_H +#include "mlir/IR/AttributeRange.h" #include "mlir/IR/BuiltinAttributeInterfaces.h" #include "mlir/IR/SubElementInterfaces.h" #include "llvm/ADT/APFloat.h" @@ -61,8 +62,7 @@ }; /// Type trait detector that checks if a given type T is a complex type. -template -struct is_complex_t : public std::false_type {}; +template struct is_complex_t : public std::false_type {}; template struct is_complex_t> : public std::true_type {}; } // namespace detail @@ -82,8 +82,7 @@ /// floating point type that can be used to access the underlying element /// types of a DenseElementsAttr. // TODO: Use std::disjunction when C++17 is supported. - template - struct is_valid_cpp_fp_type { + template struct is_valid_cpp_fp_type { /// The type is a valid floating point type if it is a builtin floating /// point type, or is a potentially user defined floating point type. The /// latter allows for supporting users that have custom types defined for @@ -366,8 +365,7 @@ Attribute getValue(ArrayRef index) const { return getValue(index); } - template - T getValue(ArrayRef index) const { + template T getValue(ArrayRef index) const { // Skip to the element corresponding to the flattened index. return getFlatValue(ElementsAttr::getFlattenedIndex(*this, index)); } diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td --- a/mlir/include/mlir/IR/BuiltinAttributes.td +++ b/mlir/include/mlir/IR/BuiltinAttributes.td @@ -344,6 +344,12 @@ // DictionaryAttr //===----------------------------------------------------------------------===// +def AttrRangeParameter : AttrOrTypeParameter<"::mlir::AttributeRange", ""> { + let allocator = [{ + $_dst = AttributeRange($_allocator.copyInto($_self), true); + }]; +} + def Builtin_DictionaryAttr : Builtin_Attr<"Dictionary", [ DeclareAttrInterfaceMethods ]> { @@ -367,17 +373,20 @@ {int_attr = 10, "string attr name" = "string attribute"} ``` }]; - let parameters = (ins ArrayRefParameter<"NamedAttribute", "">:$value); + // TODO: DictionaryAttr should exist as an ArrayRef and only + // be converted to AttributeRange as needed, but this cannot be done with ODS + // attributes. + let parameters = (ins AttrRangeParameter:$value); let builders = [ - AttrBuilder<(ins CArg<"ArrayRef", "llvm::None">:$value)> + AttrBuilder<(ins CArg<"AttributeRange", "llvm::None">:$value)> ]; let extraClassDeclaration = [{ - using ValueType = ArrayRef; + using ValueType = AttributeRange; /// Construct a dictionary with an array of values that is known to already /// be sorted by name and uniqued. static DictionaryAttr getWithSorted(MLIRContext *context, - ArrayRef value); + AttributeRange value); /// Return the specified attribute if present, null otherwise. Attribute get(StringRef name) const; @@ -388,7 +397,7 @@ Optional getNamed(Identifier name) const; /// Support range iteration. - using iterator = llvm::ArrayRef::iterator; + using iterator = AttributeRange::iterator; iterator begin() const; iterator end() const; bool empty() const { return size() == 0; } @@ -397,7 +406,7 @@ /// Sorts the NamedAttributes in the array ordered by name as expected by /// getWithSorted and returns whether the values were sorted. /// Requires: uniquely named attributes. - static bool sort(ArrayRef values, + static bool sort(AttributeRange values, SmallVectorImpl &storage); /// Sorts the NamedAttributes in the array ordered by name as expected by diff --git a/mlir/include/mlir/IR/BuiltinOps.td b/mlir/include/mlir/IR/BuiltinOps.td --- a/mlir/include/mlir/IR/BuiltinOps.td +++ b/mlir/include/mlir/IR/BuiltinOps.td @@ -81,16 +81,16 @@ let builders = [OpBuilder<(ins "StringRef":$name, "FunctionType":$type, - CArg<"ArrayRef", "{}">:$attrs, + CArg<"AttributeRange", "{}">:$attrs, CArg<"ArrayRef", "{}">:$argAttrs) >]; let extraClassDeclaration = [{ static FuncOp create(Location location, StringRef name, FunctionType type, - ArrayRef attrs = {}); + AttributeRange attrs = {}); static FuncOp create(Location location, StringRef name, FunctionType type, Operation::dialect_attr_range attrs); static FuncOp create(Location location, StringRef name, FunctionType type, - ArrayRef attrs, + AttributeRange attrs, ArrayRef argAttrs); /// Create a deep copy of this function and all of its blocks, remapping any diff --git a/mlir/include/mlir/IR/FunctionSupport.h b/mlir/include/mlir/IR/FunctionSupport.h --- a/mlir/include/mlir/IR/FunctionSupport.h +++ b/mlir/include/mlir/IR/FunctionSupport.h @@ -57,13 +57,13 @@ void setAllResultAttrDicts(Operation *op, ArrayRef attrs); /// Return all of the attributes for the argument at 'index'. -inline ArrayRef getArgAttrs(Operation *op, unsigned index) { +inline AttributeRange getArgAttrs(Operation *op, unsigned index) { auto argDict = getArgAttrDict(op, index); return argDict ? argDict.getValue() : llvm::None; } /// Return all of the attributes for the result at 'index'. -inline ArrayRef getResultAttrs(Operation *op, unsigned index) { +inline AttributeRange getResultAttrs(Operation *op, unsigned index) { auto resultDict = getResultAttrDict(op, index); return resultDict ? resultDict.getValue() : llvm::None; } @@ -374,7 +374,7 @@ /// exist if they are non-empty. /// Return all of the attributes for the argument at 'index'. - ArrayRef getArgAttrs(unsigned index) { + AttributeRange getArgAttrs(unsigned index) { return function_like_impl::getArgAttrs(this->getOperation(), index); } @@ -415,7 +415,7 @@ } /// Set the attributes held by the argument at 'index'. - void setArgAttrs(unsigned index, ArrayRef attributes); + void setArgAttrs(unsigned index, AttributeRange attributes); /// Set the attributes held by the argument at 'index'. `attributes` may be /// null, in which case any existing argument attributes are removed. @@ -463,7 +463,7 @@ /// exist if they are non-empty. /// Return all of the attributes for the result at 'index'. - ArrayRef getResultAttrs(unsigned index) { + AttributeRange getResultAttrs(unsigned index) { return function_like_impl::getResultAttrs(this->getOperation(), index); } @@ -504,7 +504,7 @@ } /// Set the attributes held by the result at 'index'. - void setResultAttrs(unsigned index, ArrayRef attributes); + void setResultAttrs(unsigned index, AttributeRange attributes); /// Set the attributes held by the result at 'index'. `attributes` may be /// null, in which case any existing argument attributes are removed. @@ -675,8 +675,7 @@ return entry; } -template -Block *FunctionLike::addBlock() { +template Block *FunctionLike::addBlock() { assert(!empty() && "function should at least have an entry block"); push_back(new Block()); return &back(); @@ -697,8 +696,8 @@ /// Set the attributes held by the argument at 'index'. template -void FunctionLike::setArgAttrs( - unsigned index, ArrayRef attributes) { +void FunctionLike::setArgAttrs(unsigned index, + AttributeRange attributes) { assert(index < getNumArguments() && "invalid argument number"); Operation *op = this->getOperation(); return function_like_impl::detail::setArgResAttrDict( @@ -748,8 +747,8 @@ /// Set the attributes held by the result at 'index'. template -void FunctionLike::setResultAttrs( - unsigned index, ArrayRef attributes) { +void FunctionLike::setResultAttrs(unsigned index, + AttributeRange attributes) { assert(index < getNumResults() && "invalid result number"); Operation *op = this->getOperation(); return function_like_impl::detail::setArgResAttrDict( diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -2297,7 +2297,7 @@ // static void build(OpBuilder &, OperationState &odsState, // TypeRange resultTypes, // ValueRange operands, - // ArrayRef attributes); + // AttributeRange attributes); // ``` list builders = ?; diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h --- a/mlir/include/mlir/IR/OpImplementation.h +++ b/mlir/include/mlir/IR/OpImplementation.h @@ -70,8 +70,7 @@ if (types.begin() != types.end()) printArrowTypeList(types); } - template - void printArrowTypeList(TypeRange &&types) { + template void printArrowTypeList(TypeRange &&types) { auto &os = getStream() << " -> "; bool wrapped = !llvm::hasSingleElement(types) || @@ -211,7 +210,7 @@ /// You may pass omitType=true to not print a type, and pass an empty /// attribute list if you don't care for attributes. virtual void printRegionArgument(BlockArgument arg, - ArrayRef argAttrs = {}, + AttributeRange argAttrs = {}, bool omitType = false) = 0; /// Print implementations for various things an operation contains. @@ -247,13 +246,13 @@ /// dictionary with their values. elidedAttrs allows the client to ignore /// specific well known attributes, commonly used if the attribute value is /// printed some other way (like as a fixed operand). - virtual void printOptionalAttrDict(ArrayRef attrs, + virtual void printOptionalAttrDict(AttributeRange attrs, ArrayRef elidedAttrs = {}) = 0; /// If the specified operation has attributes, print out an attribute /// dictionary prefixed with 'attributes'. virtual void - printOptionalAttrDictWithKeyword(ArrayRef attrs, + printOptionalAttrDictWithKeyword(AttributeRange attrs, ArrayRef elidedAttrs = {}) = 0; /// Print the entire operation with the default generic assembly form. @@ -507,8 +506,7 @@ virtual ParseResult parseFloat(double &result) = 0; /// Parse an integer value from the stream. - template - ParseResult parseInteger(IntT &result) { + template ParseResult parseInteger(IntT &result) { auto loc = getCurrentLocation(); OptionalParseResult parseResult = parseOptionalInteger(result); if (!parseResult.hasValue()) @@ -589,14 +587,13 @@ /// unlike `OpBuilder::getType`, this method does not implicitly insert a /// context parameter. template - T getChecked(llvm::SMLoc loc, ParamsT &&... params) { + T getChecked(llvm::SMLoc loc, ParamsT &&...params) { return T::getChecked([&] { return emitError(loc); }, std::forward(params)...); } /// A variant of `getChecked` that uses the result of `getNameLoc` to emit /// errors. - template - T getChecked(ParamsT &&... params) { + template T getChecked(ParamsT &&...params) { return T::getChecked([&] { return emitError(getNameLoc()); }, std::forward(params)...); } @@ -744,8 +741,7 @@ virtual OptionalParseResult parseOptionalType(Type &result) = 0; /// Parse a type of a specific type. - template - ParseResult parseType(TypeT &result) { + template ParseResult parseType(TypeT &result) { llvm::SMLoc loc = getCurrentLocation(); // Parse any kind of type. @@ -783,8 +779,7 @@ virtual ParseResult parseColonType(Type &result) = 0; /// Parse a colon followed by a type of a specific kind, e.g. a FunctionType. - template - ParseResult parseColonType(TypeType &result) { + template ParseResult parseColonType(TypeType &result) { llvm::SMLoc loc = getCurrentLocation(); // Parse any kind of type. diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h --- a/mlir/include/mlir/IR/Operation.h +++ b/mlir/include/mlir/IR/Operation.h @@ -28,19 +28,12 @@ class alignas(8) Operation final : public llvm::ilist_node_with_parent, private llvm::TrailingObjects { + NamedAttribute, detail::OperandStorage> { public: /// Create a new Operation with the specific fields. static Operation *create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, - ArrayRef attributes, - BlockRange successors, unsigned numRegions); - - /// Overload of create that takes an existing DictionaryAttr to avoid - /// unnecessarily uniquing a list of attributes. - static Operation *create(Location location, OperationName name, - TypeRange resultTypes, ValueRange operands, - DictionaryAttr attributes, BlockRange successors, + AttributeRange attributes, BlockRange successors, unsigned numRegions); /// Create a new Operation from the fields stored in `state`. @@ -49,7 +42,7 @@ /// Create a new Operation with the specific fields. static Operation *create(Location location, OperationName name, TypeRange resultTypes, ValueRange operands, - DictionaryAttr attributes, + AttributeRange attributes, BlockRange successors = {}, RegionRange regions = {}); @@ -126,8 +119,7 @@ } /// Returns the closest surrounding parent operation with trait `Trait`. - template