[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:
Hideto Ueno 2023-08-23 18:07:40 +09:00 committed by GitHub
parent 325d74c1a0
commit becb4c0ef3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 0 deletions

View File

@ -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 #endif // CIRCT_DIALECT_OM_OMOPS_TD

View File

@ -16,6 +16,12 @@
#include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/Types.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 #define GET_TYPEDEF_CLASSES
#include "circt/Dialect/OM/OMTypes.h.inc" #include "circt/Dialect/OM/OMTypes.h.inc"

View File

@ -421,6 +421,38 @@ LogicalResult TupleGetOp::inferReturnTypes(
return success(); 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. // TableGen generated logic.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -35,3 +35,9 @@ circt::om::MapType::verify(llvm::function_ref<mlir::InFlightDiagnostic()> diag,
<< keyType; << keyType;
return mlir::success(); 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());
}

View File

@ -191,3 +191,11 @@ om.class @MapConstant() {
// CHECK: om.class.field @map_i64, %[[const1]] : !om.map<!om.string, i64> // CHECK: om.class.field @map_i64, %[[const1]] : !om.map<!om.string, i64>
om.class.field @map_i64, %0 : !om.map<!om.string, i64> 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>>
}