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.
|
||||
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.
|
||||
MLIR_CAPI_EXPORTED bool omTypeIsAStringType(MlirType type);
|
||||
|
||||
|
@ -187,31 +181,6 @@ omEvaluatorListGetNumElements(OMEvaluatorValue evaluatorValue);
|
|||
MLIR_CAPI_EXPORTED OMEvaluatorValue
|
||||
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.
|
||||
MLIR_CAPI_EXPORTED bool
|
||||
omEvaluatorValueIsABasePath(OMEvaluatorValue evaluatorValue);
|
||||
|
@ -275,20 +244,6 @@ MLIR_CAPI_EXPORTED MlirAttribute omListAttrGet(MlirType elementType,
|
|||
intptr_t numElements,
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -47,7 +47,7 @@ using ObjectFields = SmallDenseMap<StringAttr, EvaluatorValuePtr>;
|
|||
/// the appropriate reference count.
|
||||
struct EvaluatorValue : std::enable_shared_from_this<EvaluatorValue> {
|
||||
// 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)
|
||||
: kind(kind), ctx(ctx), loc(loc) {}
|
||||
Kind getKind() const { return kind; }
|
||||
|
@ -224,44 +224,6 @@ private:
|
|||
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.
|
||||
struct ObjectValue : EvaluatorValue {
|
||||
ObjectValue(om::ClassOp cls, ObjectFields fields, Location loc)
|
||||
|
@ -313,46 +275,6 @@ private:
|
|||
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.
|
||||
struct BasePathValue : EvaluatorValue {
|
||||
BasePathValue(MLIRContext *context);
|
||||
|
@ -493,14 +415,6 @@ private:
|
|||
FailureOr<EvaluatorValuePtr> evaluateListConcat(ListConcatOp op,
|
||||
ActualParameters actualParams,
|
||||
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>
|
||||
evaluateBasePathCreate(FrozenBasePathCreateOp op,
|
||||
ActualParameters actualParams, Location loc);
|
||||
|
@ -543,8 +457,6 @@ operator<<(mlir::Diagnostic &diag,
|
|||
diag << "Object(" << object->getType() << ")";
|
||||
else if (auto *list = llvm::dyn_cast<evaluator::ListValue>(&evaluatorValue))
|
||||
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))
|
||||
diag << "BasePath()";
|
||||
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"> {
|
||||
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)";
|
||||
}
|
||||
|
||||
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,
|
||||
DeclareOpInterfaceMethods<SymbolUserOpInterface>
|
||||
]> {
|
||||
|
|
|
@ -16,12 +16,7 @@
|
|||
#include "mlir/IR/BuiltinAttributes.h"
|
||||
#include "mlir/IR/Types.h"
|
||||
|
||||
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
|
||||
namespace circt::om {} // namespace circt::om
|
||||
|
||||
#define GET_TYPEDEF_CLASSES
|
||||
#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", []> {
|
||||
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 @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
|
||||
|
||||
%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>
|
||||
|
||||
%tuple = om.tuple_create %list, %c_14: !om.list<!om.string>, !om.integer
|
||||
|
||||
%c_15 = om.constant #om.integer<15> : !om.integer
|
||||
%1 = om.object @Child(%c_15) : (!om.integer) -> !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>
|
||||
|
||||
%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
|
||||
%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) {
|
||||
|
@ -158,21 +150,6 @@ print("child.foo: ", obj.child.foo)
|
|||
print("child.foo.loc", obj.child.get_field_loc("foo"))
|
||||
# CHECK: ('Root', 'x')
|
||||
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:
|
||||
# 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
|
||||
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")
|
||||
object_dict: Dict[om.Object, str] = {}
|
||||
for field_name, data in obj:
|
||||
|
|
|
@ -26,8 +26,6 @@ namespace {
|
|||
|
||||
struct List;
|
||||
struct Object;
|
||||
struct Tuple;
|
||||
struct Map;
|
||||
struct BasePath;
|
||||
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
|
||||
/// is tried first, then we can hit an assert inside the MLIR codebase.
|
||||
struct None {};
|
||||
using PythonValue = std::variant<None, Object, List, Tuple, Map, BasePath, Path,
|
||||
PythonPrimitive>;
|
||||
using PythonValue =
|
||||
std::variant<None, Object, List, BasePath, Path, PythonPrimitive>;
|
||||
|
||||
/// Map an opaque OMEvaluatorValue into a python value.
|
||||
PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result);
|
||||
|
@ -69,58 +67,6 @@ private:
|
|||
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.
|
||||
struct BasePath {
|
||||
/// Instantiate a BasePath with a reference to the underlying
|
||||
|
@ -289,80 +235,6 @@ private:
|
|||
PythonValue List::getElement(intptr_t 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++
|
||||
// fast path of the parts of attribute_to_var that we use in the OM dialect.
|
||||
static PythonPrimitive omPrimitiveToPythonValue(MlirAttribute attr) {
|
||||
|
@ -411,17 +283,6 @@ static PythonPrimitive omPrimitiveToPythonValue(MlirAttribute attr) {
|
|||
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);
|
||||
throw nb::type_error("Unexpected OM primitive attribute");
|
||||
}
|
||||
|
@ -493,14 +354,6 @@ PythonValue omEvaluatorValueToPythonValue(OMEvaluatorValue result) {
|
|||
if (omEvaluatorValueIsAList(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 (omEvaluatorValueIsABasePath(result))
|
||||
return BasePath(result);
|
||||
|
@ -523,12 +376,6 @@ OMEvaluatorValue pythonValueToOMEvaluatorValue(PythonValue result,
|
|||
if (auto *list = std::get_if<List>(&result))
|
||||
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))
|
||||
return basePath->getValue();
|
||||
|
||||
|
@ -563,18 +410,6 @@ void circt::python::populateDialectOMSubmodule(nb::module_ &m) {
|
|||
.def("__getitem__", &List::getElement)
|
||||
.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.
|
||||
nb::class_<BasePath>(m, "BasePath")
|
||||
.def(nb::init<BasePath>(), nb::arg("basepath"))
|
||||
|
@ -628,12 +463,6 @@ void circt::python::populateDialectOMSubmodule(nb::module_ &m) {
|
|||
[](MlirAttribute arr) { return PyListAttrIterator(arr); });
|
||||
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.
|
||||
mlir_type_subclass(m, "AnyType", omTypeIsAAnyType, omAnyTypeGetTypeID);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
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 ..support import attribute_to_var, var_to_attribute
|
||||
|
@ -28,12 +28,6 @@ def wrap_mlir_object(value):
|
|||
if isinstance(value, BaseList):
|
||||
return List(value)
|
||||
|
||||
if isinstance(value, BaseTuple):
|
||||
return Tuple(value)
|
||||
|
||||
if isinstance(value, BaseMap):
|
||||
return Map(value)
|
||||
|
||||
if isinstance(value, BaseBasePath):
|
||||
return BasePath(value)
|
||||
|
||||
|
@ -56,12 +50,6 @@ def unwrap_python_object(value):
|
|||
if isinstance(value, List):
|
||||
return BaseList(value)
|
||||
|
||||
if isinstance(value, Tuple):
|
||||
return BaseTuple(value)
|
||||
|
||||
if isinstance(value, Map):
|
||||
return BaseMap(value)
|
||||
|
||||
if isinstance(value, BasePath):
|
||||
return BaseBasePath(value)
|
||||
|
||||
|
@ -90,47 +78,6 @@ class List(BaseList):
|
|||
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):
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -248,10 +248,6 @@ def attribute_to_var(attr):
|
|||
return list(map(attribute_to_var, om.ListAttr(attr)))
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
return {name: attribute_to_var(value) for name, value in om.MapAttr(attr)}
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
return int(str(om.OMIntegerAttr(attr)))
|
||||
except ValueError:
|
||||
|
|
|
@ -90,14 +90,6 @@ MlirType omStringTypeGet(MlirContext ctx) {
|
|||
/// Get the TypeID for a StringType.
|
||||
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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -196,15 +188,6 @@ MlirAttribute omEvaluatorObjectGetFieldNames(OMEvaluatorValue object) {
|
|||
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.
|
||||
OMEvaluatorValue omEvaluatorObjectGetField(OMEvaluatorValue object,
|
||||
MlirAttribute name) {
|
||||
|
@ -296,41 +279,6 @@ OMEvaluatorValue omEvaluatorListGetElement(OMEvaluatorValue evaluatorValue,
|
|||
->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) {
|
||||
return isa<evaluator::BasePathValue>(unwrap(evaluatorValue).get());
|
||||
}
|
||||
|
@ -440,24 +388,3 @@ MlirAttribute omListAttrGet(MlirType elementType, intptr_t numElements,
|
|||
auto *ctx = type.getContext();
|
||||
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;
|
||||
assert(isFullyEvaluated());
|
||||
return llvm::TypeSwitch<EvaluatorValue *, LogicalResult>(this)
|
||||
.Case<AttributeValue, ObjectValue, ListValue, MapValue, ReferenceValue,
|
||||
TupleValue, BasePathValue, PathValue>(
|
||||
[](auto v) { return v->finalizeImpl(); });
|
||||
.Case<AttributeValue, ObjectValue, ListValue, ReferenceValue,
|
||||
BasePathValue, PathValue>([](auto v) { return v->finalizeImpl(); });
|
||||
}
|
||||
|
||||
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<ObjectValue>([](auto *object) { return object->getObjectType(); })
|
||||
.Case<ListValue>([](auto *list) { return list->getListType(); })
|
||||
.Case<MapValue>([](auto *map) { return map->getMapType(); })
|
||||
.Case<ReferenceValue>([](auto *ref) { return ref->getValueType(); })
|
||||
.Case<TupleValue>([](auto *tuple) { return tuple->getTupleType(); })
|
||||
.Case<BasePathValue>(
|
||||
[this](auto *tuple) { return FrozenBasePathType::get(ctx); })
|
||||
.Case<PathValue>(
|
||||
|
@ -73,22 +70,11 @@ circt::om::Evaluator::getPartiallyEvaluatedValue(Type type, Location loc) {
|
|||
using namespace circt::om::evaluator;
|
||||
|
||||
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) {
|
||||
evaluator::EvaluatorValuePtr result =
|
||||
std::make_shared<evaluator::ListValue>(type, loc);
|
||||
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)
|
||||
-> FailureOr<evaluator::EvaluatorValuePtr> {
|
||||
ClassOp cls =
|
||||
|
@ -167,13 +153,9 @@ FailureOr<evaluator::EvaluatorValuePtr> circt::om::Evaluator::getOrCreateValue(
|
|||
evaluator::PathValue::getEmptyPath(loc));
|
||||
return success(result);
|
||||
})
|
||||
.Case<ListCreateOp, ListConcatOp, TupleCreateOp, MapCreateOp,
|
||||
ObjectFieldOp>([&](auto op) {
|
||||
.Case<ListCreateOp, ListConcatOp, ObjectFieldOp>([&](auto op) {
|
||||
return getPartiallyEvaluatedValue(op.getType(), loc);
|
||||
})
|
||||
.Case<TupleGetOp>([&](auto op) {
|
||||
return evaluateTupleGet(op, actualParams, loc);
|
||||
})
|
||||
.Case<ObjectOp>([&](auto op) {
|
||||
return getPartiallyEvaluatedValue(op.getType(), op.getLoc());
|
||||
})
|
||||
|
@ -369,18 +351,9 @@ circt::om::Evaluator::evaluateValue(Value value, ActualParameters actualParams,
|
|||
.Case([&](ListConcatOp op) {
|
||||
return evaluateListConcat(op, actualParams, loc);
|
||||
})
|
||||
.Case([&](TupleCreateOp op) {
|
||||
return evaluateTupleCreate(op, actualParams, loc);
|
||||
})
|
||||
.Case([&](TupleGetOp op) {
|
||||
return evaluateTupleGet(op, actualParams, loc);
|
||||
})
|
||||
.Case([&](AnyCastOp op) {
|
||||
return evaluateValue(op.getInput(), actualParams, loc);
|
||||
})
|
||||
.Case([&](MapCreateOp op) {
|
||||
return evaluateMapCreate(op, actualParams, loc);
|
||||
})
|
||||
.Case([&](FrozenBasePathCreateOp op) {
|
||||
return evaluateBasePathCreate(op, actualParams, loc);
|
||||
})
|
||||
|
@ -635,67 +608,6 @@ circt::om::Evaluator::evaluateListConcat(ListConcatOp op,
|
|||
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>
|
||||
circt::om::Evaluator::evaluateBasePathCreate(FrozenBasePathCreateOp op,
|
||||
ActualParameters actualParams,
|
||||
|
@ -771,36 +683,6 @@ LogicalResult circt::om::evaluator::ObjectValue::finalizeImpl() {
|
|||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#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"
|
||||
|
||||
|
@ -36,11 +35,6 @@ 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));
|
||||
|
@ -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 {
|
||||
odsPrinter << '[';
|
||||
llvm::interleaveComma(getPath(), odsPrinter, [&](PathElement element) {
|
||||
|
|
|
@ -611,80 +611,6 @@ ParseResult circt::om::ListCreateOp::parse(OpAsmParser &parser,
|
|||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -30,18 +30,3 @@ void circt::om::OMDialect::registerTypes() {
|
|||
#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>"
|
||||
" om.class.fields %param, %0 : !om.integer, !om.class.type<@Child>"
|
||||
" }"
|
||||
" om.class @Child() -> (foo: i64, bar: !om.list<i64>, baz: "
|
||||
"tuple<!om.list<i64>, i64>){"
|
||||
" om.class @Child() -> (foo: i64, bar: !om.list<i64>){"
|
||||
" %0 = om.constant 14 : i64"
|
||||
" %1 = om.constant 15 : i64"
|
||||
" %2 = om.list_create %0, %1 : i64"
|
||||
" %3 = om.tuple_create %2, %0 : !om.list<i64>, i64"
|
||||
" om.class.fields %0, %2, %3 : i64, !om.list<i64>, "
|
||||
"tuple<!om.list<i64>, i64>"
|
||||
" om.class.fields %0, %2 : i64, !om.list<i64>"
|
||||
" }"
|
||||
"}";
|
||||
|
||||
|
@ -202,12 +199,9 @@ void testEvaluator(MlirContext ctx) {
|
|||
OMEvaluatorValue bar = omEvaluatorObjectGetField(
|
||||
child, mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("bar")));
|
||||
|
||||
OMEvaluatorValue baz = omEvaluatorObjectGetField(
|
||||
child, mlirStringAttrGet(ctx, mlirStringRefCreateFromCString("baz")));
|
||||
|
||||
MlirAttribute fieldNamesC = omEvaluatorObjectGetFieldNames(child);
|
||||
|
||||
// CHECK: ["bar", "baz", "foo"]
|
||||
// CHECK: ["bar", "foo"]
|
||||
mlirAttributeDump(fieldNamesC);
|
||||
|
||||
// CHECK: child object field `foo` is primitive: 1
|
||||
|
@ -226,14 +220,6 @@ void testEvaluator(MlirContext ctx) {
|
|||
// CHECK: 15 : i64
|
||||
mlirAttributeDump(
|
||||
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) {
|
||||
|
|
|
@ -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.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
|
||||
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.module @PathModule() {
|
||||
|
|
|
@ -1323,40 +1323,6 @@ TEST(EvaluatorTests, ListConcatPartialCycle) {
|
|||
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) {
|
||||
StringRef mod =
|
||||
"om.class @Empty() {"
|
||||
|
|
Loading…
Reference in New Issue