mirror of https://github.com/llvm/circt.git
[OM] Add om.map attribute (#5869)
This implement a `om.map` attribute as constant of map types.
This commit is contained in:
parent
34ded4fb5c
commit
7d0c88281d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue