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))
44 if (realType.getWidth() == RealWidth::f32)
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<PackedType, Domain>(*
this)
129 .Case<IntType>([&](
auto type) {
return type.getDomain(); })
131 .Case<ArrayType, OpenArrayType>(
132 [&](
auto type) {
return type.getElementType().getDomain(); })
133 .Case<StructType, UnionType>([](
auto type) {
134 for (
const auto &member : type.getMembers())
142 return TypeSwitch<PackedType, std::optional<unsigned>>(*this)
143 .Case<VoidType>([](
auto) {
return 0; })
144 .Case<IntType>([](
auto type) {
return type.getWidth(); })
145 .Case<TimeType>([](
auto type) {
return 64; })
146 .Case<ArrayType>([](
auto type) -> std::optional<unsigned> {
147 if (
auto size = type.getElementType().getBitSize())
148 return (*size) * type.getSize();
151 .Case<OpenArrayType>([](
auto) {
return std::nullopt; })
152 .Case<StructType>([](
auto type) -> std::optional<unsigned> {
154 for (
const auto &member : type.getMembers()) {
155 if (
auto memberSize = member.type.getBitSize()) {
163 .Case<UnionType>([](
auto type) -> std::optional<unsigned> {
165 for (
const auto &member : type.getMembers()) {
166 if (
auto memberSize = member.type.getBitSize()) {
167 size = (*memberSize > size) ? *memberSize : size;
174 .Default([](
auto) {
return std::nullopt; });
178 if (
auto intType = dyn_cast<IntType>(*
this))
181 return IntType::get(getContext(), *bitSize,
getDomain());
186 return TypeSwitch<PackedType, bool>(*
this)
187 .Case<VoidType, IntType>([](
auto) {
return false; })
188 .Case<TimeType>([](
auto) {
return true; })
189 .Case<ArrayType, OpenArrayType>(
190 [](
auto type) {
return type.getElementType().containsTimeType(); })
191 .Case<StructType, UnionType>([](
auto type) {
192 return llvm::any_of(type.getMembers(), [](
auto &member) {
193 return cast<PackedType>(member.type).containsTimeType();
204 SmallVector<StructLikeMember> &members) {
205 return parser.parseCommaSeparatedList(AsmParser::Delimiter::Braces, [&]() {
208 if (parser.parseKeywordOrString(&name) || parser.parseColon() ||
209 parser.parseCustomTypeWithFallback(type))
212 members.push_back({StringAttr::get(parser.getContext(), name), type});
219 ArrayRef<StructLikeMember> members) {
221 llvm::interleaveComma(members, printer.getStream(),
223 printer.printKeywordOrString(member.name);
225 printer.printStrippedAttrOrType(member.type);
232 ArrayRef<StructLikeMember> members) {
233 if (!llvm::all_of(members, [](
const auto &member) {
234 return llvm::isa<PackedType>(member.type);
236 return emitError() <<
"StructType/UnionType members must be packed types";
240LogicalResult StructType::verify(function_ref<InFlightDiagnostic()> emitError,
241 ArrayRef<StructLikeMember> members) {
245LogicalResult UnionType::verify(function_ref<InFlightDiagnostic()> emitError,
246 ArrayRef<StructLikeMember> members) {
254static std::optional<DenseMap<Attribute, Type>>
256 DenseMap<Attribute, Type> destructured;
257 for (
const auto &member : members)
258 destructured.insert({member.name, RefType::get(member.type)});
264 auto indexAttr = cast<StringAttr>(index);
267 for (
const auto &member : members) {
268 if (member.name == indexAttr) {
269 return RefType::get(member.type);
275static std::optional<uint32_t>
277 for (uint32_t fieldIndex = 0; fieldIndex < members.size(); fieldIndex++)
278 if (members[fieldIndex].name == nameField)
283std::optional<DenseMap<Attribute, Type>> StructType::getSubelementIndexMap() {
287Type StructType::getTypeAtIndex(Attribute index) {
291std::optional<uint32_t> StructType::getFieldIndex(StringAttr nameField) {
295std::optional<DenseMap<Attribute, Type>>
296UnpackedStructType::getSubelementIndexMap() {
300Type UnpackedStructType::getTypeAtIndex(Attribute index) {
304std::optional<uint32_t>
305UnpackedStructType::getFieldIndex(StringAttr nameField) {
309std::optional<DenseMap<Attribute, Type>> UnionType::getSubelementIndexMap() {
313Type UnionType::getTypeAtIndex(Attribute index) {
317std::optional<uint32_t> UnionType::getFieldIndex(StringAttr nameField) {
321std::optional<DenseMap<Attribute, Type>>
322UnpackedUnionType::getSubelementIndexMap() {
326Type UnpackedUnionType::getTypeAtIndex(Attribute index) {
330std::optional<uint32_t> UnpackedUnionType::getFieldIndex(StringAttr nameField) {
334std::optional<DenseMap<Attribute, Type>> RefType::getSubelementIndexMap() {
335 return TypeSwitch<Type, std::optional<DenseMap<Attribute, Type>>>(
337 .Case<StructType, UnpackedStructType>([](
auto &type) {
340 .Default([](
auto) {
return std::nullopt; });
343Type RefType::getTypeAtIndex(Attribute index) {
344 return TypeSwitch<Type, Type>(getNestedType())
345 .Case<StructType, UnpackedStructType>([&index](
auto &type) {
348 .Default([](
auto) {
return Type(); });
351std::optional<uint32_t> RefType::getFieldIndex(StringAttr nameField) {
352 return TypeSwitch<Type, std::optional<uint32_t>>(getNestedType())
353 .Case<StructType, UnpackedStructType>([&nameField](
auto &type) {
356 .Default([](
auto) {
return std::nullopt; });
363#define GET_TYPEDEF_CLASSES
364#include "circt/Dialect/Moore/MooreTypes.cpp.inc"
366void MooreDialect::registerTypes() {
368#define GET_TYPEDEF_LIST
369#include "circt/Dialect/Moore/MooreTypes.cpp.inc"
379 llvm::SMLoc loc = parser.getCurrentLocation();
383 if (
auto result = generatedTypeParser(parser, &mnemonic, type);
385 return result.value();
388 if (mnemonic.size() > 1 && (mnemonic[0] ==
'i' || mnemonic[0] ==
'l') &&
391 auto spelling = mnemonic.drop_front(1);
393 if (spelling.getAsInteger(10, width))
394 return parser.emitError(loc,
"integer width invalid");
395 type = IntType::get(parser.getContext(), width, domain);
399 if (mnemonic ==
"f32") {
404 if (mnemonic ==
"f64") {
409 parser.emitError(loc) <<
"unknown type `" << mnemonic
410 <<
"` in dialect `moore`";
417 if (
auto intType = dyn_cast<IntType>(type)) {
419 printer << intType.getWidth();
422 if (
auto rt = dyn_cast<moore::RealType>(type)) {
432 if (succeeded(generatedTypePrinter(type, printer)))
434 assert(
false &&
"no printer for unknown `moore` dialect type");
438Type MooreDialect::parseType(DialectAsmParser &parser)
const {
446void 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
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.