mirror of https://github.com/llvm/circt.git
[OM] Deprecate the OM Map and Tuple (#8606)
Remove the support for OM Map and Tuple. All the dependence on them have been removed. --------- Co-authored-by: Mike Urbach <mikeurbach@gmail.com>
This commit is contained in:
parent
e5603e1437
commit
2beb8e783f
|
@ -61,12 +61,6 @@ MLIR_CAPI_EXPORTED MlirTypeID omListTypeGetTypeID(void);
|
||||||
// Return a element type of a ListType.
|
// Return a element type of a ListType.
|
||||||
MLIR_CAPI_EXPORTED MlirType omListTypeGetElementType(MlirType type);
|
MLIR_CAPI_EXPORTED MlirType omListTypeGetElementType(MlirType type);
|
||||||
|
|
||||||
/// Is the Type a MapType.
|
|
||||||
MLIR_CAPI_EXPORTED bool omTypeIsAMapType(MlirType type);
|
|
||||||
|
|
||||||
// Return a key type of a MapType.
|
|
||||||
MLIR_CAPI_EXPORTED MlirType omMapTypeGetKeyType(MlirType type);
|
|
||||||
|
|
||||||
/// Is the Type a StringType.
|
/// Is the Type a StringType.
|
||||||
MLIR_CAPI_EXPORTED bool omTypeIsAStringType(MlirType type);
|
MLIR_CAPI_EXPORTED bool omTypeIsAStringType(MlirType type);
|
||||||
|
|
||||||
|
@ -187,31 +181,6 @@ omEvaluatorListGetNumElements(OMEvaluatorValue evaluatorValue);
|
||||||
MLIR_CAPI_EXPORTED OMEvaluatorValue
|
MLIR_CAPI_EXPORTED OMEvaluatorValue
|
||||||
omEvaluatorListGetElement(OMEvaluatorValue evaluatorValue, intptr_t pos);
|
omEvaluatorListGetElement(OMEvaluatorValue evaluatorValue, intptr_t pos);
|
||||||
|
|
||||||
/// Query if the EvaluatorValue is a Tuple.
|
|
||||||
MLIR_CAPI_EXPORTED bool
|
|
||||||
omEvaluatorValueIsATuple(OMEvaluatorValue evaluatorValue);
|
|
||||||
|
|
||||||
/// Get the size of the tuple.
|
|
||||||
MLIR_CAPI_EXPORTED intptr_t
|
|
||||||
omEvaluatorTupleGetNumElements(OMEvaluatorValue evaluatorValue);
|
|
||||||
|
|
||||||
/// Get an element of the tuple.
|
|
||||||
MLIR_CAPI_EXPORTED OMEvaluatorValue
|
|
||||||
omEvaluatorTupleGetElement(OMEvaluatorValue evaluatorValue, intptr_t pos);
|
|
||||||
|
|
||||||
/// Get an element of the map.
|
|
||||||
MLIR_CAPI_EXPORTED OMEvaluatorValue
|
|
||||||
omEvaluatorMapGetElement(OMEvaluatorValue evaluatorValue, MlirAttribute attr);
|
|
||||||
|
|
||||||
MLIR_CAPI_EXPORTED MlirAttribute omEvaluatorMapGetKeys(OMEvaluatorValue object);
|
|
||||||
|
|
||||||
/// Query if the EvaluatorValue is a Map.
|
|
||||||
MLIR_CAPI_EXPORTED bool omEvaluatorValueIsAMap(OMEvaluatorValue evaluatorValue);
|
|
||||||
|
|
||||||
/// Get the Type from a Map, which will be a MapType.
|
|
||||||
MLIR_CAPI_EXPORTED MlirType
|
|
||||||
omEvaluatorMapGetType(OMEvaluatorValue evaluatorValue);
|
|
||||||
|
|
||||||
/// Query if the EvaluatorValue is a BasePath.
|
/// Query if the EvaluatorValue is a BasePath.
|
||||||
MLIR_CAPI_EXPORTED bool
|
MLIR_CAPI_EXPORTED bool
|
||||||
omEvaluatorValueIsABasePath(OMEvaluatorValue evaluatorValue);
|
omEvaluatorValueIsABasePath(OMEvaluatorValue evaluatorValue);
|
||||||
|
@ -275,20 +244,6 @@ MLIR_CAPI_EXPORTED MlirAttribute omListAttrGet(MlirType elementType,
|
||||||
intptr_t numElements,
|
intptr_t numElements,
|
||||||
const MlirAttribute *elements);
|
const MlirAttribute *elements);
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// MapAttr API
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
MLIR_CAPI_EXPORTED bool omAttrIsAMapAttr(MlirAttribute attr);
|
|
||||||
|
|
||||||
MLIR_CAPI_EXPORTED intptr_t omMapAttrGetNumElements(MlirAttribute attr);
|
|
||||||
|
|
||||||
MLIR_CAPI_EXPORTED MlirIdentifier omMapAttrGetElementKey(MlirAttribute attr,
|
|
||||||
intptr_t pos);
|
|
||||||
|
|
||||||
MLIR_CAPI_EXPORTED MlirAttribute omMapAttrGetElementValue(MlirAttribute attr,
|
|
||||||
intptr_t pos);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -47,7 +47,7 @@ using ObjectFields = SmallDenseMap<StringAttr, EvaluatorValuePtr>;
|
||||||
/// the appropriate reference count.
|
/// the appropriate reference count.
|
||||||
struct EvaluatorValue : std::enable_shared_from_this<EvaluatorValue> {
|
struct EvaluatorValue : std::enable_shared_from_this<EvaluatorValue> {
|
||||||
// Implement LLVM RTTI.
|
// Implement LLVM RTTI.
|
||||||
enum class Kind { Attr, Object, List, Tuple, Map, Reference, BasePath, Path };
|
enum class Kind { Attr, Object, List, Reference, BasePath, Path };
|
||||||
EvaluatorValue(MLIRContext *ctx, Kind kind, Location loc)
|
EvaluatorValue(MLIRContext *ctx, Kind kind, Location loc)
|
||||||
: kind(kind), ctx(ctx), loc(loc) {}
|
: kind(kind), ctx(ctx), loc(loc) {}
|
||||||
Kind getKind() const { return kind; }
|
Kind getKind() const { return kind; }
|
||||||
|
@ -224,44 +224,6 @@ private:
|
||||||
SmallVector<EvaluatorValuePtr> elements;
|
SmallVector<EvaluatorValuePtr> elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A Map value.
|
|
||||||
struct MapValue : EvaluatorValue {
|
|
||||||
MapValue(om::MapType type, DenseMap<Attribute, EvaluatorValuePtr> elements,
|
|
||||||
Location loc)
|
|
||||||
: EvaluatorValue(type.getContext(), Kind::Map, loc), type(type),
|
|
||||||
elements(std::move(elements)) {
|
|
||||||
markFullyEvaluated();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partially evaluated value.
|
|
||||||
MapValue(om::MapType type, Location loc)
|
|
||||||
: EvaluatorValue(type.getContext(), Kind::Map, loc), type(type) {}
|
|
||||||
|
|
||||||
const auto &getElements() const { return elements; }
|
|
||||||
void setElements(DenseMap<Attribute, EvaluatorValuePtr> newElements) {
|
|
||||||
elements = std::move(newElements);
|
|
||||||
markFullyEvaluated();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalize the evaluator value.
|
|
||||||
LogicalResult finalizeImpl();
|
|
||||||
|
|
||||||
/// Return the type of the value, which is a MapType.
|
|
||||||
om::MapType getMapType() const { return type; }
|
|
||||||
|
|
||||||
/// Return an array of keys in the ascending order.
|
|
||||||
ArrayAttr getKeys();
|
|
||||||
|
|
||||||
/// Implement LLVM RTTI.
|
|
||||||
static bool classof(const EvaluatorValue *e) {
|
|
||||||
return e->getKind() == Kind::Map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
om::MapType type;
|
|
||||||
DenseMap<Attribute, EvaluatorValuePtr> elements;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A composite Object, which has a type and fields.
|
/// A composite Object, which has a type and fields.
|
||||||
struct ObjectValue : EvaluatorValue {
|
struct ObjectValue : EvaluatorValue {
|
||||||
ObjectValue(om::ClassOp cls, ObjectFields fields, Location loc)
|
ObjectValue(om::ClassOp cls, ObjectFields fields, Location loc)
|
||||||
|
@ -313,46 +275,6 @@ private:
|
||||||
llvm::SmallDenseMap<StringAttr, EvaluatorValuePtr> fields;
|
llvm::SmallDenseMap<StringAttr, EvaluatorValuePtr> fields;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Tuple values.
|
|
||||||
struct TupleValue : EvaluatorValue {
|
|
||||||
using TupleElements = llvm::SmallVector<EvaluatorValuePtr>;
|
|
||||||
TupleValue(TupleType type, TupleElements tupleElements, Location loc)
|
|
||||||
: EvaluatorValue(type.getContext(), Kind::Tuple, loc), type(type),
|
|
||||||
elements(std::move(tupleElements)) {
|
|
||||||
markFullyEvaluated();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partially evaluated value.
|
|
||||||
TupleValue(TupleType type, Location loc)
|
|
||||||
: EvaluatorValue(type.getContext(), Kind::Tuple, loc), type(type) {}
|
|
||||||
|
|
||||||
void setElements(TupleElements newElements) {
|
|
||||||
elements = std::move(newElements);
|
|
||||||
markFullyEvaluated();
|
|
||||||
}
|
|
||||||
|
|
||||||
LogicalResult finalizeImpl() {
|
|
||||||
for (auto &&value : elements)
|
|
||||||
if (failed(finalizeEvaluatorValue(value)))
|
|
||||||
return failure();
|
|
||||||
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
/// Implement LLVM RTTI.
|
|
||||||
static bool classof(const EvaluatorValue *e) {
|
|
||||||
return e->getKind() == Kind::Tuple;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the type of the value, which is a TupleType.
|
|
||||||
TupleType getTupleType() const { return type; }
|
|
||||||
|
|
||||||
const TupleElements &getElements() const { return elements; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
TupleType type;
|
|
||||||
TupleElements elements;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A Basepath value.
|
/// A Basepath value.
|
||||||
struct BasePathValue : EvaluatorValue {
|
struct BasePathValue : EvaluatorValue {
|
||||||
BasePathValue(MLIRContext *context);
|
BasePathValue(MLIRContext *context);
|
||||||
|
@ -493,14 +415,6 @@ private:
|
||||||
FailureOr<EvaluatorValuePtr> evaluateListConcat(ListConcatOp op,
|
FailureOr<EvaluatorValuePtr> evaluateListConcat(ListConcatOp op,
|
||||||
ActualParameters actualParams,
|
ActualParameters actualParams,
|
||||||
Location loc);
|
Location loc);
|
||||||
FailureOr<EvaluatorValuePtr>
|
|
||||||
evaluateTupleCreate(TupleCreateOp op, ActualParameters actualParams,
|
|
||||||
Location loc);
|
|
||||||
FailureOr<EvaluatorValuePtr>
|
|
||||||
evaluateTupleGet(TupleGetOp op, ActualParameters actualParams, Location loc);
|
|
||||||
FailureOr<evaluator::EvaluatorValuePtr>
|
|
||||||
evaluateMapCreate(MapCreateOp op, ActualParameters actualParams,
|
|
||||||
Location loc);
|
|
||||||
FailureOr<evaluator::EvaluatorValuePtr>
|
FailureOr<evaluator::EvaluatorValuePtr>
|
||||||
evaluateBasePathCreate(FrozenBasePathCreateOp op,
|
evaluateBasePathCreate(FrozenBasePathCreateOp op,
|
||||||
ActualParameters actualParams, Location loc);
|
ActualParameters actualParams, Location loc);
|
||||||
|
@ -543,8 +457,6 @@ operator<<(mlir::Diagnostic &diag,
|
||||||
diag << "Object(" << object->getType() << ")";
|
diag << "Object(" << object->getType() << ")";
|
||||||
else if (auto *list = llvm::dyn_cast<evaluator::ListValue>(&evaluatorValue))
|
else if (auto *list = llvm::dyn_cast<evaluator::ListValue>(&evaluatorValue))
|
||||||
diag << "List(" << list->getType() << ")";
|
diag << "List(" << list->getType() << ")";
|
||||||
else if (auto *map = llvm::dyn_cast<evaluator::MapValue>(&evaluatorValue))
|
|
||||||
diag << "Map(" << map->getType() << ")";
|
|
||||||
else if (llvm::isa<evaluator::BasePathValue>(&evaluatorValue))
|
else if (llvm::isa<evaluator::BasePathValue>(&evaluatorValue))
|
||||||
diag << "BasePath()";
|
diag << "BasePath()";
|
||||||
else if (llvm::isa<evaluator::PathValue>(&evaluatorValue))
|
else if (llvm::isa<evaluator::PathValue>(&evaluatorValue))
|
||||||
|
|
|
@ -81,28 +81,6 @@ 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();
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
def OMPathAttr : AttrDef<OMDialect, "Path"> {
|
def OMPathAttr : AttrDef<OMDialect, "Path"> {
|
||||||
let summary = "An attribute that represents an instance path";
|
let summary = "An attribute that represents an instance path";
|
||||||
|
|
||||||
|
|
|
@ -280,94 +280,6 @@ def ListConcatOp : OMOp<"list_concat", [Pure, SameOperandsAndResultType]> {
|
||||||
let assemblyFormat = "$subLists attr-dict `:` type($result)";
|
let assemblyFormat = "$subLists attr-dict `:` type($result)";
|
||||||
}
|
}
|
||||||
|
|
||||||
def TupleCreateOp : OMOp<"tuple_create", [Pure, InferTypeOpInterface]> {
|
|
||||||
let summary = "Create a tuple of values";
|
|
||||||
let description = [{
|
|
||||||
Create a tuple from a sequence of inputs.
|
|
||||||
|
|
||||||
```
|
|
||||||
%tuple = om.tuple_create %a, %b, %c : !om.ref, !om.string, !om.list<i32>
|
|
||||||
```
|
|
||||||
}];
|
|
||||||
|
|
||||||
let arguments = (ins Variadic<AnyType>:$inputs);
|
|
||||||
let results = (outs
|
|
||||||
TupleOf<[AnyType]>:$result
|
|
||||||
);
|
|
||||||
|
|
||||||
let assemblyFormat = [{
|
|
||||||
$inputs attr-dict `:` type($inputs)
|
|
||||||
}];
|
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
|
||||||
// Implement InferTypeOpInterface.
|
|
||||||
static ::mlir::LogicalResult inferReturnTypes(
|
|
||||||
::mlir::MLIRContext *context, ::std::optional<::mlir::Location> location,
|
|
||||||
::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes,
|
|
||||||
::mlir::OpaqueProperties,
|
|
||||||
::mlir::RegionRange regions,
|
|
||||||
::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes);
|
|
||||||
}];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
def TupleGetOp : OMOp<"tuple_get", [Pure, InferTypeOpInterface]> {
|
|
||||||
let summary = "Extract a value from a tuple";
|
|
||||||
let description = [{
|
|
||||||
Extract a value from a tuple.
|
|
||||||
|
|
||||||
```
|
|
||||||
%value = om.tuple_get %a[0] : tuple<!om.ref, !om.string, !om.list<i32>>
|
|
||||||
```
|
|
||||||
}];
|
|
||||||
|
|
||||||
let arguments = (ins
|
|
||||||
TupleOf<[AnyType]>:$input,
|
|
||||||
I32Attr:$index
|
|
||||||
);
|
|
||||||
|
|
||||||
let results = (outs
|
|
||||||
AnyType:$result
|
|
||||||
);
|
|
||||||
|
|
||||||
let assemblyFormat = [{
|
|
||||||
$input `[` $index `]` attr-dict `:` type($input)
|
|
||||||
}];
|
|
||||||
|
|
||||||
let extraClassDeclaration = [{
|
|
||||||
// Implement InferTypeOpInterface.
|
|
||||||
static ::mlir::LogicalResult inferReturnTypes(
|
|
||||||
::mlir::MLIRContext *context, ::std::optional<::mlir::Location> location,
|
|
||||||
::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes,
|
|
||||||
::mlir::OpaqueProperties, ::mlir::RegionRange regions,
|
|
||||||
::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes);
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
def MapKeyValuePair: Type<CPred<"::circt::om::isMapKeyValuePairType($_self)">,
|
|
||||||
"a pair whose first element is an attribute",
|
|
||||||
"::mlir::TupleType">;
|
|
||||||
|
|
||||||
def MapCreateOp : OMOp<"map_create", [Pure, SameTypeOperands]> {
|
|
||||||
let summary = "Create a map";
|
|
||||||
let description = [{
|
|
||||||
Creates a map from a sequence of inputs.
|
|
||||||
|
|
||||||
```
|
|
||||||
%map = om.map_create %e1, %e2 : !om.string, i8
|
|
||||||
```
|
|
||||||
where `%e1` and `e2` have !om.tuple<!om.string, i8> and
|
|
||||||
`%map` has `!om.map<!om.string, i8>` type.
|
|
||||||
}];
|
|
||||||
|
|
||||||
let arguments = (ins Variadic<MapKeyValuePair>:$inputs);
|
|
||||||
let results = (outs
|
|
||||||
MapType:$result
|
|
||||||
);
|
|
||||||
|
|
||||||
let hasCustomAssemblyFormat = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
def BasePathCreateOp : OMOp<"basepath_create", [Pure,
|
def BasePathCreateOp : OMOp<"basepath_create", [Pure,
|
||||||
DeclareOpInterfaceMethods<SymbolUserOpInterface>
|
DeclareOpInterfaceMethods<SymbolUserOpInterface>
|
||||||
]> {
|
]> {
|
||||||
|
|
|
@ -16,12 +16,7 @@
|
||||||
#include "mlir/IR/BuiltinAttributes.h"
|
#include "mlir/IR/BuiltinAttributes.h"
|
||||||
#include "mlir/IR/Types.h"
|
#include "mlir/IR/Types.h"
|
||||||
|
|
||||||
namespace circt::om {
|
namespace circt::om {} // namespace circt::om
|
||||||
// Return true if the type is a pair whose first element is either string or
|
|
||||||
// integer.
|
|
||||||
bool isMapKeyValuePairType(mlir::Type);
|
|
||||||
|
|
||||||
} // namespace circt::om
|
|
||||||
|
|
||||||
#define GET_TYPEDEF_CLASSES
|
#define GET_TYPEDEF_CLASSES
|
||||||
#include "circt/Dialect/OM/OMTypes.h.inc"
|
#include "circt/Dialect/OM/OMTypes.h.inc"
|
||||||
|
|
|
@ -51,25 +51,6 @@ def ListType : TypeDef<OMDialect, "List", []> {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
def MapType : TypeDef<OMDialect, "Map", []> {
|
|
||||||
let summary = [{A type that represents a map. A key type must be either
|
|
||||||
an integer or string type}];
|
|
||||||
|
|
||||||
let mnemonic = "map";
|
|
||||||
let parameters = (ins "mlir::Type": $keyType, "mlir::Type":$valueType);
|
|
||||||
let assemblyFormat = [{
|
|
||||||
`<` $keyType `,` $valueType `>`
|
|
||||||
}];
|
|
||||||
|
|
||||||
let builders = [
|
|
||||||
AttrBuilderWithInferredContext<(ins "::mlir::Type":$keyType, "::mlir::Type":$valueType), [{
|
|
||||||
return $_get(keyType.getContext(), keyType, valueType);
|
|
||||||
}]>
|
|
||||||
];
|
|
||||||
|
|
||||||
let genVerifyDecl = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
def SymbolRefType : TypeDef<OMDialect, "SymbolRef", []> {
|
def SymbolRefType : TypeDef<OMDialect, "SymbolRef", []> {
|
||||||
let summary = "A type that represents a reference to a flat symbol reference.";
|
let summary = "A type that represents a reference to a flat symbol reference.";
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ with Context() as ctx, Location.unknown():
|
||||||
om.class.fields %2, %0, %0 : !om.class.type<@comp>, !om.class.type<@node>, !om.class.type<@node>
|
om.class.fields %2, %0, %0 : !om.class.type<@comp>, !om.class.type<@node>, !om.class.type<@node>
|
||||||
}
|
}
|
||||||
|
|
||||||
om.class @Test(%param: !om.integer) -> (field: !om.integer, child: !om.class.type<@Child>, reference: !om.ref, list: !om.list<!om.string>, tuple: tuple<!om.list<!om.string>, !om.integer>, nest: !om.class.type<@Nest>, map: !om.map<!om.string, !om.integer>, map_create: !om.map<!om.string, !om.integer>, true: i1, false: i1) {
|
om.class @Test(%param: !om.integer) -> (field: !om.integer, child: !om.class.type<@Child>, reference: !om.ref, list: !om.list<!om.string>, nest: !om.class.type<@Nest>, true: i1, false: i1) {
|
||||||
%sym = om.constant #om.ref<<@Root::@x>> : !om.ref
|
%sym = om.constant #om.ref<<@Root::@x>> : !om.ref
|
||||||
|
|
||||||
%c_14 = om.constant #om.integer<14> : !om.integer
|
%c_14 = om.constant #om.integer<14> : !om.integer
|
||||||
|
@ -42,26 +42,18 @@ with Context() as ctx, Location.unknown():
|
||||||
|
|
||||||
%list = om.constant #om.list<!om.string, ["X" : !om.string, "Y" : !om.string]> : !om.list<!om.string>
|
%list = om.constant #om.list<!om.string, ["X" : !om.string, "Y" : !om.string]> : !om.list<!om.string>
|
||||||
|
|
||||||
%tuple = om.tuple_create %list, %c_14: !om.list<!om.string>, !om.integer
|
|
||||||
|
|
||||||
%c_15 = om.constant #om.integer<15> : !om.integer
|
%c_15 = om.constant #om.integer<15> : !om.integer
|
||||||
%1 = om.object @Child(%c_15) : (!om.integer) -> !om.class.type<@Child>
|
%1 = om.object @Child(%c_15) : (!om.integer) -> !om.class.type<@Child>
|
||||||
%list_child = om.list_create %0, %1: !om.class.type<@Child>
|
%list_child = om.list_create %0, %1: !om.class.type<@Child>
|
||||||
%2 = om.object @Nest(%list_child) : (!om.list<!om.class.type<@Child>>) -> !om.class.type<@Nest>
|
%2 = om.object @Nest(%list_child) : (!om.list<!om.class.type<@Child>>) -> !om.class.type<@Nest>
|
||||||
|
|
||||||
%3 = om.constant #om.map<!om.integer, {a = #om.integer<42>, b = #om.integer<32>}> : !om.map<!om.string, !om.integer>
|
|
||||||
|
|
||||||
%x = om.constant "X" : !om.string
|
|
||||||
%y = om.constant "Y" : !om.string
|
|
||||||
%entry1 = om.tuple_create %x, %c_14: !om.string, !om.integer
|
|
||||||
%entry2 = om.tuple_create %y, %c_15: !om.string, !om.integer
|
|
||||||
|
|
||||||
%map = om.map_create %entry1, %entry2: !om.string, !om.integer
|
|
||||||
|
|
||||||
%true = om.constant true
|
%true = om.constant true
|
||||||
%false = om.constant false
|
%false = om.constant false
|
||||||
|
|
||||||
om.class.fields %param, %0, %sym, %list, %tuple, %2, %3, %map, %true, %false : !om.integer, !om.class.type<@Child>, !om.ref, !om.list<!om.string>, tuple<!om.list<!om.string>, !om.integer>, !om.class.type<@Nest>, !om.map<!om.string, !om.integer>, !om.map<!om.string, !om.integer>, i1, i1
|
om.class.fields %param, %0, %sym, %list, %2, %true, %false : !om.integer, !om.class.type<@Child>, !om.ref, !om.list<!om.string>, !om.class.type<@Nest>, i1, i1
|
||||||
}
|
}
|
||||||
|
|
||||||
om.class @Child(%0: !om.integer) -> (foo: !om.integer) {
|
om.class @Child(%0: !om.integer) -> (foo: !om.integer) {
|
||||||
|
@ -158,21 +150,6 @@ print("child.foo: ", obj.child.foo)
|
||||||
print("child.foo.loc", obj.child.get_field_loc("foo"))
|
print("child.foo.loc", obj.child.get_field_loc("foo"))
|
||||||
# CHECK: ('Root', 'x')
|
# CHECK: ('Root', 'x')
|
||||||
print(obj.reference)
|
print(obj.reference)
|
||||||
(fst, snd) = obj.tuple
|
|
||||||
# CHECK: 14
|
|
||||||
print(snd)
|
|
||||||
|
|
||||||
# CHECK: loc("-":{{.*}}:{{.*}})
|
|
||||||
print("tuple", obj.get_field_loc("tuple"))
|
|
||||||
|
|
||||||
# CHECK: loc("-":{{.*}}:{{.*}})
|
|
||||||
print(obj.loc)
|
|
||||||
|
|
||||||
try:
|
|
||||||
print(obj.tuple[3])
|
|
||||||
except IndexError as e:
|
|
||||||
# CHECK: tuple index out of range
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
for (name, field) in obj:
|
for (name, field) in obj:
|
||||||
# location from om.class.field @child, %0 : !om.class.type<@Child>
|
# location from om.class.field @child, %0 : !om.class.type<@Child>
|
||||||
|
@ -196,38 +173,6 @@ for child in obj.nest.list_child:
|
||||||
# CHECK-NEXT: 15
|
# CHECK-NEXT: 15
|
||||||
print(child.foo)
|
print(child.foo)
|
||||||
|
|
||||||
# CHECK: 2
|
|
||||||
print(len(obj.map))
|
|
||||||
# CHECK: {'a': 42, 'b': 32}
|
|
||||||
print(obj.map)
|
|
||||||
for k, v in obj.map.items():
|
|
||||||
# CHECK-NEXT: a 42
|
|
||||||
# CHECK-NEXT: b 32
|
|
||||||
print(k, v)
|
|
||||||
|
|
||||||
try:
|
|
||||||
print(obj.map_create[1])
|
|
||||||
except KeyError as e:
|
|
||||||
# CHECK-NEXT: 'key is not integer'
|
|
||||||
print(e)
|
|
||||||
try:
|
|
||||||
print(obj.map_create["INVALID"])
|
|
||||||
except KeyError as e:
|
|
||||||
# CHECK-NEXT: 'key not found'
|
|
||||||
print(e)
|
|
||||||
# CHECK-NEXT: 14
|
|
||||||
print(obj.map_create["X"])
|
|
||||||
|
|
||||||
for k, v in obj.map_create.items():
|
|
||||||
# CHECK-NEXT: X 14
|
|
||||||
# CHECK-NEXT: Y 15
|
|
||||||
print(k, v)
|
|
||||||
|
|
||||||
# CHECK: True
|
|
||||||
print(obj.true)
|
|
||||||
# CHECK: False
|
|
||||||
print(obj.false)
|
|
||||||
|
|
||||||
obj = evaluator.instantiate("Client")
|
obj = evaluator.instantiate("Client")
|
||||||
object_dict: Dict[om.Object, str] = {}
|
object_dict: Dict[om.Object, str] = {}
|
||||||
for field_name, data in obj:
|
for field_name, data in obj:
|
||||||
|
|
|
@ -26,8 +26,6 @@ namespace {
|
||||||
|
|
||||||
struct List;
|
struct List;
|
||||||
struct Object;
|
struct Object;
|
||||||
struct Tuple;
|
|
||||||
struct Map;
|
|
||||||
struct BasePath;
|
struct BasePath;
|
||||||
struct Path;
|
struct Path;
|
||||||
|
|
||||||
|
@ -42,8 +40,8 @@ using PythonPrimitive = std::variant<nb::int_, nb::float_, nb::str, nb::bool_,
|
||||||
/// MlirAttribute and the upstream MLIR type casters. If the MlirAttribute
|
/// MlirAttribute and the upstream MLIR type casters. If the MlirAttribute
|
||||||
/// is tried first, then we can hit an assert inside the MLIR codebase.
|
/// is tried first, then we can hit an assert inside the MLIR codebase.
|
||||||
struct None {};
|
struct None {};
|
||||||
using PythonValue = std::variant<None, Object, List, Tuple, Map, BasePath, Path,
|
using PythonValue =
|
||||||
PythonPrimitive>;
|
std::variant<None, Object, List, BasePath, Path, PythonPrimitive>;
|
||||||
|
|
||||||
/// Map an opaque OMEvaluatorValue into a python value.
|
/// Map an opaque OMEvaluatorValue into a python value.
|
||||||
PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result);
|
PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result);
|
||||||
|
@ -69,58 +67,6 @@ private:
|
||||||
OMEvaluatorValue value;
|
OMEvaluatorValue value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Tuple {
|
|
||||||
// Instantiate a Tuple with a reference to the underlying OMEvaluatorValue.
|
|
||||||
Tuple(OMEvaluatorValue value) : value(value) {}
|
|
||||||
|
|
||||||
/// Return the number of elements.
|
|
||||||
intptr_t getNumElements() { return omEvaluatorTupleGetNumElements(value); }
|
|
||||||
|
|
||||||
PythonValue getElement(intptr_t i);
|
|
||||||
OMEvaluatorValue getValue() const { return value; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The underlying CAPI value.
|
|
||||||
OMEvaluatorValue value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Provides a Map class by simply wrapping the OMObject CAPI.
|
|
||||||
struct Map {
|
|
||||||
// Instantiate a Map with a reference to the underlying OMEvaluatorValue.
|
|
||||||
Map(OMEvaluatorValue value) : value(value) {}
|
|
||||||
|
|
||||||
/// Return the keys.
|
|
||||||
std::vector<nb::str> getKeys() {
|
|
||||||
auto attr = omEvaluatorMapGetKeys(value);
|
|
||||||
intptr_t numFieldNames = mlirArrayAttrGetNumElements(attr);
|
|
||||||
|
|
||||||
std::vector<nb::str> pyFieldNames;
|
|
||||||
for (intptr_t i = 0; i < numFieldNames; ++i) {
|
|
||||||
auto name = mlirStringAttrGetValue(mlirArrayAttrGetElement(attr, i));
|
|
||||||
pyFieldNames.emplace_back(nb::str(name.data, name.length));
|
|
||||||
}
|
|
||||||
|
|
||||||
return pyFieldNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Look up the value. A key is an integer, string or attribute.
|
|
||||||
PythonValue dunderGetItemAttr(MlirAttribute key);
|
|
||||||
PythonValue dunderGetItemNamed(const std::string &key);
|
|
||||||
PythonValue dunderGetItemIndexed(intptr_t key);
|
|
||||||
PythonValue
|
|
||||||
dunderGetItem(std::variant<intptr_t, std::string, MlirAttribute> key);
|
|
||||||
|
|
||||||
/// Return a context from an underlying value.
|
|
||||||
MlirContext getContext() const { return omEvaluatorValueGetContext(value); }
|
|
||||||
|
|
||||||
OMEvaluatorValue getValue() const { return value; }
|
|
||||||
MlirType getType() { return omEvaluatorMapGetType(value); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The underlying CAPI value.
|
|
||||||
OMEvaluatorValue value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Provides a BasePath class by simply wrapping the OMObject CAPI.
|
/// Provides a BasePath class by simply wrapping the OMObject CAPI.
|
||||||
struct BasePath {
|
struct BasePath {
|
||||||
/// Instantiate a BasePath with a reference to the underlying
|
/// Instantiate a BasePath with a reference to the underlying
|
||||||
|
@ -289,80 +235,6 @@ private:
|
||||||
PythonValue List::getElement(intptr_t i) {
|
PythonValue List::getElement(intptr_t i) {
|
||||||
return omEvaluatorValueToPythonValue(omEvaluatorListGetElement(value, i));
|
return omEvaluatorValueToPythonValue(omEvaluatorListGetElement(value, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
class PyMapAttrIterator {
|
|
||||||
public:
|
|
||||||
PyMapAttrIterator(MlirAttribute attr) : attr(std::move(attr)) {}
|
|
||||||
|
|
||||||
PyMapAttrIterator &dunderIter() { return *this; }
|
|
||||||
|
|
||||||
nb::tuple dunderNext() {
|
|
||||||
if (nextIndex >= omMapAttrGetNumElements(attr))
|
|
||||||
throw nb::stop_iteration();
|
|
||||||
|
|
||||||
MlirIdentifier key = omMapAttrGetElementKey(attr, nextIndex);
|
|
||||||
PythonValue value =
|
|
||||||
omPrimitiveToPythonValue(omMapAttrGetElementValue(attr, nextIndex));
|
|
||||||
nextIndex++;
|
|
||||||
|
|
||||||
auto keyName = mlirIdentifierStr(key);
|
|
||||||
std::string keyStr(keyName.data, keyName.length);
|
|
||||||
return nb::make_tuple(keyStr, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bind(nb::module_ &m) {
|
|
||||||
nb::class_<PyMapAttrIterator>(m, "MapAttributeIterator")
|
|
||||||
.def("__iter__", &PyMapAttrIterator::dunderIter)
|
|
||||||
.def("__next__", &PyMapAttrIterator::dunderNext);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
MlirAttribute attr;
|
|
||||||
intptr_t nextIndex = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
PythonValue Tuple::getElement(intptr_t i) {
|
|
||||||
if (i < 0 || i >= omEvaluatorTupleGetNumElements(value))
|
|
||||||
throw std::out_of_range("tuple index out of range");
|
|
||||||
|
|
||||||
return omEvaluatorValueToPythonValue(omEvaluatorTupleGetElement(value, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
PythonValue Map::dunderGetItemNamed(const std::string &key) {
|
|
||||||
MlirType type = omMapTypeGetKeyType(omEvaluatorMapGetType(value));
|
|
||||||
if (!omTypeIsAStringType(type))
|
|
||||||
throw nanobind::key_error("key is not string");
|
|
||||||
MlirAttribute attr =
|
|
||||||
mlirStringAttrTypedGet(type, mlirStringRefCreateFromCString(key.c_str()));
|
|
||||||
return dunderGetItemAttr(attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
PythonValue Map::dunderGetItemIndexed(intptr_t i) {
|
|
||||||
MlirType type = omMapTypeGetKeyType(omEvaluatorMapGetType(value));
|
|
||||||
if (!mlirTypeIsAInteger(type))
|
|
||||||
throw nanobind::key_error("key is not integer");
|
|
||||||
MlirAttribute attr = mlirIntegerAttrGet(type, i);
|
|
||||||
return dunderGetItemAttr(attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
PythonValue Map::dunderGetItemAttr(MlirAttribute key) {
|
|
||||||
OMEvaluatorValue result = omEvaluatorMapGetElement(value, key);
|
|
||||||
|
|
||||||
if (omEvaluatorValueIsNull(result))
|
|
||||||
throw nanobind::key_error("key not found");
|
|
||||||
|
|
||||||
return omEvaluatorValueToPythonValue(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
PythonValue
|
|
||||||
Map::dunderGetItem(std::variant<intptr_t, std::string, MlirAttribute> key) {
|
|
||||||
if (auto *i = std::get_if<intptr_t>(&key))
|
|
||||||
return dunderGetItemIndexed(*i);
|
|
||||||
else if (auto *str = std::get_if<std::string>(&key))
|
|
||||||
return dunderGetItemNamed(*str);
|
|
||||||
return dunderGetItemAttr(std::get<MlirAttribute>(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert a generic MLIR Attribute to a PythonValue. This is basically a C++
|
// Convert a generic MLIR Attribute to a PythonValue. This is basically a C++
|
||||||
// fast path of the parts of attribute_to_var that we use in the OM dialect.
|
// fast path of the parts of attribute_to_var that we use in the OM dialect.
|
||||||
static PythonPrimitive omPrimitiveToPythonValue(MlirAttribute attr) {
|
static PythonPrimitive omPrimitiveToPythonValue(MlirAttribute attr) {
|
||||||
|
@ -411,17 +283,6 @@ static PythonPrimitive omPrimitiveToPythonValue(MlirAttribute attr) {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (omAttrIsAMapAttr(attr)) {
|
|
||||||
nb::dict results;
|
|
||||||
for (intptr_t i = 0, e = omMapAttrGetNumElements(attr); i < e; ++i) {
|
|
||||||
auto keyStrRef = mlirIdentifierStr(omMapAttrGetElementKey(attr, i));
|
|
||||||
auto key = nb::str(keyStrRef.data, keyStrRef.length);
|
|
||||||
auto value = omPrimitiveToPythonValue(omMapAttrGetElementValue(attr, i));
|
|
||||||
results[key] = value;
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
mlirAttributeDump(attr);
|
mlirAttributeDump(attr);
|
||||||
throw nb::type_error("Unexpected OM primitive attribute");
|
throw nb::type_error("Unexpected OM primitive attribute");
|
||||||
}
|
}
|
||||||
|
@ -493,14 +354,6 @@ PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result) {
|
||||||
if (omEvaluatorValueIsAList(result))
|
if (omEvaluatorValueIsAList(result))
|
||||||
return List(result);
|
return List(result);
|
||||||
|
|
||||||
// If the field was a tuple, return a new Tuple.
|
|
||||||
if (omEvaluatorValueIsATuple(result))
|
|
||||||
return Tuple(result);
|
|
||||||
|
|
||||||
// If the field was a map, return a new Map.
|
|
||||||
if (omEvaluatorValueIsAMap(result))
|
|
||||||
return Map(result);
|
|
||||||
|
|
||||||
// If the field was a base path, return a new BasePath.
|
// If the field was a base path, return a new BasePath.
|
||||||
if (omEvaluatorValueIsABasePath(result))
|
if (omEvaluatorValueIsABasePath(result))
|
||||||
return BasePath(result);
|
return BasePath(result);
|
||||||
|
@ -523,12 +376,6 @@ OMEvaluatorValue pythonValueToOMEvaluatorValue(PythonValue result,
|
||||||
if (auto *list = std::get_if<List>(&result))
|
if (auto *list = std::get_if<List>(&result))
|
||||||
return list->getValue();
|
return list->getValue();
|
||||||
|
|
||||||
if (auto *tuple = std::get_if<Tuple>(&result))
|
|
||||||
return tuple->getValue();
|
|
||||||
|
|
||||||
if (auto *map = std::get_if<Map>(&result))
|
|
||||||
return map->getValue();
|
|
||||||
|
|
||||||
if (auto *basePath = std::get_if<BasePath>(&result))
|
if (auto *basePath = std::get_if<BasePath>(&result))
|
||||||
return basePath->getValue();
|
return basePath->getValue();
|
||||||
|
|
||||||
|
@ -563,18 +410,6 @@ void circt::python::populateDialectOMSubmodule(nb::module_ &m) {
|
||||||
.def("__getitem__", &List::getElement)
|
.def("__getitem__", &List::getElement)
|
||||||
.def("__len__", &List::getNumElements);
|
.def("__len__", &List::getNumElements);
|
||||||
|
|
||||||
nb::class_<Tuple>(m, "Tuple")
|
|
||||||
.def(nb::init<Tuple>(), nb::arg("tuple"))
|
|
||||||
.def("__getitem__", &Tuple::getElement)
|
|
||||||
.def("__len__", &Tuple::getNumElements);
|
|
||||||
|
|
||||||
// Add the Map class definition.
|
|
||||||
nb::class_<Map>(m, "Map")
|
|
||||||
.def(nb::init<Map>(), nb::arg("map"))
|
|
||||||
.def("__getitem__", &Map::dunderGetItem)
|
|
||||||
.def("keys", &Map::getKeys)
|
|
||||||
.def_prop_ro("type", &Map::getType, "The Type of the Map");
|
|
||||||
|
|
||||||
// Add the BasePath class definition.
|
// Add the BasePath class definition.
|
||||||
nb::class_<BasePath>(m, "BasePath")
|
nb::class_<BasePath>(m, "BasePath")
|
||||||
.def(nb::init<BasePath>(), nb::arg("basepath"))
|
.def(nb::init<BasePath>(), nb::arg("basepath"))
|
||||||
|
@ -628,12 +463,6 @@ void circt::python::populateDialectOMSubmodule(nb::module_ &m) {
|
||||||
[](MlirAttribute arr) { return PyListAttrIterator(arr); });
|
[](MlirAttribute arr) { return PyListAttrIterator(arr); });
|
||||||
PyListAttrIterator::bind(m);
|
PyListAttrIterator::bind(m);
|
||||||
|
|
||||||
// Add the MapAttr definition
|
|
||||||
mlir_attribute_subclass(m, "MapAttr", omAttrIsAMapAttr)
|
|
||||||
.def("__iter__", [](MlirAttribute arr) { return PyMapAttrIterator(arr); })
|
|
||||||
.def("__len__", &omMapAttrGetNumElements);
|
|
||||||
PyMapAttrIterator::bind(m);
|
|
||||||
|
|
||||||
// Add the AnyType class definition.
|
// Add the AnyType class definition.
|
||||||
mlir_type_subclass(m, "AnyType", omTypeIsAAnyType, omAnyTypeGetTypeID);
|
mlir_type_subclass(m, "AnyType", omTypeIsAAnyType, omAnyTypeGetTypeID);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from ._om_ops_gen import *
|
from ._om_ops_gen import *
|
||||||
from .._mlir_libs._circt._om import AnyType, Evaluator as BaseEvaluator, Object as BaseObject, List as BaseList, Tuple as BaseTuple, Map as BaseMap, BasePath as BaseBasePath, BasePathType, Path, PathType, ClassType, ReferenceAttr, ListAttr, ListType, MapAttr, OMIntegerAttr
|
from .._mlir_libs._circt._om import AnyType, Evaluator as BaseEvaluator, Object as BaseObject, List as BaseList, BasePath as BaseBasePath, BasePathType, Path, PathType, ClassType, ReferenceAttr, ListAttr, ListType, OMIntegerAttr
|
||||||
|
|
||||||
from ..ir import Attribute, Diagnostic, DiagnosticSeverity, Module, StringAttr, IntegerAttr, IntegerType
|
from ..ir import Attribute, Diagnostic, DiagnosticSeverity, Module, StringAttr, IntegerAttr, IntegerType
|
||||||
from ..support import attribute_to_var, var_to_attribute
|
from ..support import attribute_to_var, var_to_attribute
|
||||||
|
@ -28,12 +28,6 @@ def wrap_mlir_object(value):
|
||||||
if isinstance(value, BaseList):
|
if isinstance(value, BaseList):
|
||||||
return List(value)
|
return List(value)
|
||||||
|
|
||||||
if isinstance(value, BaseTuple):
|
|
||||||
return Tuple(value)
|
|
||||||
|
|
||||||
if isinstance(value, BaseMap):
|
|
||||||
return Map(value)
|
|
||||||
|
|
||||||
if isinstance(value, BaseBasePath):
|
if isinstance(value, BaseBasePath):
|
||||||
return BasePath(value)
|
return BasePath(value)
|
||||||
|
|
||||||
|
@ -56,12 +50,6 @@ def unwrap_python_object(value):
|
||||||
if isinstance(value, List):
|
if isinstance(value, List):
|
||||||
return BaseList(value)
|
return BaseList(value)
|
||||||
|
|
||||||
if isinstance(value, Tuple):
|
|
||||||
return BaseTuple(value)
|
|
||||||
|
|
||||||
if isinstance(value, Map):
|
|
||||||
return BaseMap(value)
|
|
||||||
|
|
||||||
if isinstance(value, BasePath):
|
if isinstance(value, BasePath):
|
||||||
return BaseBasePath(value)
|
return BaseBasePath(value)
|
||||||
|
|
||||||
|
@ -90,47 +78,6 @@ class List(BaseList):
|
||||||
yield self.__getitem__(i)
|
yield self.__getitem__(i)
|
||||||
|
|
||||||
|
|
||||||
class Tuple(BaseTuple):
|
|
||||||
|
|
||||||
def __init__(self, obj: BaseTuple) -> None:
|
|
||||||
super().__init__(obj)
|
|
||||||
|
|
||||||
def __getitem__(self, i):
|
|
||||||
val = super().__getitem__(i)
|
|
||||||
return wrap_mlir_object(val)
|
|
||||||
|
|
||||||
# Support iterating over a Tuple by yielding its elements.
|
|
||||||
def __iter__(self):
|
|
||||||
for i in range(0, self.__len__()):
|
|
||||||
yield self.__getitem__(i)
|
|
||||||
|
|
||||||
|
|
||||||
class Map(BaseMap):
|
|
||||||
|
|
||||||
def __init__(self, obj: BaseMap) -> None:
|
|
||||||
super().__init__(obj)
|
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
val = super().__getitem__(key)
|
|
||||||
return wrap_mlir_object(val)
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
return [wrap_mlir_object(arg) for arg in super().keys()]
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
for i in self:
|
|
||||||
yield i
|
|
||||||
|
|
||||||
def values(self):
|
|
||||||
for (_, v) in self:
|
|
||||||
yield v
|
|
||||||
|
|
||||||
# Support iterating over a Map
|
|
||||||
def __iter__(self):
|
|
||||||
for i in super().keys():
|
|
||||||
yield (wrap_mlir_object(i), self.__getitem__(i))
|
|
||||||
|
|
||||||
|
|
||||||
class BasePath(BaseBasePath):
|
class BasePath(BaseBasePath):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -248,10 +248,6 @@ def attribute_to_var(attr):
|
||||||
return list(map(attribute_to_var, om.ListAttr(attr)))
|
return list(map(attribute_to_var, om.ListAttr(attr)))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
try:
|
|
||||||
return {name: attribute_to_var(value) for name, value in om.MapAttr(attr)}
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
try:
|
try:
|
||||||
return int(str(om.OMIntegerAttr(attr)))
|
return int(str(om.OMIntegerAttr(attr)))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|
|
@ -90,14 +90,6 @@ MlirType omStringTypeGet(MlirContext ctx) {
|
||||||
/// Get the TypeID for a StringType.
|
/// Get the TypeID for a StringType.
|
||||||
MlirTypeID omStringTypeGetTypeID(void) { return wrap(StringType::getTypeID()); }
|
MlirTypeID omStringTypeGetTypeID(void) { return wrap(StringType::getTypeID()); }
|
||||||
|
|
||||||
/// Is the Type a MapType.
|
|
||||||
bool omTypeIsAMapType(MlirType type) { return isa<MapType>(unwrap(type)); }
|
|
||||||
|
|
||||||
/// Return a key type of a map.
|
|
||||||
MlirType omMapTypeGetKeyType(MlirType type) {
|
|
||||||
return wrap(cast<MapType>(unwrap(type)).getKeyType());
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Evaluator data structures.
|
// Evaluator data structures.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -196,15 +188,6 @@ MlirAttribute omEvaluatorObjectGetFieldNames(OMEvaluatorValue object) {
|
||||||
return wrap(llvm::cast<Object>(unwrap(object).get())->getFieldNames());
|
return wrap(llvm::cast<Object>(unwrap(object).get())->getFieldNames());
|
||||||
}
|
}
|
||||||
|
|
||||||
MlirType omEvaluatorMapGetType(OMEvaluatorValue value) {
|
|
||||||
return wrap(llvm::cast<evaluator::MapValue>(unwrap(value).get())->getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get an ArrayAttr with the keys in a Map.
|
|
||||||
MlirAttribute omEvaluatorMapGetKeys(OMEvaluatorValue object) {
|
|
||||||
return wrap(llvm::cast<evaluator::MapValue>(unwrap(object).get())->getKeys());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a field from an Object, which must contain a field of that name.
|
/// Get a field from an Object, which must contain a field of that name.
|
||||||
OMEvaluatorValue omEvaluatorObjectGetField(OMEvaluatorValue object,
|
OMEvaluatorValue omEvaluatorObjectGetField(OMEvaluatorValue object,
|
||||||
MlirAttribute name) {
|
MlirAttribute name) {
|
||||||
|
@ -296,41 +279,6 @@ OMEvaluatorValue omEvaluatorListGetElement(OMEvaluatorValue evaluatorValue,
|
||||||
->getElements()[pos]);
|
->getElements()[pos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Query if the EvaluatorValue is a Tuple.
|
|
||||||
bool omEvaluatorValueIsATuple(OMEvaluatorValue evaluatorValue) {
|
|
||||||
return isa<evaluator::TupleValue>(unwrap(evaluatorValue).get());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the length of the Tuple.
|
|
||||||
intptr_t omEvaluatorTupleGetNumElements(OMEvaluatorValue evaluatorValue) {
|
|
||||||
return cast<evaluator::TupleValue>(unwrap(evaluatorValue).get())
|
|
||||||
->getElements()
|
|
||||||
.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get an element of the Tuple.
|
|
||||||
OMEvaluatorValue omEvaluatorTupleGetElement(OMEvaluatorValue evaluatorValue,
|
|
||||||
intptr_t pos) {
|
|
||||||
return wrap(cast<evaluator::TupleValue>(unwrap(evaluatorValue).get())
|
|
||||||
->getElements()[pos]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get an element of the Map.
|
|
||||||
OMEvaluatorValue omEvaluatorMapGetElement(OMEvaluatorValue evaluatorValue,
|
|
||||||
MlirAttribute attr) {
|
|
||||||
const auto &elements =
|
|
||||||
cast<evaluator::MapValue>(unwrap(evaluatorValue).get())->getElements();
|
|
||||||
const auto &it = elements.find(unwrap(attr));
|
|
||||||
if (it != elements.end())
|
|
||||||
return wrap(it->second);
|
|
||||||
return OMEvaluatorValue{nullptr};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Query if the EvaluatorValue is a map.
|
|
||||||
bool omEvaluatorValueIsAMap(OMEvaluatorValue evaluatorValue) {
|
|
||||||
return isa<evaluator::MapValue>(unwrap(evaluatorValue).get());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool omEvaluatorValueIsABasePath(OMEvaluatorValue evaluatorValue) {
|
bool omEvaluatorValueIsABasePath(OMEvaluatorValue evaluatorValue) {
|
||||||
return isa<evaluator::BasePathValue>(unwrap(evaluatorValue).get());
|
return isa<evaluator::BasePathValue>(unwrap(evaluatorValue).get());
|
||||||
}
|
}
|
||||||
|
@ -440,24 +388,3 @@ MlirAttribute omListAttrGet(MlirType elementType, intptr_t numElements,
|
||||||
auto *ctx = type.getContext();
|
auto *ctx = type.getContext();
|
||||||
return wrap(ListAttr::get(ctx, type, ArrayAttr::get(ctx, attrs)));
|
return wrap(ListAttr::get(ctx, type, ArrayAttr::get(ctx, attrs)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// MapAttr API.
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
bool omAttrIsAMapAttr(MlirAttribute attr) { return isa<MapAttr>(unwrap(attr)); }
|
|
||||||
|
|
||||||
intptr_t omMapAttrGetNumElements(MlirAttribute attr) {
|
|
||||||
auto mapAttr = llvm::cast<MapAttr>(unwrap(attr));
|
|
||||||
return static_cast<intptr_t>(mapAttr.getElements().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
MlirIdentifier omMapAttrGetElementKey(MlirAttribute attr, intptr_t pos) {
|
|
||||||
auto mapAttr = llvm::cast<MapAttr>(unwrap(attr));
|
|
||||||
return wrap(mapAttr.getElements().getValue()[pos].getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
MlirAttribute omMapAttrGetElementValue(MlirAttribute attr, intptr_t pos) {
|
|
||||||
auto mapAttr = llvm::cast<MapAttr>(unwrap(attr));
|
|
||||||
return wrap(mapAttr.getElements().getValue()[pos].getValue());
|
|
||||||
}
|
|
||||||
|
|
|
@ -49,9 +49,8 @@ LogicalResult circt::om::evaluator::EvaluatorValue::finalize() {
|
||||||
finalized = true;
|
finalized = true;
|
||||||
assert(isFullyEvaluated());
|
assert(isFullyEvaluated());
|
||||||
return llvm::TypeSwitch<EvaluatorValue *, LogicalResult>(this)
|
return llvm::TypeSwitch<EvaluatorValue *, LogicalResult>(this)
|
||||||
.Case<AttributeValue, ObjectValue, ListValue, MapValue, ReferenceValue,
|
.Case<AttributeValue, ObjectValue, ListValue, ReferenceValue,
|
||||||
TupleValue, BasePathValue, PathValue>(
|
BasePathValue, PathValue>([](auto v) { return v->finalizeImpl(); });
|
||||||
[](auto v) { return v->finalizeImpl(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type circt::om::evaluator::EvaluatorValue::getType() const {
|
Type circt::om::evaluator::EvaluatorValue::getType() const {
|
||||||
|
@ -59,9 +58,7 @@ Type circt::om::evaluator::EvaluatorValue::getType() const {
|
||||||
.Case<AttributeValue>([](auto *attr) -> Type { return attr->getType(); })
|
.Case<AttributeValue>([](auto *attr) -> Type { return attr->getType(); })
|
||||||
.Case<ObjectValue>([](auto *object) { return object->getObjectType(); })
|
.Case<ObjectValue>([](auto *object) { return object->getObjectType(); })
|
||||||
.Case<ListValue>([](auto *list) { return list->getListType(); })
|
.Case<ListValue>([](auto *list) { return list->getListType(); })
|
||||||
.Case<MapValue>([](auto *map) { return map->getMapType(); })
|
|
||||||
.Case<ReferenceValue>([](auto *ref) { return ref->getValueType(); })
|
.Case<ReferenceValue>([](auto *ref) { return ref->getValueType(); })
|
||||||
.Case<TupleValue>([](auto *tuple) { return tuple->getTupleType(); })
|
|
||||||
.Case<BasePathValue>(
|
.Case<BasePathValue>(
|
||||||
[this](auto *tuple) { return FrozenBasePathType::get(ctx); })
|
[this](auto *tuple) { return FrozenBasePathType::get(ctx); })
|
||||||
.Case<PathValue>(
|
.Case<PathValue>(
|
||||||
|
@ -73,22 +70,11 @@ circt::om::Evaluator::getPartiallyEvaluatedValue(Type type, Location loc) {
|
||||||
using namespace circt::om::evaluator;
|
using namespace circt::om::evaluator;
|
||||||
|
|
||||||
return TypeSwitch<mlir::Type, FailureOr<evaluator::EvaluatorValuePtr>>(type)
|
return TypeSwitch<mlir::Type, FailureOr<evaluator::EvaluatorValuePtr>>(type)
|
||||||
.Case([&](circt::om::MapType type) {
|
|
||||||
evaluator::EvaluatorValuePtr result =
|
|
||||||
std::make_shared<evaluator::MapValue>(type, loc);
|
|
||||||
return success(result);
|
|
||||||
})
|
|
||||||
.Case([&](circt::om::ListType type) {
|
.Case([&](circt::om::ListType type) {
|
||||||
evaluator::EvaluatorValuePtr result =
|
evaluator::EvaluatorValuePtr result =
|
||||||
std::make_shared<evaluator::ListValue>(type, loc);
|
std::make_shared<evaluator::ListValue>(type, loc);
|
||||||
return success(result);
|
return success(result);
|
||||||
})
|
})
|
||||||
.Case([&](mlir::TupleType type) {
|
|
||||||
evaluator::EvaluatorValuePtr result =
|
|
||||||
std::make_shared<evaluator::TupleValue>(type, loc);
|
|
||||||
return success(result);
|
|
||||||
})
|
|
||||||
|
|
||||||
.Case([&](circt::om::ClassType type)
|
.Case([&](circt::om::ClassType type)
|
||||||
-> FailureOr<evaluator::EvaluatorValuePtr> {
|
-> FailureOr<evaluator::EvaluatorValuePtr> {
|
||||||
ClassOp cls =
|
ClassOp cls =
|
||||||
|
@ -167,13 +153,9 @@ FailureOr<evaluator::EvaluatorValuePtr> circt::om::Evaluator::getOrCreateValue(
|
||||||
evaluator::PathValue::getEmptyPath(loc));
|
evaluator::PathValue::getEmptyPath(loc));
|
||||||
return success(result);
|
return success(result);
|
||||||
})
|
})
|
||||||
.Case<ListCreateOp, ListConcatOp, TupleCreateOp, MapCreateOp,
|
.Case<ListCreateOp, ListConcatOp, ObjectFieldOp>([&](auto op) {
|
||||||
ObjectFieldOp>([&](auto op) {
|
|
||||||
return getPartiallyEvaluatedValue(op.getType(), loc);
|
return getPartiallyEvaluatedValue(op.getType(), loc);
|
||||||
})
|
})
|
||||||
.Case<TupleGetOp>([&](auto op) {
|
|
||||||
return evaluateTupleGet(op, actualParams, loc);
|
|
||||||
})
|
|
||||||
.Case<ObjectOp>([&](auto op) {
|
.Case<ObjectOp>([&](auto op) {
|
||||||
return getPartiallyEvaluatedValue(op.getType(), op.getLoc());
|
return getPartiallyEvaluatedValue(op.getType(), op.getLoc());
|
||||||
})
|
})
|
||||||
|
@ -369,18 +351,9 @@ circt::om::Evaluator::evaluateValue(Value value, ActualParameters actualParams,
|
||||||
.Case([&](ListConcatOp op) {
|
.Case([&](ListConcatOp op) {
|
||||||
return evaluateListConcat(op, actualParams, loc);
|
return evaluateListConcat(op, actualParams, loc);
|
||||||
})
|
})
|
||||||
.Case([&](TupleCreateOp op) {
|
|
||||||
return evaluateTupleCreate(op, actualParams, loc);
|
|
||||||
})
|
|
||||||
.Case([&](TupleGetOp op) {
|
|
||||||
return evaluateTupleGet(op, actualParams, loc);
|
|
||||||
})
|
|
||||||
.Case([&](AnyCastOp op) {
|
.Case([&](AnyCastOp op) {
|
||||||
return evaluateValue(op.getInput(), actualParams, loc);
|
return evaluateValue(op.getInput(), actualParams, loc);
|
||||||
})
|
})
|
||||||
.Case([&](MapCreateOp op) {
|
|
||||||
return evaluateMapCreate(op, actualParams, loc);
|
|
||||||
})
|
|
||||||
.Case([&](FrozenBasePathCreateOp op) {
|
.Case([&](FrozenBasePathCreateOp op) {
|
||||||
return evaluateBasePathCreate(op, actualParams, loc);
|
return evaluateBasePathCreate(op, actualParams, loc);
|
||||||
})
|
})
|
||||||
|
@ -635,67 +608,6 @@ circt::om::Evaluator::evaluateListConcat(ListConcatOp op,
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluator dispatch function for Tuple creation.
|
|
||||||
FailureOr<evaluator::EvaluatorValuePtr>
|
|
||||||
circt::om::Evaluator::evaluateTupleCreate(TupleCreateOp op,
|
|
||||||
ActualParameters actualParams,
|
|
||||||
Location loc) {
|
|
||||||
SmallVector<evaluator::EvaluatorValuePtr> values;
|
|
||||||
for (auto operand : op.getOperands()) {
|
|
||||||
auto result = evaluateValue(operand, actualParams, loc);
|
|
||||||
if (failed(result))
|
|
||||||
return result;
|
|
||||||
values.push_back(result.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the tuple.
|
|
||||||
auto val = getOrCreateValue(op, actualParams, loc);
|
|
||||||
llvm::cast<evaluator::TupleValue>(val.value().get())
|
|
||||||
->setElements(std::move(values));
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Evaluator dispatch function for List creation.
|
|
||||||
FailureOr<evaluator::EvaluatorValuePtr> circt::om::Evaluator::evaluateTupleGet(
|
|
||||||
TupleGetOp op, ActualParameters actualParams, Location loc) {
|
|
||||||
auto tuple = evaluateValue(op.getInput(), actualParams, loc);
|
|
||||||
if (failed(tuple))
|
|
||||||
return tuple;
|
|
||||||
evaluator::EvaluatorValuePtr result =
|
|
||||||
cast<evaluator::TupleValue>(tuple.value().get())
|
|
||||||
->getElements()[op.getIndex()];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Evaluator dispatch function for Map creation.
|
|
||||||
FailureOr<evaluator::EvaluatorValuePtr> circt::om::Evaluator::evaluateMapCreate(
|
|
||||||
MapCreateOp op, ActualParameters actualParams, Location loc) {
|
|
||||||
// Evaluate the Object itself, in case it hasn't been evaluated yet.
|
|
||||||
DenseMap<Attribute, evaluator::EvaluatorValuePtr> elements;
|
|
||||||
auto valueResult = getOrCreateValue(op, actualParams, loc).value();
|
|
||||||
for (auto operand : op.getOperands()) {
|
|
||||||
auto result = evaluateValue(operand, actualParams, loc);
|
|
||||||
if (failed(result))
|
|
||||||
return result;
|
|
||||||
// The result is a tuple.
|
|
||||||
auto &value = result.value();
|
|
||||||
if (!value->isFullyEvaluated())
|
|
||||||
return valueResult;
|
|
||||||
const auto &element =
|
|
||||||
llvm::cast<evaluator::TupleValue>(value.get())->getElements();
|
|
||||||
assert(element.size() == 2);
|
|
||||||
auto attr =
|
|
||||||
llvm::cast<evaluator::AttributeValue>(element[0].get())->getAttr();
|
|
||||||
if (!elements.insert({attr, element[1]}).second)
|
|
||||||
return op.emitError() << "map contains duplicated keys";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the Map.
|
|
||||||
llvm::cast<evaluator::MapValue>(valueResult.get())
|
|
||||||
->setElements(std::move(elements));
|
|
||||||
return valueResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
FailureOr<evaluator::EvaluatorValuePtr>
|
FailureOr<evaluator::EvaluatorValuePtr>
|
||||||
circt::om::Evaluator::evaluateBasePathCreate(FrozenBasePathCreateOp op,
|
circt::om::Evaluator::evaluateBasePathCreate(FrozenBasePathCreateOp op,
|
||||||
ActualParameters actualParams,
|
ActualParameters actualParams,
|
||||||
|
@ -771,36 +683,6 @@ LogicalResult circt::om::evaluator::ObjectValue::finalizeImpl() {
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// MapValue
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
/// Return an array of keys in the ascending order.
|
|
||||||
ArrayAttr circt::om::evaluator::MapValue::getKeys() {
|
|
||||||
SmallVector<Attribute> attrs;
|
|
||||||
for (auto &[key, _] : elements)
|
|
||||||
attrs.push_back(key);
|
|
||||||
|
|
||||||
std::sort(attrs.begin(), attrs.end(), [](Attribute l, Attribute r) {
|
|
||||||
if (auto lInt = dyn_cast<mlir::IntegerAttr>(l))
|
|
||||||
if (auto rInt = dyn_cast<mlir::IntegerAttr>(r))
|
|
||||||
return lInt.getValue().ult(rInt.getValue());
|
|
||||||
|
|
||||||
assert(isa<StringAttr>(l) && isa<StringAttr>(r) &&
|
|
||||||
"key type should be integer or string");
|
|
||||||
return cast<StringAttr>(l).getValue() < cast<StringAttr>(r).getValue();
|
|
||||||
});
|
|
||||||
|
|
||||||
return ArrayAttr::get(type.getContext(), attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogicalResult circt::om::evaluator::MapValue::finalizeImpl() {
|
|
||||||
for (auto &&[e, value] : elements)
|
|
||||||
if (failed(finalizeEvaluatorValue(value)))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ReferenceValue
|
// ReferenceValue
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "circt/Dialect/OM/OMDialect.h"
|
#include "circt/Dialect/OM/OMDialect.h"
|
||||||
#include "circt/Dialect/OM/OMTypes.h"
|
#include "circt/Dialect/OM/OMTypes.h"
|
||||||
#include "mlir/IR/Builders.h"
|
#include "mlir/IR/Builders.h"
|
||||||
#include "mlir/IR/BuiltinAttributes.h"
|
|
||||||
#include "mlir/IR/DialectImplementation.h"
|
#include "mlir/IR/DialectImplementation.h"
|
||||||
#include "llvm/ADT/TypeSwitch.h"
|
#include "llvm/ADT/TypeSwitch.h"
|
||||||
|
|
||||||
|
@ -36,11 +35,6 @@ Type circt::om::ListAttr::getType() {
|
||||||
return ListType::get(getContext(), getElementType());
|
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) {
|
circt::om::SymbolRefAttr circt::om::SymbolRefAttr::get(mlir::Operation *op) {
|
||||||
return om::SymbolRefAttr::get(op->getContext(),
|
return om::SymbolRefAttr::get(op->getContext(),
|
||||||
mlir::FlatSymbolRefAttr::get(op));
|
mlir::FlatSymbolRefAttr::get(op));
|
||||||
|
@ -73,24 +67,6 @@ 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 PathAttr::print(AsmPrinter &odsPrinter) const {
|
void PathAttr::print(AsmPrinter &odsPrinter) const {
|
||||||
odsPrinter << '[';
|
odsPrinter << '[';
|
||||||
llvm::interleaveComma(getPath(), odsPrinter, [&](PathElement element) {
|
llvm::interleaveComma(getPath(), odsPrinter, [&](PathElement element) {
|
||||||
|
|
|
@ -611,80 +611,6 @@ ParseResult circt::om::ListCreateOp::parse(OpAsmParser &parser,
|
||||||
return success();
|
return success();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// TupleCreateOp
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
LogicalResult TupleCreateOp::inferReturnTypes(
|
|
||||||
MLIRContext *context, std::optional<Location> location, ValueRange operands,
|
|
||||||
DictionaryAttr attributes, OpaqueProperties, RegionRange regions,
|
|
||||||
llvm::SmallVectorImpl<Type> &inferredReturnTypes) {
|
|
||||||
::llvm::SmallVector<Type> types;
|
|
||||||
for (auto op : operands)
|
|
||||||
types.push_back(op.getType());
|
|
||||||
inferredReturnTypes.push_back(TupleType::get(context, types));
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// TupleGetOp
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
LogicalResult TupleGetOp::inferReturnTypes(
|
|
||||||
MLIRContext *context, std::optional<Location> location, ValueRange operands,
|
|
||||||
DictionaryAttr attributes, OpaqueProperties properties, RegionRange regions,
|
|
||||||
llvm::SmallVectorImpl<Type> &inferredReturnTypes) {
|
|
||||||
Adaptor adaptor(operands, attributes, properties, regions);
|
|
||||||
auto idx = adaptor.getIndexAttr();
|
|
||||||
if (operands.empty() || !idx)
|
|
||||||
return failure();
|
|
||||||
|
|
||||||
auto tupleTypes = cast<TupleType>(adaptor.getInput().getType()).getTypes();
|
|
||||||
if (tupleTypes.size() <= idx.getValue().getLimitedValue()) {
|
|
||||||
if (location)
|
|
||||||
mlir::emitError(*location,
|
|
||||||
"tuple index out-of-bounds, must be less than ")
|
|
||||||
<< tupleTypes.size() << " but got "
|
|
||||||
<< idx.getValue().getLimitedValue();
|
|
||||||
return failure();
|
|
||||||
}
|
|
||||||
|
|
||||||
inferredReturnTypes.push_back(tupleTypes[idx.getValue().getLimitedValue()]);
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// MapCreateOp
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
void circt::om::MapCreateOp::print(OpAsmPrinter &p) {
|
|
||||||
p << " ";
|
|
||||||
p.printOperands(getInputs());
|
|
||||||
p.printOptionalAttrDict((*this)->getAttrs());
|
|
||||||
p << " : " << cast<circt::om::MapType>(getType()).getKeyType() << ", "
|
|
||||||
<< cast<circt::om::MapType>(getType()).getValueType();
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseResult circt::om::MapCreateOp::parse(OpAsmParser &parser,
|
|
||||||
OperationState &result) {
|
|
||||||
llvm::SmallVector<OpAsmParser::UnresolvedOperand, 16> operands;
|
|
||||||
Type elementType, valueType;
|
|
||||||
|
|
||||||
if (parser.parseOperandList(operands) ||
|
|
||||||
parser.parseOptionalAttrDict(result.attributes) || parser.parseColon() ||
|
|
||||||
parser.parseType(elementType) || parser.parseComma() ||
|
|
||||||
parser.parseType(valueType))
|
|
||||||
return failure();
|
|
||||||
result.addTypes({circt::om::MapType::get(elementType, valueType)});
|
|
||||||
auto operandType =
|
|
||||||
mlir::TupleType::get(valueType.getContext(), {elementType, valueType});
|
|
||||||
|
|
||||||
for (auto operand : operands)
|
|
||||||
if (parser.resolveOperand(operand, operandType, result.operands))
|
|
||||||
return failure();
|
|
||||||
return success();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// BasePathCreateOp
|
// BasePathCreateOp
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -30,18 +30,3 @@ void circt::om::OMDialect::registerTypes() {
|
||||||
#include "circt/Dialect/OM/OMTypes.cpp.inc"
|
#include "circt/Dialect/OM/OMTypes.cpp.inc"
|
||||||
>();
|
>();
|
||||||
}
|
}
|
||||||
|
|
||||||
mlir::LogicalResult
|
|
||||||
circt::om::MapType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> diag,
|
|
||||||
mlir::Type keyType, mlir::Type elementType) {
|
|
||||||
if (!llvm::isa<om::StringType, mlir::IntegerType>(keyType))
|
|
||||||
return diag() << "map key type must be either string or integer but got "
|
|
||||||
<< keyType;
|
|
||||||
return mlir::success();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool circt::om::isMapKeyValuePairType(mlir::Type type) {
|
|
||||||
auto tuple = llvm::dyn_cast<mlir::TupleType>(type);
|
|
||||||
return tuple && tuple.getTypes().size() == 2 &&
|
|
||||||
llvm::isa<om::StringType, mlir::IntegerType>(tuple.getTypes().front());
|
|
||||||
}
|
|
||||||
|
|
|
@ -103,14 +103,11 @@ void testEvaluator(MlirContext ctx) {
|
||||||
" %0 = om.object @Child() : () -> !om.class.type<@Child>"
|
" %0 = om.object @Child() : () -> !om.class.type<@Child>"
|
||||||
" om.class.fields %param, %0 : !om.integer, !om.class.type<@Child>"
|
" om.class.fields %param, %0 : !om.integer, !om.class.type<@Child>"
|
||||||
" }"
|
" }"
|
||||||
" om.class @Child() -> (foo: i64, bar: !om.list<i64>, baz: "
|
" om.class @Child() -> (foo: i64, bar: !om.list<i64>){"
|
||||||
"tuple<!om.list<i64>, i64>){"
|
|
||||||
" %0 = om.constant 14 : i64"
|
" %0 = om.constant 14 : i64"
|
||||||
" %1 = om.constant 15 : i64"
|
" %1 = om.constant 15 : i64"
|
||||||
" %2 = om.list_create %0, %1 : i64"
|
" %2 = om.list_create %0, %1 : i64"
|
||||||
" %3 = om.tuple_create %2, %0 : !om.list<i64>, i64"
|
" om.class.fields %0, %2 : i64, !om.list<i64>"
|
||||||
" om.class.fields %0, %2, %3 : i64, !om.list<i64>, "
|
|
||||||
"tuple<!om.list<i64>, i64>"
|
|
||||||
" }"
|
" }"
|
||||||
"}";
|
"}";
|
||||||
|
|
||||||
|
@ -202,12 +199,9 @@ void testEvaluator(MlirContext ctx) {
|
||||||
OMEvaluatorValue bar = omEvaluatorObjectGetField(
|
OMEvaluatorValue bar = omEvaluatorObjectGetField(
|
||||||
child, mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("bar")));
|
child, mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("bar")));
|
||||||
|
|
||||||
OMEvaluatorValue baz = omEvaluatorObjectGetField(
|
|
||||||
child, mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("baz")));
|
|
||||||
|
|
||||||
MlirAttribute fieldNamesC = omEvaluatorObjectGetFieldNames(child);
|
MlirAttribute fieldNamesC = omEvaluatorObjectGetFieldNames(child);
|
||||||
|
|
||||||
// CHECK: ["bar", "baz", "foo"]
|
// CHECK: ["bar", "foo"]
|
||||||
mlirAttributeDump(fieldNamesC);
|
mlirAttributeDump(fieldNamesC);
|
||||||
|
|
||||||
// CHECK: child object field `foo` is primitive: 1
|
// CHECK: child object field `foo` is primitive: 1
|
||||||
|
@ -226,14 +220,6 @@ void testEvaluator(MlirContext ctx) {
|
||||||
// CHECK: 15 : i64
|
// CHECK: 15 : i64
|
||||||
mlirAttributeDump(
|
mlirAttributeDump(
|
||||||
omEvaluatorValueGetPrimitive(omEvaluatorListGetElement(bar, 1)));
|
omEvaluatorValueGetPrimitive(omEvaluatorListGetElement(bar, 1)));
|
||||||
|
|
||||||
// CHECK: child object field `baz` is tuple: 1
|
|
||||||
fprintf(stderr, "child object field `baz` is tuple: %d\n",
|
|
||||||
omEvaluatorValueIsATuple(baz));
|
|
||||||
|
|
||||||
// CHECK: 14 : i64
|
|
||||||
mlirAttributeDump(
|
|
||||||
omEvaluatorValueGetPrimitive(omEvaluatorTupleGetElement(baz, 1)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
|
@ -112,29 +112,6 @@ om.class @ListCreate() {
|
||||||
|
|
||||||
// -----
|
// -----
|
||||||
|
|
||||||
// expected-error @+1 {{map key type must be either string or integer but got '!om.list<!om.string>'}}
|
|
||||||
om.class @Map(%map: !om.map<!om.list<!om.string>, !om.string>) {
|
|
||||||
om.class.fields
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----
|
|
||||||
|
|
||||||
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.fields
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----
|
|
||||||
|
|
||||||
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>
|
|
||||||
om.class.fields
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----
|
|
||||||
|
|
||||||
om.class @Thing() {
|
om.class @Thing() {
|
||||||
om.class.fields
|
om.class.fields
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,43 +223,6 @@ om.class @BoolConstant(%b0 : i1) -> (bool: i1, bool2: i1, bool3: i1) {
|
||||||
// CHECK: om.class.fields %b0, %[[const1]], %[[const2]] : i1, i1, i1
|
// CHECK: om.class.fields %b0, %[[const1]], %[[const2]] : i1, i1, i1
|
||||||
om.class.fields %b0, %1, %2 : i1, i1, i1
|
om.class.fields %b0, %1, %2 : i1, i1, i1
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: @Map
|
|
||||||
// CHECK-SAME: !om.map<!om.string, !om.string>
|
|
||||||
// CHECK-SAME: -> (field: !om.map<!om.string, !om.string>)
|
|
||||||
om.class @Map(%map: !om.map<!om.string, !om.string>) -> (field: !om.map<!om.string, !om.string>) {
|
|
||||||
// CHECK: om.class.fields %map : !om.map<!om.string, !om.string>
|
|
||||||
om.class.fields %map : !om.map<!om.string, !om.string>
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK-LABEL: @Tuple
|
|
||||||
// CHECK-SAME: -> (tuple: tuple<i1, !om.string>, val: !om.string)
|
|
||||||
om.class @Tuple(%int: i1, %str: !om.string) -> (tuple: tuple<i1, !om.string>, val: !om.string) {
|
|
||||||
// CHECK: %[[tuple:.+]] = om.tuple_create %int, %str : i1, !om.string
|
|
||||||
%tuple = om.tuple_create %int, %str : i1, !om.string
|
|
||||||
// CHECK-NEXT: %[[tuple_get:.+]] = om.tuple_get %[[tuple]][1] : tuple<i1, !om.string>
|
|
||||||
%val = om.tuple_get %tuple[1] : tuple<i1, !om.string>
|
|
||||||
// CHECK-NEXT: om.class.fields %[[tuple]], %[[tuple_get]] : tuple<i1, !om.string>, !om.string
|
|
||||||
om.class.fields %tuple, %val : tuple<i1, !om.string>, !om.string
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK-LABEL: @MapConstant
|
|
||||||
// CHECK-SAME: -> (map_i64: !om.map<!om.string, i64>)
|
|
||||||
om.class @MapConstant() -> (map_i64: !om.map<!om.string, i64>) {
|
|
||||||
// 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.fields %[[const1]] : !om.map<!om.string, i64>
|
|
||||||
om.class.fields %0 : !om.map<!om.string, i64>
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK-LABEL: @MapCreate
|
|
||||||
// CHECK-SAME: -> (map_field: !om.map<!om.string, !om.class.type<@Empty>>)
|
|
||||||
om.class @MapCreate(%e1: tuple<!om.string, !om.class.type<@Empty>>, %e2: tuple<!om.string, !om.class.type<@Empty>>) -> (map_field: !om.map<!om.string, !om.class.type<@Empty>>) {
|
|
||||||
// CHECK: %[[map:.+]] = om.map_create %e1, %e2 : !om.string, !om.class.type<@Empty>
|
|
||||||
%map = om.map_create %e1, %e2 : !om.string, !om.class.type<@Empty>
|
|
||||||
// CHECK-NEXT: om.class.fields %[[map]] : !om.map<!om.string, !om.class.type<@Empty>>
|
|
||||||
om.class.fields %map : !om.map<!om.string, !om.class.type<@Empty>>
|
|
||||||
}
|
|
||||||
|
|
||||||
hw.hierpath @HierPath [@PathModule::@wire]
|
hw.hierpath @HierPath [@PathModule::@wire]
|
||||||
hw.module @PathModule() {
|
hw.module @PathModule() {
|
||||||
|
|
|
@ -1323,40 +1323,6 @@ TEST(EvaluatorTests, ListConcatPartialCycle) {
|
||||||
ASSERT_EQ(2U, id2->getAs<circt::om::IntegerAttr>().getValue().getValue());
|
ASSERT_EQ(2U, id2->getAs<circt::om::IntegerAttr>().getValue().getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(EvaluatorTests, TupleGet) {
|
|
||||||
StringRef mod = "om.class @Tuple() -> (val: !om.string) {"
|
|
||||||
" %int = om.constant 1 : i1"
|
|
||||||
" %str = om.constant \"foo\" : !om.string"
|
|
||||||
" %tuple = om.tuple_create %int, %str : i1, !om.string"
|
|
||||||
" %val = om.tuple_get %tuple[1] : tuple<i1, !om.string>"
|
|
||||||
" om.class.fields %val : !om.string"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
DialectRegistry registry;
|
|
||||||
registry.insert<OMDialect>();
|
|
||||||
|
|
||||||
MLIRContext context(registry);
|
|
||||||
context.getOrLoadDialect<OMDialect>();
|
|
||||||
|
|
||||||
OwningOpRef<ModuleOp> owning =
|
|
||||||
parseSourceString<ModuleOp>(mod, ParserConfig(&context));
|
|
||||||
|
|
||||||
Evaluator evaluator(owning.release());
|
|
||||||
|
|
||||||
auto result = evaluator.instantiate(StringAttr::get(&context, "Tuple"), {});
|
|
||||||
|
|
||||||
ASSERT_TRUE(succeeded(result));
|
|
||||||
|
|
||||||
auto fieldValue = llvm::cast<evaluator::ObjectValue>(result.value().get())
|
|
||||||
->getField("val")
|
|
||||||
.value();
|
|
||||||
|
|
||||||
ASSERT_EQ("foo", llvm::cast<evaluator::AttributeValue>(fieldValue.get())
|
|
||||||
->getAs<StringAttr>()
|
|
||||||
.getValue()
|
|
||||||
.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(EvaluatorTests, NestedReferenceValue) {
|
TEST(EvaluatorTests, NestedReferenceValue) {
|
||||||
StringRef mod =
|
StringRef mod =
|
||||||
"om.class @Empty() {"
|
"om.class @Empty() {"
|
||||||
|
|
Loading…
Reference in New Issue