mirror of https://github.com/llvm/circt.git
[OM] Add om.map_create op (#5870)
This PR adds om.map_create op for om.map object creation which takes a variadic length of operands whose type is a same tuple.
This commit is contained in:
parent
325d74c1a0
commit
becb4c0ef3
|
@ -261,4 +261,28 @@ def TupleGetOp : OMOp<"tuple_get", [Pure, InferTypeOpInterface]> {
|
|||
}];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endif // CIRCT_DIALECT_OM_OMOPS_TD
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
#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
|
||||
|
||||
#define GET_TYPEDEF_CLASSES
|
||||
#include "circt/Dialect/OM/OMTypes.h.inc"
|
||||
|
||||
|
|
|
@ -421,6 +421,38 @@ LogicalResult TupleGetOp::inferReturnTypes(
|
|||
return success();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MapCreateOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
void circt::om::MapCreateOp::print(OpAsmPrinter &p) {
|
||||
p << " ";
|
||||
p.printOperands(getInputs());
|
||||
p.printOptionalAttrDict((*this)->getAttrs());
|
||||
p << " : " << getType().cast<circt::om::MapType>().getKeyType() << ", "
|
||||
<< getType().cast<circt::om::MapType>().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();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TableGen generated logic.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -35,3 +35,9 @@ circt::om::MapType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> diag,
|
|||
<< 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());
|
||||
}
|
||||
|
|
|
@ -191,3 +191,11 @@ om.class @MapConstant() {
|
|||
// CHECK: om.class.field @map_i64, %[[const1]] : !om.map<!om.string, i64>
|
||||
om.class.field @map_i64, %0 : !om.map<!om.string, i64>
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @MapCreate
|
||||
om.class @MapCreate(%e1: tuple<!om.string, !om.class.type<@Empty>>, %e2: tuple<!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.field @map_field, %[[map]] : !om.map<!om.string, !om.class.type<@Empty>>
|
||||
om.class.field @map_field, %map : !om.map<!om.string, !om.class.type<@Empty>>
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue