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 SmallVector<StructLikeMember> &members);
45 ArrayRef<StructLikeMember> members);
55 return TypeSwitch<UnpackedType, Domain>(*
this)
56 .Case<
PackedType>([](
auto type) {
return type.getDomain(); })
57 .Case<UnpackedArrayType, OpenUnpackedArrayType, AssocArrayType,
59 [&](
auto type) {
return type.getElementType().getDomain(); })
60 .Case<UnpackedStructType, UnpackedUnionType>([](
auto type) {
61 for (
const auto &member : type.getMembers())
70 return TypeSwitch<UnpackedType, std::optional<unsigned>>(*this)
71 .Case<
PackedType>([](
auto type) {
return type.getBitSize(); })
72 .Case<RealType>([](
auto type) {
return 64; })
73 .Case<UnpackedArrayType>([](
auto type) -> std::optional<unsigned> {
74 if (
auto size = type.getElementType().getBitSize())
75 return (*size) * type.getSize();
78 .Case<UnpackedStructType>([](
auto type) -> std::optional<unsigned> {
80 for (
const auto &member : type.getMembers()) {
81 if (
auto memberSize = member.type.getBitSize()) {
89 .Case<UnpackedUnionType>([](
auto type) -> std::optional<unsigned> {
91 for (
const auto &member : type.getMembers()) {
92 if (
auto memberSize = member.type.getBitSize()) {
93 size = (*memberSize > size) ? *memberSize : size;
100 .Default([](
auto) {
return std::nullopt; });
119 return TypeSwitch<PackedType, Domain>(*
this)
121 .Case<IntType>([&](
auto type) {
return type.getDomain(); })
123 .Case<ArrayType, OpenArrayType>(
124 [&](
auto type) {
return type.getElementType().getDomain(); })
125 .Case<StructType, UnionType>([](
auto type) {
126 for (
const auto &member : type.getMembers())
134 return TypeSwitch<PackedType, std::optional<unsigned>>(*this)
135 .Case<VoidType>([](
auto) {
return 0; })
136 .Case<IntType>([](
auto type) {
return type.getWidth(); })
137 .Case<TimeType>([](
auto type) {
return 64; })
138 .Case<ArrayType>([](
auto type) -> std::optional<unsigned> {
139 if (
auto size = type.getElementType().getBitSize())
140 return (*size) * type.getSize();
143 .Case<OpenArrayType>([](
auto) {
return std::nullopt; })
144 .Case<StructType>([](
auto type) -> std::optional<unsigned> {
146 for (
const auto &member : type.getMembers()) {
147 if (
auto memberSize = member.type.getBitSize()) {
155 .Case<UnionType>([](
auto type) -> std::optional<unsigned> {
157 for (
const auto &member : type.getMembers()) {
158 if (
auto memberSize = member.type.getBitSize()) {
159 size = (*memberSize > size) ? *memberSize : size;
166 .Default([](
auto) {
return std::nullopt; });
170 if (
auto intType = dyn_cast<IntType>(*
this))
173 return IntType::get(getContext(), *bitSize,
getDomain());
178 return TypeSwitch<PackedType, bool>(*
this)
179 .Case<VoidType, IntType>([](
auto) {
return false; })
180 .Case<TimeType>([](
auto) {
return true; })
181 .Case<ArrayType, OpenArrayType>(
182 [](
auto type) {
return type.getElementType().containsTimeType(); })
183 .Case<StructType, UnionType>([](
auto type) {
184 return llvm::any_of(type.getMembers(), [](
auto &member) {
185 return cast<PackedType>(member.type).containsTimeType();
196 SmallVector<StructLikeMember> &members) {
197 return parser.parseCommaSeparatedList(AsmParser::Delimiter::Braces, [&]() {
200 if (parser.parseKeywordOrString(&name) || parser.parseColon() ||
201 parser.parseCustomTypeWithFallback(type))
204 members.push_back({StringAttr::get(parser.getContext(), name), type});
211 ArrayRef<StructLikeMember> members) {
213 llvm::interleaveComma(members, printer.getStream(),
215 printer.printKeywordOrString(member.name);
217 printer.printStrippedAttrOrType(member.type);
224 ArrayRef<StructLikeMember> members) {
225 if (!llvm::all_of(members, [](
const auto &member) {
226 return llvm::isa<PackedType>(member.type);
228 return emitError() <<
"StructType/UnionType members must be packed types";
232LogicalResult StructType::verify(function_ref<InFlightDiagnostic()> emitError,
233 ArrayRef<StructLikeMember> members) {
237LogicalResult UnionType::verify(function_ref<InFlightDiagnostic()> emitError,
238 ArrayRef<StructLikeMember> members) {
246static std::optional<DenseMap<Attribute, Type>>
248 DenseMap<Attribute, Type> destructured;
249 for (
const auto &member : members)
250 destructured.insert({member.name, RefType::get(member.type)});
256 auto indexAttr = cast<StringAttr>(index);
259 for (
const auto &member : members) {
260 if (member.name == indexAttr) {
261 return RefType::get(member.type);
267static std::optional<uint32_t>
269 for (uint32_t fieldIndex = 0; fieldIndex < members.size(); fieldIndex++)
270 if (members[fieldIndex].name == nameField)
275std::optional<DenseMap<Attribute, Type>> StructType::getSubelementIndexMap() {
279Type StructType::getTypeAtIndex(Attribute index) {
283std::optional<uint32_t> StructType::getFieldIndex(StringAttr nameField) {
287std::optional<DenseMap<Attribute, Type>>
288UnpackedStructType::getSubelementIndexMap() {
292Type UnpackedStructType::getTypeAtIndex(Attribute index) {
296std::optional<uint32_t>
297UnpackedStructType::getFieldIndex(StringAttr nameField) {
301std::optional<DenseMap<Attribute, Type>> UnionType::getSubelementIndexMap() {
305Type UnionType::getTypeAtIndex(Attribute index) {
309std::optional<uint32_t> UnionType::getFieldIndex(StringAttr nameField) {
313std::optional<DenseMap<Attribute, Type>>
314UnpackedUnionType::getSubelementIndexMap() {
318Type UnpackedUnionType::getTypeAtIndex(Attribute index) {
322std::optional<uint32_t> UnpackedUnionType::getFieldIndex(StringAttr nameField) {
326std::optional<DenseMap<Attribute, Type>> RefType::getSubelementIndexMap() {
327 return TypeSwitch<Type, std::optional<DenseMap<Attribute, Type>>>(
329 .Case<StructType, UnpackedStructType>([](
auto &type) {
332 .Default([](
auto) {
return std::nullopt; });
335Type RefType::getTypeAtIndex(Attribute index) {
336 return TypeSwitch<Type, Type>(getNestedType())
337 .Case<StructType, UnpackedStructType>([&index](
auto &type) {
340 .Default([](
auto) {
return Type(); });
343std::optional<uint32_t> RefType::getFieldIndex(StringAttr nameField) {
344 return TypeSwitch<Type, std::optional<uint32_t>>(getNestedType())
345 .Case<StructType, UnpackedStructType>([&nameField](
auto &type) {
348 .Default([](
auto) {
return std::nullopt; });
355#define GET_TYPEDEF_CLASSES
356#include "circt/Dialect/Moore/MooreTypes.cpp.inc"
358void MooreDialect::registerTypes() {
360#define GET_TYPEDEF_LIST
361#include "circt/Dialect/Moore/MooreTypes.cpp.inc"
371 llvm::SMLoc loc = parser.getCurrentLocation();
375 if (
auto result = generatedTypeParser(parser, &mnemonic, type);
377 return result.value();
380 if (mnemonic.size() > 1 && (mnemonic[0] ==
'i' || mnemonic[0] ==
'l') &&
383 auto spelling = mnemonic.drop_front(1);
385 if (spelling.getAsInteger(10, width))
386 return parser.emitError(loc,
"integer width invalid");
387 type = IntType::get(parser.getContext(), width, domain);
391 parser.emitError(loc) <<
"unknown type `" << mnemonic
392 <<
"` in dialect `moore`";
399 if (
auto intType = dyn_cast<IntType>(type)) {
401 printer << intType.getWidth();
406 if (succeeded(generatedTypePrinter(type, printer)))
408 assert(
false &&
"no printer for unknown `moore` dialect type");
412Type MooreDialect::parseType(DialectAsmParser &parser)
const {
420void MooreDialect::printType(Type type, DialectAsmPrinter &printer)
const {
assert(baseType &&"element must be base type")
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 void printMooreType(Type type, AsmPrinter &printer)
Print a type registered with this dialect.
static Type getTypeAtAllIndex(ArrayRef< StructLikeMember > members, Attribute index)
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
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.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.