diff --git a/mlir/include/mlir/IR/Builders.h b/mlir/include/mlir/IR/Builders.h index ad59ea63a6901..5a2520b48a7b3 100644 --- a/mlir/include/mlir/IR/Builders.h +++ b/mlir/include/mlir/IR/Builders.h @@ -615,6 +615,96 @@ class OpBuilder : public Builder { Block::iterator insertPoint; }; +/// ImplicitLocOpBuilder maintains a 'current location', allowing use of the +/// create<> method without specifying the location. It is otherwise the same +/// as OpBuilder. +class ImplicitLocOpBuilder : public mlir::OpBuilder { +public: + /// OpBuilder has a bunch of convenience constructors - we support them all + /// with the additional Location. + template + ImplicitLocOpBuilder(Location loc, T &&...operands) + : OpBuilder(std::forward(operands)...), curLoc(loc) {} + + /// Create a builder and set the insertion point to before the first operation + /// in the block but still inside the block. + static ImplicitLocOpBuilder atBlockBegin(Location loc, Block *block, + Listener *listener = nullptr) { + return ImplicitLocOpBuilder(loc, block, block->begin(), listener); + } + + /// Create a builder and set the insertion point to after the last operation + /// in the block but still inside the block. + static ImplicitLocOpBuilder atBlockEnd(Location loc, Block *block, + Listener *listener = nullptr) { + return ImplicitLocOpBuilder(loc, block, block->end(), listener); + } + + /// Create a builder and set the insertion point to before the block + /// terminator. + static ImplicitLocOpBuilder atBlockTerminator(Location loc, Block *block, + Listener *listener = nullptr) { + auto *terminator = block->getTerminator(); + assert(terminator != nullptr && "the block has no terminator"); + return ImplicitLocOpBuilder(loc, block, Block::iterator(terminator), + listener); + } + + /// Accessors for the implied location. + Location getLoc() const { return curLoc; } + void setLoc(Location loc) { curLoc = loc; } + + // We allow clients to use the explicit-loc version of create as well. + using OpBuilder::create; + using OpBuilder::createOrFold; + + /// Create an operation of specific op type at the current insertion point and + /// location. + template + OpTy create(Args &&...args) { + return OpBuilder::create(curLoc, std::forward(args)...); + } + + /// Create an operation of specific op type at the current insertion point, + /// and immediately try to fold it. This functions populates 'results' with + /// the results after folding the operation. + template + void createOrFold(llvm::SmallVectorImpl &results, Args &&...args) { + OpBuilder::createOrFold(results, curLoc, std::forward(args)...); + } + + /// Overload to create or fold a single result operation. + template + std::enable_if_t(), Value> + createOrFold(Args &&...args) { + return OpBuilder::createOrFold(curLoc, std::forward(args)...); + } + + /// Overload to create or fold a zero result operation. + template + std::enable_if_t(), OpTy> + createOrFold(Args &&...args) { + return OpBuilder::createOrFold(curLoc, std::forward(args)...); + } + + /// This builder can also be used to emit diagnostics to the current location. + mlir::InFlightDiagnostic + emitError(const llvm::Twine &message = llvm::Twine()) { + return mlir::emitError(curLoc, message); + } + mlir::InFlightDiagnostic + emitWarning(const llvm::Twine &message = llvm::Twine()) { + return mlir::emitWarning(curLoc, message); + } + mlir::InFlightDiagnostic + emitRemark(const llvm::Twine &message = llvm::Twine()) { + return mlir::emitRemark(curLoc, message); + } + +private: + Location curLoc; +}; + } // namespace mlir #endif diff --git a/mlir/include/mlir/IR/ImplicitLocOpBuilder.h b/mlir/include/mlir/IR/ImplicitLocOpBuilder.h index f2985d4dd9dfc..1772dd83b29f5 100644 --- a/mlir/include/mlir/IR/ImplicitLocOpBuilder.h +++ b/mlir/include/mlir/IR/ImplicitLocOpBuilder.h @@ -15,98 +15,4 @@ #include "mlir/IR/Builders.h" -namespace mlir { - -/// ImplicitLocOpBuilder maintains a 'current location', allowing use of the -/// create<> method without specifying the location. It is otherwise the same -/// as OpBuilder. -class ImplicitLocOpBuilder : public mlir::OpBuilder { -public: - /// OpBuilder has a bunch of convenience constructors - we support them all - /// with the additional Location. - template - ImplicitLocOpBuilder(Location loc, T &&...operands) - : OpBuilder(std::forward(operands)...), curLoc(loc) {} - - /// Create a builder and set the insertion point to before the first operation - /// in the block but still inside the block. - static ImplicitLocOpBuilder atBlockBegin(Location loc, Block *block, - Listener *listener = nullptr) { - return ImplicitLocOpBuilder(loc, block, block->begin(), listener); - } - - /// Create a builder and set the insertion point to after the last operation - /// in the block but still inside the block. - static ImplicitLocOpBuilder atBlockEnd(Location loc, Block *block, - Listener *listener = nullptr) { - return ImplicitLocOpBuilder(loc, block, block->end(), listener); - } - - /// Create a builder and set the insertion point to before the block - /// terminator. - static ImplicitLocOpBuilder atBlockTerminator(Location loc, Block *block, - Listener *listener = nullptr) { - auto *terminator = block->getTerminator(); - assert(terminator != nullptr && "the block has no terminator"); - return ImplicitLocOpBuilder(loc, block, Block::iterator(terminator), - listener); - } - - /// Accessors for the implied location. - Location getLoc() const { return curLoc; } - void setLoc(Location loc) { curLoc = loc; } - - // We allow clients to use the explicit-loc version of create as well. - using OpBuilder::create; - using OpBuilder::createOrFold; - - /// Create an operation of specific op type at the current insertion point and - /// location. - template - OpTy create(Args &&...args) { - return OpBuilder::create(curLoc, std::forward(args)...); - } - - /// Create an operation of specific op type at the current insertion point, - /// and immediately try to fold it. This functions populates 'results' with - /// the results after folding the operation. - template - void createOrFold(llvm::SmallVectorImpl &results, Args &&...args) { - OpBuilder::createOrFold(results, curLoc, std::forward(args)...); - } - - /// Overload to create or fold a single result operation. - template - std::enable_if_t(), Value> - createOrFold(Args &&...args) { - return OpBuilder::createOrFold(curLoc, std::forward(args)...); - } - - /// Overload to create or fold a zero result operation. - template - std::enable_if_t(), OpTy> - createOrFold(Args &&...args) { - return OpBuilder::createOrFold(curLoc, std::forward(args)...); - } - - /// This builder can also be used to emit diagnostics to the current location. - mlir::InFlightDiagnostic - emitError(const llvm::Twine &message = llvm::Twine()) { - return mlir::emitError(curLoc, message); - } - mlir::InFlightDiagnostic - emitWarning(const llvm::Twine &message = llvm::Twine()) { - return mlir::emitWarning(curLoc, message); - } - mlir::InFlightDiagnostic - emitRemark(const llvm::Twine &message = llvm::Twine()) { - return mlir::emitRemark(curLoc, message); - } - -private: - Location curLoc; -}; - -} // namespace mlir - #endif // MLIR_IR_IMPLICITLOCOPBUILDER_H diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h index 663c256c848df..75c3aea0792ac 100644 --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -30,6 +30,7 @@ namespace mlir { class Builder; class OpBuilder; +class ImplicitLocOpBuilder; /// This class implements `Optional` functionality for ParseResult. We don't /// directly use Optional here, because it provides an implicit conversion diff --git a/mlir/include/mlir/TableGen/Class.h b/mlir/include/mlir/TableGen/Class.h index f750a34a3b2ba..ea4af074ac656 100644 --- a/mlir/include/mlir/TableGen/Class.h +++ b/mlir/include/mlir/TableGen/Class.h @@ -71,6 +71,10 @@ class MethodParameter { StringRef getName() const { return name; } /// Returns true if the parameter has a default value. bool hasDefaultValue() const { return !defaultValue.empty(); } + /// Get the default value. + StringRef getDefaultValue() const { return defaultValue; } + /// Returns true if the parameter is optional. + bool isOptional() const { return optional; } private: /// The C++ type. diff --git a/mlir/test/mlir-tblgen/op-decl-and-defs.td b/mlir/test/mlir-tblgen/op-decl-and-defs.td index 3ccefd4d82366..f213f50ae2f39 100644 --- a/mlir/test/mlir-tblgen/op-decl-and-defs.td +++ b/mlir/test/mlir-tblgen/op-decl-and-defs.td @@ -111,15 +111,33 @@ def NS_AOp : NS_Op<"a_op", [IsolatedFromAbove, IsolatedFromAbove]> { // CHECK: ::std::optional< ::llvm::APFloat > getSomeAttr2(); // CHECK: ::mlir::Attribute removeSomeAttr2Attr() { // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, Value val); +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, Value val); +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, Value val); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, int integer = 0); +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, int integer = 0); +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, int integer = 0); // CHECK{LITERAL}: [[deprecated("the deprecation message")]] // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, float something); +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, float something); +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, float something); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type r, ::mlir::TypeRange s, ::mlir::Value a, ::mlir::ValueRange b, ::mlir::IntegerAttr attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount) +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type r, ::mlir::TypeRange s, ::mlir::Value a, ::mlir::ValueRange b, ::mlir::IntegerAttr attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount) +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Type r, ::mlir::TypeRange s, ::mlir::Value a, ::mlir::ValueRange b, ::mlir::IntegerAttr attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount) // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::ValueRange b, ::mlir::IntegerAttr attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount); +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::ValueRange b, ::mlir::IntegerAttr attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount); +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::ValueRange b, ::mlir::IntegerAttr attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type r, ::mlir::TypeRange s, ::mlir::Value a, ::mlir::ValueRange b, uint32_t attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount) +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type r, ::mlir::TypeRange s, ::mlir::Value a, ::mlir::ValueRange b, uint32_t attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount) +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Type r, ::mlir::TypeRange s, ::mlir::Value a, ::mlir::ValueRange b, uint32_t attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount) // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::ValueRange b, uint32_t attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount); +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::ValueRange b, uint32_t attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount); +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::ValueRange b, uint32_t attr1, /*optional*/::mlir::FloatAttr some_attr2, unsigned someRegionsCount); // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes, unsigned numRegions) +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes, unsigned numRegions) +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes, unsigned numRegions) // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes, unsigned numRegions) +// CHECK: static AOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes, unsigned numRegions) +// CHECK: static AOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes, unsigned numRegions) // CHECK: static ::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result); // CHECK: void print(::mlir::OpAsmPrinter &p); // CHECK: ::llvm::LogicalResult verifyInvariants(); @@ -196,6 +214,8 @@ def NS_EOp : NS_Op<"op_with_optionals", []> { // CHECK: ::mlir::MutableOperandRange getAMutable(); // CHECK: ::mlir::TypedValue<::mlir::FloatType> getB() { // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, /*optional*/::mlir::Type b, /*optional*/::mlir::Value a) +// CHECK: static EOp create(::mlir::OpBuilder &builder, ::mlir::Location location, /*optional*/::mlir::Type b, /*optional*/::mlir::Value a) +// CHECK: static EOp create(::mlir::ImplicitLocOpBuilder &builder, /*optional*/::mlir::Type b, /*optional*/::mlir::Value a) // Check that all types match constraint results in generating builder. // --- @@ -214,6 +234,18 @@ def NS_FOp : NS_Op<"op_with_all_types_constraint", // DEFS: else // DEFS: ::mlir::detail::reportFatalInferReturnTypesError(odsState); +// DEFS: FOp FOp::create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Value a) { +// DEFS: ::mlir::OperationState __state__(location, getOperationName()); +// DEFS: build(builder, __state__, a); +// DEFS: auto __res__ = ::llvm::dyn_cast(builder.create(__state__)); +// DEFS: assert(__res__ && "builder didn't return the right type"); +// DEFS: return __res__; +// DEFS: } + +// DEFS: FOp FOp::create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Value a) { +// DEFS: return create(builder, builder.getLoc(), a); +// DEFS: } + def NS_GOp : NS_Op<"op_with_fixed_return_type", []> { let arguments = (ins AnyType:$a); let results = (outs I32:$b); @@ -231,9 +263,17 @@ def NS_HCollectiveParamsOp : NS_Op<"op_collective_params", []> { // CHECK-LABEL: class HCollectiveParamsOp : // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type b, ::mlir::Value a); +// CHECK: static HCollectiveParamsOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type b, ::mlir::Value a); +// CHECK: static HCollectiveParamsOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Type b, ::mlir::Value a); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value a); +// CHECK: static HCollectiveParamsOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value a); +// CHECK: static HCollectiveParamsOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value a); // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}) +// CHECK: static HCollectiveParamsOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}) +// CHECK: static HCollectiveParamsOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}) // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}) +// CHECK: static HCollectiveParamsOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}) +// CHECK: static HCollectiveParamsOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}) // Check suppression of "separate arg, separate result" build method for an op // with single variadic arg and single variadic result (since it will be @@ -245,7 +285,11 @@ def NS_HCollectiveParamsSuppress0Op : NS_Op<"op_collective_suppress0", []> { // CHECK-LABEL: class HCollectiveParamsSuppress0Op : // CHECK-NOT: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange b, ::mlir::ValueRange a); +// CHECK-NOT: static HCollectiveParamsSuppress0Op create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange b, ::mlir::ValueRange a); +// CHECK-NOT: static HCollectiveParamsSuppress0Op create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange b, ::mlir::ValueRange a); // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static HCollectiveParamsSuppress0Op create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static HCollectiveParamsSuppress0Op create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); // Check suppression of "separate arg, collective result" build method for an op // with single variadic arg and non variadic result (since it will be @@ -257,7 +301,11 @@ def NS_HCollectiveParamsSuppress1Op : NS_Op<"op_collective_suppress1", []> { // CHECK-LABEL: class HCollectiveParamsSuppress1Op : // CHECK-NOT: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange b, ::mlir::ValueRange a); +// CHECK-NOT: static HCollectiveParamsSuppress1Op create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange b, ::mlir::ValueRange a); +// CHECK-NOT: static HCollectiveParamsSuppress1Op create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange b, ::mlir::ValueRange a); // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static HCollectiveParamsSuppress1Op create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static HCollectiveParamsSuppress1Op create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); // Check suppression of "separate arg, collective result" build method for an op // with single variadic arg and > 1 variadic result (since it will be @@ -270,8 +318,14 @@ def NS_HCollectiveParamsSuppress2Op : NS_Op<"op_collective_suppress2", [SameVari } // CHECK-LABEL: class HCollectiveParamsSuppress2Op : // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange b, ::mlir::TypeRange c, ::mlir::ValueRange a); +// CHECK: static HCollectiveParamsSuppress2Op create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange b, ::mlir::TypeRange c, ::mlir::ValueRange a); +// CHECK: static HCollectiveParamsSuppress2Op create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange b, ::mlir::TypeRange c, ::mlir::ValueRange a); // CHECK-NOT: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange b, ::mlir::ValueRange a); +// CHECK-NOT: static HCollectiveParamsSuppress2Op create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange b, ::mlir::ValueRange a); +// CHECK-NOT: static HCollectiveParamsSuppress2Op create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange b, ::mlir::ValueRange a); // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static HCollectiveParamsSuppress2Op create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static HCollectiveParamsSuppress2Op create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); // Check default value of `attributes` for the `genUseOperandAsResultTypeCollectiveParamBuilder` builder def NS_IOp : NS_Op<"op_with_same_operands_and_result_types_trait", [SameOperandsAndResultType]> { @@ -280,12 +334,32 @@ def NS_IOp : NS_Op<"op_with_same_operands_and_result_types_trait", [SameOperands } // CHECK-LABEL: class IOp : // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b); +// CHECK: static IOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b); +// CHECK: static IOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Value a, ::mlir::Value b); +// CHECK: static IOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Value a, ::mlir::Value b); +// CHECK: static IOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Value a, ::mlir::Value b); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b); +// CHECK: static IOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b); +// CHECK: static IOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b); + // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static IOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static IOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static IOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static IOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static IOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static IOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static IOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static IOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); // Check default value of `attributes` for the `genInferredTypeCollectiveParamBuilder` builder def NS_JOp : NS_Op<"op_with_InferTypeOpInterface_interface", [DeclareOpInterfaceMethods]> { @@ -294,12 +368,32 @@ def NS_JOp : NS_Op<"op_with_InferTypeOpInterface_interface", [DeclareOpInterface } // CHECK-LABEL: class JOp : // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b); +// CHECK: static JOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b); +// CHECK: static JOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Value a, ::mlir::Value b); +// CHECK: static JOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Value a, ::mlir::Value b); +// CHECK: static JOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Value a, ::mlir::Value b); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b); +// CHECK: static JOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b); +// CHECK: static JOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b); + // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static JOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static JOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static JOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static JOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static JOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static JOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static JOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static JOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); // Test usage of TraitList getting flattened during emission. def NS_KOp : NS_Op<"k_op", [IsolatedFromAbove, @@ -329,15 +423,44 @@ def NS_LOp : NS_Op<"op_with_same_operands_and_result_types_unwrapped_attr", [Sam } // CHECK-LABEL: class LOp : // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b, ::mlir::IntegerAttr attr1); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Type r, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::Value a, ::mlir::Value b, uint32_t attr1); + // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); + // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); + // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static LOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); +// CHECK: static LOp create(::mlir::ImplicitLocOpBuilder &builder, ::mlir::ValueRange operands, const Properties &properties, ::llvm::ArrayRef<::mlir::NamedAttribute> discardableAttributes = {}); def NS_MOp : NS_Op<"op_with_single_result_and_fold_adaptor_fold", []> { let results = (outs AnyType:$res); diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp index cbb4030f3adb4..f35cfa6826388 100644 --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -230,6 +230,18 @@ static const char *const opCommentHeader = R"( )"; +static const char *const inlineCreateBody = R"( + ::mlir::OperationState __state__({0}, getOperationName()); + build(builder, __state__{1}); + auto __res__ = ::llvm::dyn_cast<{2}>(builder.create(__state__)); + assert(__res__ && "builder didn't return the right type"); + return __res__; +)"; + +static const char *const inlineCreateBodyImplicitLoc = R"( + return create(builder, builder.getLoc(){0}); +)"; + //===----------------------------------------------------------------------===// // Utility structs and functions //===----------------------------------------------------------------------===// @@ -665,6 +677,7 @@ class OpEmitter { // Generates the build() method that takes each operand/attribute // as a stand-alone parameter. void genSeparateArgParamBuilder(); + void genInlineCreateBody(const SmallVector ¶mList); // Generates the build() method that takes each operand/attribute as a // stand-alone parameter. The generated build() method uses first operand's @@ -2568,6 +2581,51 @@ static bool canInferType(const Operator &op) { return op.getTrait("::mlir::InferTypeOpInterface::Trait"); } +void OpEmitter::genInlineCreateBody( + const SmallVector ¶mList) { + SmallVector createParamListOpBuilder; + SmallVector createParamListImplicitLocOpBuilder; + SmallVector nonBuilderStateArgsList; + createParamListOpBuilder.emplace_back("::mlir::OpBuilder &", "builder"); + createParamListImplicitLocOpBuilder.emplace_back( + "::mlir::ImplicitLocOpBuilder &", "builder"); + std::string locParamName = "location"; + while (llvm::find_if(paramList, [&locParamName](const MethodParameter &p) { + return p.getName() == locParamName; + }) != paramList.end()) { + locParamName += "_"; + } + createParamListOpBuilder.emplace_back("::mlir::Location", locParamName); + + for (auto ¶m : paramList) { + if (param.getType() == "::mlir::OpBuilder &" || + param.getType() == "::mlir::OperationState &") + continue; + createParamListOpBuilder.emplace_back(param.getType(), param.getName(), + param.getDefaultValue(), + param.isOptional()); + createParamListImplicitLocOpBuilder.emplace_back( + param.getType(), param.getName(), param.getDefaultValue(), + param.isOptional()); + nonBuilderStateArgsList.push_back(param.getName()); + } + auto *cWithLoc = opClass.addStaticMethod(opClass.getClassName(), "create", + createParamListOpBuilder); + auto *cImplicitLoc = opClass.addStaticMethod( + opClass.getClassName(), "create", createParamListImplicitLocOpBuilder); + std::string nonBuilderStateArgs = ""; + if (!nonBuilderStateArgsList.empty()) { + llvm::raw_string_ostream nonBuilderStateArgsOS(nonBuilderStateArgs); + interleaveComma(nonBuilderStateArgsList, nonBuilderStateArgsOS); + nonBuilderStateArgs = ", " + nonBuilderStateArgs; + } + cWithLoc->body() << llvm::formatv(inlineCreateBody, locParamName, + nonBuilderStateArgs, + opClass.getClassName()); + cImplicitLoc->body() << llvm::formatv(inlineCreateBodyImplicitLoc, + nonBuilderStateArgs); +} + void OpEmitter::genSeparateArgParamBuilder() { SmallVector attrBuilderType; attrBuilderType.push_back(AttrParamKind::WrappedAttr); @@ -2584,10 +2642,12 @@ void OpEmitter::genSeparateArgParamBuilder() { buildParamList(paramList, inferredAttributes, resultNames, paramKind, attrType); - auto *m = opClass.addStaticMethod("void", "build", std::move(paramList)); + auto *m = opClass.addStaticMethod("void", "build", paramList); // If the builder is redundant, skip generating the method. if (!m) return; + genInlineCreateBody(paramList); + auto &body = m->body(); genCodeForAddingArgAndRegionForBuilder(body, inferredAttributes, /*isRawValueAttr=*/attrType == @@ -2712,10 +2772,11 @@ void OpEmitter::genUseOperandAsResultTypeCollectiveParamBuilder( if (op.getNumVariadicRegions()) paramList.emplace_back("unsigned", "numRegions"); - auto *m = opClass.addStaticMethod("void", "build", std::move(paramList)); + auto *m = opClass.addStaticMethod("void", "build", paramList); // If the builder is redundant, skip generating the method if (!m) return; + genInlineCreateBody(paramList); auto &body = m->body(); // Operands @@ -2826,10 +2887,11 @@ void OpEmitter::genInferredTypeCollectiveParamBuilder( if (op.getNumVariadicRegions()) paramList.emplace_back("unsigned", "numRegions"); - auto *m = opClass.addStaticMethod("void", "build", std::move(paramList)); + auto *m = opClass.addStaticMethod("void", "build", paramList); // If the builder is redundant, skip generating the method if (!m) return; + genInlineCreateBody(paramList); auto &body = m->body(); int numResults = op.getNumResults(); @@ -2906,10 +2968,11 @@ void OpEmitter::genUseOperandAsResultTypeSeparateParamBuilder() { buildParamList(paramList, inferredAttributes, resultNames, TypeParamKind::None, attrType); - auto *m = opClass.addStaticMethod("void", "build", std::move(paramList)); + auto *m = opClass.addStaticMethod("void", "build", paramList); // If the builder is redundant, skip generating the method if (!m) return; + genInlineCreateBody(paramList); auto &body = m->body(); genCodeForAddingArgAndRegionForBuilder(body, inferredAttributes, /*isRawValueAttr=*/attrType == @@ -2948,10 +3011,11 @@ void OpEmitter::genUseAttrAsResultTypeCollectiveParamBuilder( : "attributes"; paramList.emplace_back("::llvm::ArrayRef<::mlir::NamedAttribute>", attributesName, "{}"); - auto *m = opClass.addStaticMethod("void", "build", std::move(paramList)); + auto *m = opClass.addStaticMethod("void", "build", paramList); // If the builder is redundant, skip generating the method if (!m) return; + genInlineCreateBody(paramList); auto &body = m->body(); @@ -3039,8 +3103,7 @@ void OpEmitter::genBuilder() { std::optional body = builder.getBody(); auto properties = body ? Method::Static : Method::StaticDeclaration; - auto *method = - opClass.addMethod("void", "build", properties, std::move(arguments)); + auto *method = opClass.addMethod("void", "build", properties, arguments); if (body) ERROR_IF_PRUNED(method, "build", op); @@ -3052,6 +3115,7 @@ void OpEmitter::genBuilder() { fctx.addSubst("_state", builderOpState); if (body) method->body() << tgfmt(*body, &fctx); + genInlineCreateBody(arguments); } // Generate default builders that requires all result type, operands, and @@ -3114,10 +3178,11 @@ void OpEmitter::genCollectiveParamBuilder(CollectiveBuilderKind kind) { if (op.getNumVariadicRegions()) paramList.emplace_back("unsigned", "numRegions"); - auto *m = opClass.addStaticMethod("void", "build", std::move(paramList)); + auto *m = opClass.addStaticMethod("void", "build", paramList); // If the builder is redundant, skip generating the method if (!m) return; + genInlineCreateBody(paramList); auto &body = m->body(); // Operands