15 #include "mlir/IR/Builders.h"
16 #include "mlir/IR/DialectImplementation.h"
17 #include "llvm/ADT/TypeSwitch.h"
19 using namespace circt;
21 using mlir::AsmParser;
22 using mlir::AsmPrinter;
25 SmallVector<StructLikeMember> &members);
27 ArrayRef<StructLikeMember> members);
37 return TypeSwitch<UnpackedType, Domain>(*
this)
38 .Case<
PackedType>([](
auto type) {
return type.getDomain(); })
39 .Case<UnpackedArrayType, OpenUnpackedArrayType, AssocArrayType,
41 [&](
auto type) {
return type.getElementType().getDomain(); })
42 .Case<UnpackedStructType, UnpackedUnionType>([](
auto type) {
43 for (
const auto &member : type.getMembers())
52 return TypeSwitch<UnpackedType, std::optional<unsigned>>(*this)
53 .Case<
PackedType>([](
auto type) {
return type.getBitSize(); })
54 .Case<RealType>([](
auto type) {
return 64; })
55 .Case<UnpackedArrayType>([](
auto type) -> std::optional<unsigned> {
56 if (
auto size = type.getElementType().getBitSize())
57 return (*size) * type.getSize();
60 .Case<UnpackedStructType>([](
auto type) -> std::optional<unsigned> {
62 for (
const auto &member : type.getMembers()) {
63 if (
auto memberSize = member.type.getBitSize()) {
71 .Case<UnpackedUnionType>([](
auto type) -> std::optional<unsigned> {
73 for (
const auto &member : type.getMembers()) {
74 if (
auto memberSize = member.type.getBitSize()) {
75 size = (*memberSize > size) ? *memberSize : size;
82 .Default([](
auto) {
return std::nullopt; });
101 return TypeSwitch<PackedType, Domain>(*
this)
103 .Case<IntType>([&](
auto type) {
return type.getDomain(); })
104 .Case<ArrayType, OpenArrayType>(
105 [&](
auto type) {
return type.getElementType().getDomain(); })
106 .Case<StructType, UnionType>([](
auto type) {
107 for (
const auto &member : type.getMembers())
115 return TypeSwitch<PackedType, std::optional<unsigned>>(*this)
116 .Case<VoidType>([](
auto) {
return 0; })
117 .Case<IntType>([](
auto type) {
return type.getWidth(); })
118 .Case<ArrayType>([](
auto type) -> std::optional<unsigned> {
119 if (
auto size = type.getElementType().getBitSize())
120 return (*size) * type.getSize();
123 .Case<OpenArrayType>([](
auto) {
return std::nullopt; })
124 .Case<StructType>([](
auto type) -> std::optional<unsigned> {
126 for (
const auto &member : type.getMembers()) {
127 if (
auto memberSize = member.type.getBitSize()) {
135 .Case<UnionType>([](
auto type) -> std::optional<unsigned> {
137 for (
const auto &member : type.getMembers()) {
138 if (
auto memberSize = member.type.getBitSize()) {
139 size = (*memberSize > size) ? *memberSize : size;
146 .Default([](
auto) {
return std::nullopt; });
155 SmallVector<StructLikeMember> &members) {
156 return parser.parseCommaSeparatedList(AsmParser::Delimiter::Braces, [&]() {
159 if (parser.parseKeywordOrString(&name) || parser.parseColon() ||
160 parser.parseCustomTypeWithFallback(type))
170 ArrayRef<StructLikeMember> members) {
172 llvm::interleaveComma(members, printer.getStream(),
174 printer.printKeywordOrString(member.name);
176 printer.printStrippedAttrOrType(member.type);
183 ArrayRef<StructLikeMember> members) {
184 if (!llvm::all_of(members, [](
const auto &member) {
185 return llvm::isa<PackedType>(member.type);
187 return emitError() <<
"StructType/UnionType members must be packed types";
192 ArrayRef<StructLikeMember> members) {
197 ArrayRef<StructLikeMember> members) {
205 static std::optional<DenseMap<Attribute, Type>>
207 DenseMap<Attribute, Type> destructured;
208 for (
const auto &member : members)
209 destructured.insert({member.name,
RefType::get(member.type)});
215 auto indexAttr = cast<StringAttr>(index);
218 for (
const auto &member : members) {
219 if (member.name == indexAttr) {
226 static std::optional<uint32_t>
228 for (uint32_t fieldIndex = 0; fieldIndex < members.size(); fieldIndex++)
229 if (members[fieldIndex].name == nameField)
234 std::optional<DenseMap<Attribute, Type>> StructType::getSubelementIndexMap() {
238 Type StructType::getTypeAtIndex(Attribute index) {
242 std::optional<uint32_t> StructType::getFieldIndex(StringAttr nameField) {
246 std::optional<DenseMap<Attribute, Type>>
247 UnpackedStructType::getSubelementIndexMap() {
251 Type UnpackedStructType::getTypeAtIndex(Attribute index) {
255 std::optional<uint32_t>
256 UnpackedStructType::getFieldIndex(StringAttr nameField) {
260 std::optional<DenseMap<Attribute, Type>> UnionType::getSubelementIndexMap() {
264 Type UnionType::getTypeAtIndex(Attribute index) {
268 std::optional<uint32_t> UnionType::getFieldIndex(StringAttr nameField) {
272 std::optional<DenseMap<Attribute, Type>>
273 UnpackedUnionType::getSubelementIndexMap() {
277 Type UnpackedUnionType::getTypeAtIndex(Attribute index) {
281 std::optional<uint32_t> UnpackedUnionType::getFieldIndex(StringAttr nameField) {
285 std::optional<DenseMap<Attribute, Type>> RefType::getSubelementIndexMap() {
286 return TypeSwitch<Type, std::optional<DenseMap<Attribute, Type>>>(
288 .Case<StructType, UnpackedStructType>([](
auto &type) {
291 .Default([](
auto) {
return std::nullopt; });
294 Type RefType::getTypeAtIndex(Attribute index) {
295 return TypeSwitch<Type, Type>(getNestedType())
296 .Case<StructType, UnpackedStructType>([&index](
auto &type) {
299 .Default([](
auto) {
return Type(); });
302 std::optional<uint32_t> RefType::getFieldIndex(StringAttr nameField) {
303 return TypeSwitch<Type, std::optional<uint32_t>>(getNestedType())
304 .Case<StructType, UnpackedStructType>([&nameField](
auto &type) {
307 .Default([](
auto) {
return std::nullopt; });
314 #define GET_TYPEDEF_CLASSES
315 #include "circt/Dialect/Moore/MooreTypes.cpp.inc"
317 void MooreDialect::registerTypes() {
319 #define GET_TYPEDEF_LIST
320 #include "circt/Dialect/Moore/MooreTypes.cpp.inc"
330 llvm::SMLoc loc = parser.getCurrentLocation();
334 if (
auto result = generatedTypeParser(parser, &mnemonic, type);
336 return result.value();
339 if (mnemonic.size() > 1 && (mnemonic[0] ==
'i' || mnemonic[0] ==
'l') &&
342 auto spelling = mnemonic.drop_front(1);
344 if (spelling.getAsInteger(10,
width))
345 return parser.emitError(loc,
"integer width invalid");
350 parser.emitError(loc) <<
"unknown type `" << mnemonic
351 <<
"` in dialect `moore`";
358 if (
auto intType = dyn_cast<IntType>(type)) {
360 printer << intType.getWidth();
365 if (succeeded(generatedTypePrinter(type, printer)))
367 assert(
false &&
"no printer for unknown `moore` dialect type");
379 void MooreDialect::printType(Type type, DialectAsmPrinter &printer)
const {
assert(baseType &&"element must be base type")
static ParseResult parseType(Type &result, StringRef name, AsmParser &parser)
Parse a type defined by this dialect.
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 std::optional< uint32_t > getFieldAllIndex(ArrayRef< StructLikeMember > members, StringAttr nameField)
static std::optional< DenseMap< Attribute, Type > > getAllSubelementIndexMap(ArrayRef< StructLikeMember > members)
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)
A packed 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.
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
static LogicalResult verify(Value clock, bool eventExists, mlir::Location loc)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
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.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.