15#include "mlir/IR/Builders.h"
16#include "mlir/IR/DialectImplementation.h"
17#include "llvm/ADT/TypeSwitch.h"
22using mlir::AsmPrinter;
25 if (
auto intType = dyn_cast<IntType>(type))
26 return intType.getWidth() == width;
31 if (
auto intType = dyn_cast<IntType>(type))
32 return intType.getDomain() == domain;
37 if (
auto intType = dyn_cast<IntType>(type))
38 return intType.getWidth() == width && intType.getDomain() == domain;
43 if (
auto realType = dyn_cast<RealType>(type))
50 SmallVector<StructLikeMember> &members);
52 ArrayRef<StructLikeMember> members);
62 return TypeSwitch<UnpackedType, Domain>(*
this)
63 .Case<
PackedType>([](
auto type) {
return type.getDomain(); })
64 .Case<UnpackedArrayType, OpenUnpackedArrayType, AssocArrayType,
66 [&](
auto type) {
return type.getElementType().getDomain(); })
67 .Case<UnpackedStructType, UnpackedUnionType>([](
auto type) {
68 for (
const auto &member : type.getMembers())
77 return TypeSwitch<UnpackedType, std::optional<unsigned>>(*this)
78 .Case<
PackedType>([](
auto type) {
return type.getBitSize(); })
80 [](
auto type) {
return type.getWidth() ==
RealWidth::f32 ? 32 : 64; })
81 .Case<UnpackedArrayType>([](
auto type) -> std::optional<unsigned> {
82 if (
auto size = type.getElementType().getBitSize())
83 return (*size) * type.getSize();
86 .Case<UnpackedStructType>([](
auto type) -> std::optional<unsigned> {
88 for (
const auto &member : type.getMembers()) {
89 if (
auto memberSize = member.type.getBitSize()) {
97 .Case<UnpackedUnionType>([](
auto type) -> std::optional<unsigned> {
99 for (
const auto &member : type.getMembers()) {
100 if (
auto memberSize = member.type.getBitSize()) {
101 size = (*memberSize > size) ? *memberSize : size;
108 .Default([](
auto) {
return std::nullopt; });
127 return TypeSwitch<WrapperType, UnpackedType>(*this).Case<RefType, NetType>(
128 [](
auto type) { return type.getNestedType(); });
132 return TypeSwitch<WrapperType, WrapperType>(*this).Case<RefType, NetType>(
133 [&](
auto type) { return decltype(type)::get(nestedType); });
141 return TypeSwitch<PackedType, Domain>(*
this)
143 .Case<IntType>([&](
auto type) {
return type.getDomain(); })
145 .Case<ArrayType, OpenArrayType>(
146 [&](
auto type) {
return type.getElementType().getDomain(); })
147 .Case<StructType, UnionType>([](
auto type) {
148 for (
const auto &member : type.getMembers())
156 return TypeSwitch<PackedType, std::optional<unsigned>>(*this)
157 .Case<VoidType>([](
auto) {
return 0; })
158 .Case<IntType>([](
auto type) {
return type.getWidth(); })
159 .Case<TimeType>([](
auto type) {
return 64; })
160 .Case<ArrayType>([](
auto type) -> std::optional<unsigned> {
161 if (
auto size = type.getElementType().getBitSize())
162 return (*size) * type.getSize();
165 .Case<OpenArrayType>([](
auto) {
return std::nullopt; })
166 .Case<StructType>([](
auto type) -> std::optional<unsigned> {
168 for (
const auto &member : type.getMembers()) {
169 if (
auto memberSize = member.type.getBitSize()) {
177 .Case<UnionType>([](
auto type) -> std::optional<unsigned> {
179 for (
const auto &member : type.getMembers()) {
180 if (
auto memberSize = member.type.getBitSize()) {
181 size = (*memberSize > size) ? *memberSize : size;
188 .Default([](
auto) {
return std::nullopt; });
192 if (
auto intType = dyn_cast<IntType>(*
this))
195 return IntType::get(getContext(), *bitSize,
getDomain());
200 return TypeSwitch<PackedType, bool>(*
this)
201 .Case<VoidType, IntType>([](
auto) {
return false; })
202 .Case<TimeType>([](
auto) {
return true; })
203 .Case<ArrayType, OpenArrayType>(
204 [](
auto type) {
return type.getElementType().containsTimeType(); })
205 .Case<StructType, UnionType>([](
auto type) {
206 return llvm::any_of(type.getMembers(), [](
auto &member) {
207 return cast<PackedType>(member.type).containsTimeType();
218 SmallVector<StructLikeMember> &members) {
219 return parser.parseCommaSeparatedList(AsmParser::Delimiter::Braces, [&]() {
222 if (parser.parseKeywordOrString(&name) || parser.parseColon() ||
223 parser.parseCustomTypeWithFallback(type))
226 members.push_back({StringAttr::get(parser.getContext(), name), type});
233 ArrayRef<StructLikeMember> members) {
235 llvm::interleaveComma(members, printer.getStream(),
237 printer.printKeywordOrString(member.name);
239 printer.printStrippedAttrOrType(member.type);
246 ArrayRef<StructLikeMember> members) {
247 if (!llvm::all_of(members, [](
const auto &member) {
248 return llvm::isa<PackedType>(member.type);
250 return emitError() <<
"StructType/UnionType members must be packed types";
254LogicalResult StructType::verify(function_ref<InFlightDiagnostic()> emitError,
255 ArrayRef<StructLikeMember> members) {
259LogicalResult UnionType::verify(function_ref<InFlightDiagnostic()> emitError,
260 ArrayRef<StructLikeMember> members) {
268template <
typename WrapperTy = RefType>
269static std::optional<DenseMap<Attribute, Type>>
271 DenseMap<Attribute, Type> destructured;
272 for (
const auto &member : members)
273 destructured.insert({member.name, WrapperTy::get(member.type)});
277template <
typename WrapperTy = RefType>
280 auto indexAttr = cast<StringAttr>(index);
283 for (
const auto &member : members) {
284 if (member.name == indexAttr) {
285 return WrapperTy::get(member.type);
291static std::optional<uint32_t>
293 for (uint32_t fieldIndex = 0; fieldIndex < members.size(); fieldIndex++)
294 if (members[fieldIndex].name == nameField)
299std::optional<DenseMap<Attribute, Type>> StructType::getSubelementIndexMap() {
303Type StructType::getTypeAtIndex(Attribute index) {
307std::optional<uint32_t> StructType::getFieldIndex(StringAttr nameField) {
311std::optional<DenseMap<Attribute, Type>>
312UnpackedStructType::getSubelementIndexMap() {
316Type UnpackedStructType::getTypeAtIndex(Attribute index) {
320std::optional<uint32_t>
321UnpackedStructType::getFieldIndex(StringAttr nameField) {
325std::optional<DenseMap<Attribute, Type>> UnionType::getSubelementIndexMap() {
329Type UnionType::getTypeAtIndex(Attribute index) {
333std::optional<uint32_t> UnionType::getFieldIndex(StringAttr nameField) {
337std::optional<DenseMap<Attribute, Type>>
338UnpackedUnionType::getSubelementIndexMap() {
342Type UnpackedUnionType::getTypeAtIndex(Attribute index) {
346std::optional<uint32_t> UnpackedUnionType::getFieldIndex(StringAttr nameField) {
350std::optional<DenseMap<Attribute, Type>> RefType::getSubelementIndexMap() {
351 return TypeSwitch<Type, std::optional<DenseMap<Attribute, Type>>>(
353 .Case<StructType, UnpackedStructType>([](
auto &type) {
356 .Default([](
auto) {
return std::nullopt; });
359Type RefType::getTypeAtIndex(Attribute index) {
360 return TypeSwitch<Type, Type>(getNestedType())
361 .Case<StructType, UnpackedStructType>([&index](
auto &type) {
364 .Default([](
auto) {
return Type(); });
367std::optional<uint32_t> RefType::getFieldIndex(StringAttr nameField) {
368 return TypeSwitch<Type, std::optional<uint32_t>>(getNestedType())
369 .Case<StructType, UnpackedStructType>([&nameField](
auto &type) {
372 .Default([](
auto) {
return std::nullopt; });
375std::optional<DenseMap<Attribute, Type>> NetType::getSubelementIndexMap() {
376 return TypeSwitch<Type, std::optional<DenseMap<Attribute, Type>>>(
378 .Case<StructType, UnpackedStructType>([](
auto &type) {
381 .Default([](
auto) {
return std::nullopt; });
384Type NetType::getTypeAtIndex(Attribute index) {
385 return TypeSwitch<Type, Type>(getNestedType())
386 .Case<StructType, UnpackedStructType>([&index](
auto &type) {
389 .Default([](
auto) {
return Type(); });
392std::optional<uint32_t> NetType::getFieldIndex(StringAttr nameField) {
393 return TypeSwitch<Type, std::optional<uint32_t>>(getNestedType())
394 .Case<StructType, UnpackedStructType>([&nameField](
auto &type) {
397 .Default([](
auto) {
return std::nullopt; });
404#define GET_TYPEDEF_CLASSES
405#include "circt/Dialect/Moore/MooreTypes.cpp.inc"
407void MooreDialect::registerTypes() {
409#define GET_TYPEDEF_LIST
410#include "circt/Dialect/Moore/MooreTypes.cpp.inc"
420 llvm::SMLoc loc = parser.getCurrentLocation();
424 if (
auto result = generatedTypeParser(parser, &mnemonic, type);
426 return result.value();
429 if (mnemonic.size() > 1 && (mnemonic[0] ==
'i' || mnemonic[0] ==
'l') &&
432 auto spelling = mnemonic.drop_front(1);
434 if (spelling.getAsInteger(10, width))
435 return parser.emitError(loc,
"integer width invalid");
436 type = IntType::get(parser.getContext(), width, domain);
440 if (mnemonic ==
"f32") {
445 if (mnemonic ==
"f64") {
450 parser.emitError(loc) <<
"unknown type `" << mnemonic
451 <<
"` in dialect `moore`";
458 if (
auto intType = dyn_cast<IntType>(type)) {
460 printer << intType.getWidth();
463 if (
auto rt = dyn_cast<moore::RealType>(type)) {
473 if (succeeded(generatedTypePrinter(type, printer)))
475 assert(
false &&
"no printer for unknown `moore` dialect type");
479Type MooreDialect::parseType(DialectAsmParser &parser)
const {
487void MooreDialect::printType(Type type, DialectAsmPrinter &printer)
const {
assert(baseType &&"element must be base type")
false return failure()
Parse an optional keyword or string and set instance into 'result'.
static std::optional< uint32_t > getFieldAllIndex(ArrayRef< StructLikeMember > members, StringAttr nameField)
static LogicalResult verifyAllMembersPacked(function_ref< InFlightDiagnostic()> emitError, ArrayRef< StructLikeMember > members)
static LogicalResult parseMembers(AsmParser &parser, SmallVector< StructLikeMember > &members)
Parse a list of struct members.
static ParseResult parseMooreType(AsmParser &parser, Type &type)
Parse a type registered with this dialect.
static void printMembers(AsmPrinter &printer, ArrayRef< StructLikeMember > members)
Print a list of struct members.
static Type getTypeAtAllIndex(ArrayRef< StructLikeMember > members, Attribute index)
static void printMooreType(Type type, AsmPrinter &printer)
Print a type registered with this dialect.
static std::optional< DenseMap< Attribute, Type > > getAllSubelementIndexMap(ArrayRef< StructLikeMember > members)
A packed SystemVerilog type.
bool containsTimeType() const
Check if this is a TimeType, or an aggregate that contains a nested TimeType.
std::optional< unsigned > getBitSize() const
Get the size of this type in bits.
Domain getDomain() const
Get the value domain of this type.
IntType getSimpleBitVector() const
Get the simple bit vector type equivalent to this packed type.
An unpacked SystemVerilog type.
std::optional< unsigned > getBitSize() const
Get the size of this type in bits.
Domain getDomain() const
Get the value domain of this type.
static Type parse(mlir::AsmParser &odsParser)
void print(mlir::AsmPrinter &odsPrinter) const
UnpackedType getNestedType() const
Get the wrapped type.
WrapperType withNestedType(UnpackedType nestedType) const
Get a wrapper of the same kind around a different nested type.
bool isRealType(Type type, unsigned width)
Check if a type is a RealType type of the given width.
Domain
The number of values each bit of a type can assume.
@ FourValued
Four-valued types such as logic or integer.
@ TwoValued
Two-valued types such as bit or int.
bool isIntType(Type type, unsigned width)
Check if a type is an IntType type of the given width.
@ f32
A standard 32-Bit floating point number ("float").
@ f64
A 64-bit double-precision floation point number ("double").
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.