[OM] Add om.map attribute (#5869)

This implement  a `om.map` attribute as constant of map types.
This commit is contained in:
Hideto Ueno 2023-08-23 13:14:17 +09:00 committed by GitHub
parent 34ded4fb5c
commit 7d0c88281d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 0 deletions

View File

@ -81,4 +81,26 @@ def OMListAttr : AttrDef<OMDialect, "List", [TypedAttrInterface]> {
}];
}
def MapAttr : AttrDef<OMDialect, "Map", [TypedAttrInterface]> {
let summary = "An attribute that represents a string map";
let mnemonic = "map";
let parameters = (ins
"mlir::Type": $valueType,
"mlir::DictionaryAttr":$elements
);
// TODO: Use custom assembly format to infer a type from elements.
let assemblyFormat = [{
`<` $valueType `,` $elements `>`
}];
let genVerifyDecl = 1;
let extraClassDeclaration = [{
mlir::Type getType();
}];
}
#endif // CIRCT_DIALECT_OM_OMATTRIBUTES_TD

View File

@ -14,6 +14,7 @@
#include "circt/Dialect/OM/OMDialect.h"
#include "circt/Dialect/OM/OMTypes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/DialectImplementation.h"
#include "llvm/ADT/TypeSwitch.h"
@ -35,6 +36,11 @@ Type circt::om::ListAttr::getType() {
return ListType::get(getContext(), getElementType());
}
Type circt::om::MapAttr::getType() {
return MapType::get(getContext(), StringType::get(getContext()),
getValueType());
}
circt::om::SymbolRefAttr circt::om::SymbolRefAttr::get(mlir::Operation *op) {
return om::SymbolRefAttr::get(op->getContext(),
mlir::FlatSymbolRefAttr::get(op));
@ -67,6 +73,24 @@ circt::om::ListAttr::verify(function_ref<InFlightDiagnostic()> emitError,
}));
}
LogicalResult
circt::om::MapAttr::verify(function_ref<InFlightDiagnostic()> emitError,
mlir::Type valueType,
mlir::DictionaryAttr elements) {
for (auto attr : elements) {
auto typedAttr = llvm::dyn_cast<mlir::TypedAttr>(attr.getValue());
if (!typedAttr)
return emitError()
<< "a value of a map attribute must be a typed attr but got "
<< attr.getValue();
if (typedAttr.getType() != valueType)
return emitError() << "a value of a map attribute must have a type "
<< valueType << " but field " << attr.getName()
<< " has " << typedAttr.getType();
}
return success();
}
void circt::om::OMDialect::registerAttributes() {
addAttributes<
#define GET_ATTRDEF_LIST

View File

@ -109,3 +109,10 @@ om.class @Tuple(%tuple: tuple<i1, !om.string>) {
// expected-error @+1 {{tuple index out-of-bounds, must be less than 2 but got 2}}
%val = om.tuple_get %tuple[2] : tuple<i1, !om.string>
}
// -----
om.class @MapConstant() {
// expected-error @+1 {{a value of a map attribute must have a type 'i64' but field "b" has '!om.list<i32>'}}
%0 = om.constant #om.map<i64, {a = 42, b = #om.list<i32, []>}> : !om.map<!om.string, i64>
}

View File

@ -183,3 +183,11 @@ om.class @Tuple(%int: i1, %str: !om.string) {
// CHECK-NEXT: om.class.field @val, %[[tuple_get]] : !om.string
om.class.field @val, %val : !om.string
}
// CHECK-LABEL: @MapConstant
om.class @MapConstant() {
// CHECK: %[[const1:.+]] = om.constant #om.map<i64, {a = 42 : i64, b = 32 : i64}> : !om.map<!om.string, i64>
%0 = om.constant #om.map<i64, {a = 42, b = 32}> : !om.map<!om.string, i64>
// CHECK: om.class.field @map_i64, %[[const1]] : !om.map<!om.string, i64>
om.class.field @map_i64, %0 : !om.map<!om.string, i64>
}