forked from OSchip/llvm-project
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
This commit is contained in:
parent
0cc24bb1af
commit
0a95aac7c7
|
@ -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"); }
|
||||
|
||||
|
|
|
@ -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<NumericAttr>();
|
||||
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<NumericAttr>())
|
||||
return numericAttr.getType();
|
||||
if (auto functionAttr = attr.dyn_cast<FunctionAttr>())
|
||||
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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue