From 0a95aac7c70aa607e57ee5f71b0e2d5dbc0881e7 Mon Sep 17 00:00:00 2001 From: Alex Zinenko Date: Wed, 20 Feb 2019 08:08:16 -0800 Subject: [PATCH] Allow Builder to create function-type constants A recent change made ConstantOp::build accept a NumericAttr or assert that a generic Attribute is in fact a NumericAttr. The rationale behind the change was that NumericAttrs have a type that can be used as the result type of the constant operation. FunctionAttr also has a type, and it is valid to construct function-typed constants as exercised by the parser.mlir test. Relax ConstantOp::build back to take a generic Attribute. In the overload that only takes an attribute, assert that the Attribute is either a NumericAttr or a FunctionAttr, because it is necessary to extract the type. In the overload that takes both type type and the attribute, delegate the attribute type checking to ConstantOp::verify to prevent non-Builder-based Op construction mechanisms from creating invalid IR. PiperOrigin-RevId: 234798569 --- mlir/include/mlir/IR/BuiltinOps.h | 3 +-- mlir/lib/IR/BuiltinOps.cpp | 32 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/mlir/include/mlir/IR/BuiltinOps.h b/mlir/include/mlir/IR/BuiltinOps.h index ebd55a998d0c..77594c83a448 100644 --- a/mlir/include/mlir/IR/BuiltinOps.h +++ b/mlir/include/mlir/IR/BuiltinOps.h @@ -227,8 +227,7 @@ public: /// Builds a constant op with the specified attribute value and the /// attribute's type. - static void build(Builder *builder, OperationState *result, - NumericAttr value); + static void build(Builder *builder, OperationState *result, Attribute value); Attribute getValue() const { return getAttr("value"); } diff --git a/mlir/lib/IR/BuiltinOps.cpp b/mlir/lib/IR/BuiltinOps.cpp index 5b492df2f137..32a226172f60 100644 --- a/mlir/lib/IR/BuiltinOps.cpp +++ b/mlir/lib/IR/BuiltinOps.cpp @@ -241,19 +241,28 @@ void CondBranchOp::eraseFalseOperand(unsigned index) { /// Builds a constant op with the specified attribute value and result type. void ConstantOp::build(Builder *builder, OperationState *result, Type type, Attribute value) { - auto attr = value.dyn_cast(); - assert(attr && "expected numeric value"); - assert(attr.getType() == type && "value should be of the given type"); - (void)attr; - result->addAttribute("value", value); result->types.push_back(type); } +// Extracts and returns a type of an attribute if it has one. Returns a null +// type otherwise. Currently, NumericAttrs and FunctionAttrs have types. +static Type getAttributeType(Attribute attr) { + assert(attr && "expected non-null attribute"); + if (auto numericAttr = attr.dyn_cast()) + return numericAttr.getType(); + if (auto functionAttr = attr.dyn_cast()) + return functionAttr.getType(); + return {}; +} + +/// Builds a constant of with the specified attribute value and type extracted +/// from the attribute. The attribute must have a type. void ConstantOp::build(Builder *builder, OperationState *result, - NumericAttr value) { - result->addAttribute("value", value); - result->types.push_back(value.getType()); + Attribute value) { + Type t = getAttributeType(value); + assert(t && "expected an attribute with a type"); + return build(builder, result, t, value); } void ConstantOp::print(OpAsmPrinter *p) const { @@ -334,6 +343,13 @@ bool ConstantOp::verify() const { return false; } + auto attrType = getAttributeType(value); + if (!attrType) + return emitOpError("requires 'value' attribute to have a type"); + if (attrType != type) + return emitOpError("requires the type of the 'value' attribute to match " + "that of the operation result"); + return emitOpError( "requires a result type that aligns with the 'value' attribute"); }