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::DialectAsmParser;
22 using mlir::DialectAsmPrinter;
23 using mlir::LocationAttr;
24 using mlir::OptionalParseResult;
25 using mlir::StringSwitch;
26 using mlir::TypeStorage;
27 using mlir::TypeStorageAllocator;
33 #define GET_TYPEDEF_CLASSES
34 #include "circt/Dialect/Moore/MooreTypes.cpp.inc"
36 void MooreDialect::registerTypes() {
42 #define GET_TYPEDEF_LIST
43 #include "circt/Dialect/Moore/MooreTypes.cpp.inc"
58 llvm_unreachable(
"all signs should be handled");
62 return StringSwitch<std::optional<Sign>>(keyword)
75 std::optional<Sign> maybeSign;
100 return TypeSwitch<UnpackedType, UnpackedType>(*
this)
102 [&](
auto type) {
return type.resolved(); })
103 .Default([](
auto type) {
return type; });
107 return TypeSwitch<UnpackedType, UnpackedType>(*
this)
109 [&](
auto type) {
return type.fullyResolved(); })
110 .Default([](
auto type) {
return type; });
114 return TypeSwitch<UnpackedType, Domain>(*
this)
115 .Case<
PackedType>([](
auto type) {
return type.getDomain(); })
116 .Case<UnpackedIndirectType, UnpackedDim>(
117 [&](
auto type) {
return type.getInner().getDomain(); })
118 .Case<UnpackedStructType>(
119 [](
auto type) {
return type.getStruct().domain; })
124 return TypeSwitch<UnpackedType, Sign>(*
this)
125 .Case<
PackedType>([](
auto type) {
return type.getSign(); })
126 .Case<UnpackedIndirectType, UnpackedDim>(
127 [&](
auto type) {
return type.getInner().getSign(); })
132 return TypeSwitch<UnpackedType, std::optional<unsigned>>(*this)
134 .Case<UnpackedUnsizedDim>([](
auto) {
return std::nullopt; })
135 .Case<UnpackedArrayDim>([](
auto type) -> std::optional<unsigned> {
136 if (
auto size = type.getInner().getBitSize())
137 return (*size) * type.getSize();
140 .Case<UnpackedRangeDim>([](
auto type) -> std::optional<unsigned> {
141 if (
auto size = type.getInner().getBitSize())
142 return (*size) * type.getRange().size;
145 .Case<UnpackedIndirectType>(
146 [](
auto type) {
return type.getInner().getBitSize(); })
147 .Case<UnpackedStructType>(
148 [](
auto type) {
return type.getStruct().bitSize; })
149 .Default([](
auto) {
return std::nullopt; });
155 bool usedAtom = bitSize > 1;
161 return TypeSwitch<UnpackedType, SimpleBitVectorType>(
fullyResolved())
166 .Case<PackedRangeDim>([](
auto rangeType) {
169 rangeType.getInner().fullyResolved().template dyn_cast<IntType>();
181 if (range.size == 0 || range.offset != 0 || range.dir !=
RangeDir::Down)
184 sbv.size = range.size;
202 if (!bitSize || *bitSize == 0)
211 llvm::raw_ostream &os,
212 llvm::function_ref<
void(llvm::raw_ostream &os)> around)
const {
213 TypeSwitch<UnpackedType>(*
this)
214 .Case<
StringType>([&](
auto) { os <<
"string"; })
215 .Case<ChandleType>([&](
auto) { os <<
"chandle"; })
216 .Case<EventType>([&](
auto) { os <<
"event"; })
217 .Case<RealType>([&](
auto type) { os << type.getKeyword(); })
218 .Case<PackedType, UnpackedStructType>([&](
auto type) { type.format(os); })
219 .Case<UnpackedDim>([&](
auto type) { type.format(os, around); })
220 .Case<UnpackedNamedType>(
221 [&](
auto type) { os << type.getName().getValue(); })
222 .Case<UnpackedRefType>(
223 [&](
auto type) { os <<
"type(" << type.getInner() <<
")"; })
224 .Default([](
auto) { llvm_unreachable(
"all types should be handled"); });
231 if (!isa<UnpackedDim>() && around) {
242 return TypeSwitch<PackedType, PackedType>(*
this)
244 [&](
auto type) {
return type.resolved(); })
245 .Default([](
auto type) {
return type; });
249 return TypeSwitch<PackedType, PackedType>(*
this)
251 [&](
auto type) {
return type.fullyResolved(); })
252 .Default([](
auto type) {
return type; });
256 return TypeSwitch<PackedType, Domain>(*
this)
258 .Case<IntType>([&](
auto type) {
return type.getDomain(); })
259 .Case<PackedIndirectType, PackedDim>(
260 [&](
auto type) {
return type.getInner().getDomain(); })
261 .Case<EnumType>([](
auto type) {
return type.getBase().getDomain(); })
262 .Case<PackedStructType>(
263 [](
auto type) {
return type.getStruct().domain; });
267 return TypeSwitch<PackedType, Sign>(*
this)
269 .Case<IntType, PackedStructType>(
270 [&](
auto type) {
return type.getSign(); })
271 .Case<PackedIndirectType, PackedDim>(
272 [&](
auto type) {
return type.getInner().getSign(); })
273 .Case<EnumType>([](
auto type) {
return type.getBase().getSign(); });
277 return TypeSwitch<PackedType, std::optional<unsigned>>(*this)
278 .Case<
VoidType>([](
auto) {
return 0; })
279 .Case<IntType>([](
auto type) {
return type.getBitSize(); })
280 .Case<PackedUnsizedDim>([](
auto) {
return std::nullopt; })
281 .Case<PackedRangeDim>([](
auto type) -> std::optional<unsigned> {
282 if (
auto size = type.getInner().getBitSize())
283 return (*size) * type.getRange().size;
286 .Case<PackedIndirectType>(
287 [](
auto type) {
return type.getInner().getBitSize(); })
288 .Case<EnumType>([](
auto type) {
return type.getBase().getBitSize(); })
289 .Case<PackedStructType>(
290 [](
auto type) {
return type.getStruct().bitSize; });
294 TypeSwitch<PackedType>(*
this)
295 .Case<
VoidType>([&](
auto) { os <<
"void"; })
298 .Case<PackedNamedType>(
299 [&](
auto type) { os << type.getName().getValue(); })
300 .Case<PackedRefType>(
301 [&](
auto type) { os <<
"type(" << type.getInner() <<
")"; })
302 .Default([](
auto) { llvm_unreachable(
"all types should be handled"); });
331 : kind(static_cast<
Kind>((key >> 16) & 0xFF)),
332 sign(static_cast<
Sign>((key >> 8) & 0xFF)), explicitSign(key & 1) {}
334 return static_cast<unsigned>(kind) << 16 |
335 static_cast<unsigned>(sign) << 8 | explicitSign;
338 return pack(kind, sign, explicitSign) == key;
354 return StringSwitch<std::optional<Kind>>(keyword)
388 llvm_unreachable(
"all kinds should be handled");
405 llvm_unreachable(
"all kinds should be handled");
422 llvm_unreachable(
"all kinds should be handled");
444 llvm_unreachable(
"all kinds should be handled");
475 llvm_unreachable(
"all domains should be handled");
479 std::optional<Sign> sign) {
511 return kind ==
static_cast<Kind>(key);
525 return StringSwitch<std::optional<Kind>>(keyword)
541 llvm_unreachable(
"all kinds should be handled");
553 llvm_unreachable(
"all kinds should be handled");
557 return Base::get(context,
static_cast<unsigned>(kind));
571 using KeyTy = std::tuple<UnpackedType, StringAttr, LocationAttr>;
577 : inner(inner), name(name), loc(loc) {}
579 return std::get<0>(key) == inner && std::get<1>(key) == name &&
580 std::get<2>(key) == loc;
611 PackedType inner, StringAttr name, Location loc) {
612 return Base::get(inner.getContext(), inner, name, loc);
618 return Base::get(inner.getContext(), inner, name, loc);
625 return Base::get(inner.getContext(), inner, StringAttr{}, loc);
632 return Base::get(inner.getContext(), inner, StringAttr{}, loc);
654 LogicalResult
mutate(TypeStorageAllocator &allocator,
681 template <
class ConcreteDim,
typename... Args>
682 void finalize(ConcreteDim dim, Args... args)
const {
685 auto inner = dim.getInner();
686 auto newResolved = dim;
687 auto newFullyResolved = dim;
692 auto result = dim.mutate(newResolved, newFullyResolved);
694 assert(succeeded(result));
711 using KeyTy = std::pair<UnpackedType, Range>;
715 return key.first ==
inner && key.second ==
range;
734 SmallVector<PackedDim> dims;
735 dims.push_back(*
this);
738 if (
auto dim = inner.dyn_cast<
PackedDim>()) {
746 for (
auto dim : dims) {
752 TypeSwitch<PackedDim>(*
this)
754 [&](
auto dim) { os <<
"[" << dim.getRange() <<
"]"; })
755 .Case<PackedUnsizedDim>([&](
auto dim) { os <<
"[]"; })
756 .Default([&](
auto) { llvm_unreachable(
"unhandled dim type"); });
768 if (
auto dim = dyn_cast<PackedRangeDim>())
769 return dim.getRange();
774 return llvm::transformOptional(
getRange(), [](
auto r) {
return r.size; });
782 auto type =
Base::get(inner.getContext(), inner);
788 auto type =
Base::get(inner.getContext(), inner, range);
804 using KeyTy = std::pair<UnpackedType, unsigned>;
808 return key.first == inner && key.second == size;
819 using KeyTy = std::pair<UnpackedType, UnpackedType>;
823 return key.first == inner && key.second == indexType;
840 llvm::raw_ostream &os,
841 llvm::function_ref<
void(llvm::raw_ostream &)> around)
const {
842 SmallVector<UnpackedDim> dims;
843 dims.push_back(*
this);
859 for (
auto dim : dims) {
865 TypeSwitch<UnpackedDim>(*
this)
867 .Case<UnpackedArrayDim>(
868 [&](
auto dim) { os <<
"[" << dim.getSize() <<
"]"; })
869 .Case<UnpackedRangeDim>(
870 [&](
auto dim) { os <<
"[" << dim.getRange() <<
"]"; })
871 .Case<UnpackedAssocDim>([&](
auto dim) {
873 if (
auto indexType = dim.getIndexType())
874 indexType.format(os);
879 .Case<UnpackedQueueDim>([&](
auto dim) {
881 if (
auto bound = dim.getBound())
885 .Default([&](
auto) { llvm_unreachable(
"unhandled dim type"); });
899 auto type =
Base::get(inner.getContext(), inner);
905 auto type =
Base::get(inner.getContext(), inner, size);
913 auto type =
Base::get(inner.getContext(), inner, range);
922 auto type =
Base::get(inner.getContext(), inner, indexType);
928 return getImpl()->indexType;
932 std::optional<unsigned> bound) {
933 auto type =
Base::get(inner.getContext(), inner, bound.value_or(-1));
939 unsigned bound = getImpl()->size;
940 if (bound ==
static_cast<unsigned>(-1))
954 using KeyTy = std::tuple<StringAttr, Location, PackedType, char>;
957 : name(std::
get<0>(key)), loc(std::
get<1>(key)), base(std::
get<2>(key)),
958 explicitBase(std::
get<3>(key)) {}
960 return std::get<0>(key) == name && std::get<1>(key) == loc &&
961 std::get<2>(key) == base && std::get<3>(key) == explicitBase;
979 return Base::get(loc.getContext(), name, loc,
996 os <<
" " << name.getValue();
1016 return "tagged_union";
1018 llvm_unreachable(
"all struct kinds should be handled");
1022 return StringSwitch<std::optional<StructKind>>(mnemonic)
1031 : kind(kind), members(members.begin(), members.end()), name(name),
1045 for (
const auto &member :
members) {
1046 if (
auto memberSize = member.type.getBitSize()) {
1056 std::optional<Sign> signing)
const {
1061 os <<
" " << *signing;
1065 os <<
" " <<
name.getValue();
1072 os <<
" " << member.type <<
" " << member.name.getValue() <<
";";
1084 std::tuple<unsigned, ArrayRef<StructMember>, StringAttr, Location>;
1087 : strukt(static_cast<
StructKind>((std::
get<0>(key) >> 16) & 0xFF),
1088 std::
get<1>(key), std::
get<2>(key), std::
get<3>(key)),
1089 sign(static_cast<
Sign>((std::
get<0>(key) >> 8) & 0xFF)),
1090 explicitSign((std::
get<0>(key) >> 0) & 1) {}
1092 return static_cast<unsigned>(kind) << 16 |
1093 static_cast<unsigned>(sign) << 8 | explicitSign;
1096 return std::get<0>(key) == pack(strukt.kind, sign, explicitSign) &&
1097 std::get<1>(key) == ArrayRef<StructMember>(strukt.members) &&
1098 std::get<2>(key) == strukt.name && std::get<3>(key) == strukt.loc;
1115 ArrayRef<StructMember> members,
1116 StringAttr name, Location loc,
1117 std::optional<Sign> sign) {
1118 assert(llvm::all_of(members,
1122 "packed struct members must be packed");
1126 members, name, loc);
1132 return getImpl()->explicitSign;
1138 ArrayRef<StructMember> members,
1139 StringAttr name, Location loc) {
1142 members, name, loc);
1146 return getImpl()->strukt;
1154 enum { None, Unpacked, Packed } implied = None;
1155 bool allowUnpacked =
true;
1160 static void printMooreType(Type type, DialectAsmPrinter &printer,
1165 StringRef mnemonic,
Subset subset,
1166 llvm::SMLoc loc, Type &type) {
1167 auto *context = parser.getContext();
1175 parser.emitError(loc)
1176 <<
"unpacked type " << x <<
" where only packed types are allowed";
1183 [&](llvm::function_ref<
PackedType()> ifPacked,
1186 return yieldPacked(ifPacked());
1188 return yieldUnpacked(ifUnpacked());
1189 parser.emitError(loc)
1190 <<
"ambiguous packing; wrap `" << mnemonic
1191 <<
"` in `packed<...>` or `unpacked<...>` to disambiguate";
1196 if (mnemonic ==
"unpacked") {
1198 if (parser.parseLess() ||
1200 parser.parseGreater())
1202 return yieldUnpacked(inner);
1204 if (mnemonic ==
"packed") {
1206 if (parser.parseLess() ||
1208 parser.parseGreater())
1210 return yieldPacked(inner);
1214 if (mnemonic ==
"void")
1218 std::optional<Sign> sign;
1219 if (succeeded(parser.parseOptionalLess())) {
1220 StringRef signKeyword;
1221 if (parser.parseKeyword(&signKeyword) || parser.parseGreater())
1225 parser.emitError(parser.getCurrentLocation())
1226 <<
"expected keyword `unsigned` or `signed`";
1230 return yieldPacked(
IntType::get(context, *kind, sign));
1234 if (mnemonic ==
"string")
1236 if (mnemonic ==
"chandle")
1238 if (mnemonic ==
"event")
1244 if (mnemonic ==
"enum") {
1245 if (parser.parseLess())
1248 auto result = parser.parseOptionalAttribute(name);
1249 if (result.has_value())
1250 if (*result || parser.parseComma())
1254 result = parser.parseOptionalAttribute(loc);
1255 if (result.has_value()) {
1260 parser.parseComma() || parser.parseAttribute(loc))
1263 if (parser.parseGreater())
1276 if (mnemonic ==
"named") {
1280 if (parser.parseLess() || parser.parseAttribute(name) ||
1282 parser.parseComma() || parser.parseAttribute(loc) ||
1283 parser.parseGreater())
1285 return yieldImplied(
1291 if (mnemonic ==
"ref") {
1294 if (parser.parseLess() ||
parseMooreType(parser, subset, inner) ||
1295 parser.parseComma() || parser.parseAttribute(loc) ||
1296 parser.parseGreater())
1298 return yieldImplied(
1304 if (mnemonic ==
"unsized") {
1306 if (parser.parseLess() ||
parseMooreType(parser, subset, inner) ||
1307 parser.parseGreater())
1309 return yieldImplied(
1313 if (mnemonic ==
"range") {
1316 if (parser.parseLess() ||
parseMooreType(parser, subset, inner) ||
1317 parser.parseComma() || parser.parseInteger(left) ||
1318 parser.parseColon() || parser.parseInteger(right) ||
1319 parser.parseGreater())
1321 return yieldImplied(
1327 if (mnemonic ==
"array") {
1330 if (parser.parseLess() ||
parseMooreType(parser, subset, inner) ||
1331 parser.parseComma() || parser.parseInteger(size) ||
1332 parser.parseGreater())
1336 if (mnemonic ==
"assoc") {
1341 if (succeeded(parser.parseOptionalComma())) {
1345 if (parser.parseGreater())
1349 if (mnemonic ==
"queue") {
1351 std::optional<unsigned> size;
1354 if (succeeded(parser.parseOptionalComma())) {
1356 if (parser.parseInteger(tmpSize))
1360 if (parser.parseGreater())
1367 if (parser.parseLess())
1371 auto result = parser.parseOptionalAttribute(name);
1372 if (result.has_value())
1373 if (*result || parser.parseComma())
1376 std::optional<Sign> sign;
1378 if (succeeded(parser.parseOptionalKeyword(&keyword))) {
1381 parser.emitError(loc) <<
"expected keyword `unsigned` or `signed`";
1385 parser.emitError(loc) <<
"unpacked struct cannot have a sign";
1388 if (parser.parseComma())
1392 SmallVector<StructMember> members;
1394 parser.parseCommaSeparatedList(OpAsmParser::Delimiter::Braces, [&]() {
1395 if (parser.parseKeyword(&keyword))
1399 if (parser.parseColon() ||
parseMooreType(parser, subset, type) ||
1400 parser.parseAttribute(loc))
1410 if (parser.parseComma() || parser.parseAttribute(loc) ||
1411 parser.parseGreater())
1414 return yieldImplied(
1434 if (needed != subset.
implied) {
1435 printer << (needed ==
Subset::Packed ?
"packed" :
"unpacked") <<
"<";
1442 return TypeSwitch<Type, LogicalResult>(type)
1448 .Case<StringType>([&](
auto) {
1449 printer <<
"string";
1452 .Case<ChandleType>([&](
auto) {
1453 printer <<
"chandle";
1456 .Case<EventType>([&](
auto) {
1462 .Case<IntType>([&](
auto type) {
1463 printer << type.getKeyword();
1464 auto sign = type.getSign();
1465 if (type.isSignExplicit())
1470 [&](
auto type) {
return printer << type.getKeyword(), success(); })
1473 .Case<EnumType>([&](
auto type) {
1476 printer << type.getName() <<
", ";
1477 if (type.isBaseExplicit()) {
1481 printer << type.getLoc() <<
">";
1486 .Case<PackedNamedType, UnpackedNamedType>([&](
auto type) {
1487 printer <<
"named<" << type.getName() <<
", ";
1489 printer <<
", " << type.getLoc() <<
">";
1492 .Case<PackedRefType, UnpackedRefType>([&](
auto type) {
1495 printer <<
", " << type.getLoc() <<
">";
1500 .Case<PackedUnsizedDim, UnpackedUnsizedDim>([&](
auto type) {
1501 printer <<
"unsized<";
1506 .Case<PackedRangeDim, UnpackedRangeDim>([&](
auto type) {
1507 printer <<
"range<";
1509 printer <<
", " << type.getRange() <<
">";
1512 .Case<UnpackedArrayDim>([&](
auto type) {
1513 printer <<
"array<";
1515 printer <<
", " << type.getSize() <<
">";
1518 .Case<UnpackedAssocDim>([&](
auto type) {
1519 printer <<
"assoc<";
1521 if (
auto indexType = type.getIndexType()) {
1528 .Case<UnpackedQueueDim>([&](
auto type) {
1529 printer <<
"queue<";
1531 if (
auto bound = type.getBound())
1532 printer <<
", " << *bound;
1538 .Case<PackedStructType, UnpackedStructType>([&](
auto type) {
1539 const auto &strukt = type.getStruct();
1542 printer << strukt.name <<
", ";
1543 auto packed = type.template dyn_cast<PackedStructType>();
1544 if (packed && packed.isSignExplicit())
1545 printer << packed.getSign() <<
", ";
1547 llvm::interleaveComma(strukt.members, printer, [&](
const auto &member) {
1548 printer << member.name.getValue() <<
": ";
1549 printMooreType(member.type, printer, subset);
1550 printer <<
" " << member.loc;
1553 printer << strukt.loc <<
">";
1557 .Default([](
auto) {
return failure(); });
1563 llvm::SMLoc loc = parser.getCurrentLocation();
1565 OptionalParseResult result = generatedTypeParser(parser, &mnemonic, type);
1566 if (result.has_value())
1567 return result.value();
1570 if (result.has_value())
1571 return result.value();
1573 parser.emitError(loc) <<
"unknown type `" << mnemonic
1574 <<
"` in dialect `moore`";
1581 if (succeeded(generatedTypePrinter(type, printer)))
1585 assert(
false &&
"no printer for unknown `moore` dialect type");
1597 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 void printMooreType(Type type, DialectAsmPrinter &printer, Subset subset)
Print a type registered with this dialect.
static LogicalResult customTypePrinter(Type type, DialectAsmPrinter &printer, Subset subset)
Print a type with custom syntax.
static SimpleBitVectorType getSimpleBitVectorFromIntType(IntType type)
Map an IntType to the corresponding SBVT. Never returns a null type.
static ParseResult parseMooreType(DialectAsmParser &parser, Subset subset, Type &type)
Parse a type registered with this dialect.
static OptionalParseResult customTypeParser(DialectAsmParser &parser, StringRef mnemonic, Subset subset, llvm::SMLoc loc, Type &type)
Parse a type with custom syntax.
static ChandleType get(MLIRContext *context)
StringAttr getName() const
Get the name of the surrounding typedef, if this enum is embedded in a typedef.
PackedType getBase() const
Get the base type of the enumeration.
static EnumType get(StringAttr name, Location loc, PackedType base={})
void format(llvm::raw_ostream &os) const
Format this enum in SystemVerilog syntax.
Location getLoc() const
Get the location in the source text where the enum was declared.
bool isBaseExplicit() const
Returns whether the base type was explicitly specified by the user.
static EventType get(MLIRContext *context)
An integer vector or atom type.
Sign getDefaultSign() const
Get the default sign for this type.
Sign getSign() const
Get the sign of this type.
Domain getDomain() const
Get the value domain for this type.
static std::optional< Kind > getKindFromDomainAndSize(Domain domain, unsigned size)
Get the integer type that corresponds to a domain and bit size.
Kind getKind() const
Get the concrete integer vector or atom type.
static IntType getInt(MLIRContext *context)
Create a int type.
bool isSignExplicit() const
Whether the sign of the type was specified explicitly.
static IntType get(MLIRContext *context, Kind kind, std::optional< Sign > sign={})
static unsigned getBitSize(Kind kind)
Get the size of one of the integer types.
unsigned getBitSize() const
Get the size of this type.
static std::optional< Kind > getKindFromKeyword(StringRef keyword)
Get the integer type that corresponds to a keyword (like bit).
StringRef getKeyword() const
Get the keyword (like bit) for this type.
void format(llvm::raw_ostream &os) const
Format this type in SystemVerilog syntax.
static Domain getDomain(Kind kind)
Get the value domain for one of the integer types.
static ConcreteTy get(InnerType inner, StringAttr name, Location loc)
std::optional< Range > getRange() const
Get the dimension's range, or None if it is unsized.
void formatDim(llvm::raw_ostream &os) const
Format just the dimension part, [...].
const detail::DimStorage * getImpl() const
PackedType resolved() const
Resolve one level of name or type reference indirection.
void format(llvm::raw_ostream &os) const
Format this type in SystemVerilog syntax.
std::optional< unsigned > getSize() const
Get the dimension's size, or None if it is unsized.
PackedType fullyResolved() const
Resolve all name or type reference indirections.
A packed type indirection. See IndirectTypeBase for details.
A packed named type. See NamedTypeBase for details.
A packed range dimension, like [a:b].
Range getRange() const
Get the range of this dimension.
static PackedRangeDim get(PackedType inner, Range range)
A packed named type. See NamedTypeBase for details.
const Struct & getStruct() const
Get the struct definition.
static PackedStructType get(StructKind kind, ArrayRef< StructMember > members, StringAttr name, Location loc, std::optional< Sign > sign={})
Sign getSign() const
Get the sign of this struct.
bool isSignExplicit() const
Returns whether the sign was explicitly mentioned by the user.
A packed SystemVerilog type.
Sign getSign() const
Get the sign for this type.
PackedType resolved() const
Resolve one level of name or type reference indirection.
std::optional< unsigned > getBitSize() const
Get the size of this type in bits.
Domain getDomain() const
Get the value domain of this type.
void format(llvm::raw_ostream &os) const
Format this type in SystemVerilog syntax into an output stream.
PackedType fullyResolved() const
Resolve all name or type reference indirections.
A packed unsized dimension, like [].
static PackedUnsizedDim get(PackedType inner)
StringRef getKeyword() const
Get the keyword (like bit) for this type.
static std::optional< Kind > getKindFromKeyword(StringRef keyword)
Get the integer type that corresponds to a keyword (like bit).
static RealType get(MLIRContext *context, Kind kind)
unsigned getBitSize() const
Get the size of this type.
Kind getKind() const
Get the concrete integer vector or atom type.
static PackedRefType get(InnerType inner, Location loc)
static StringType get(MLIRContext *context)
An unpacked array dimension, like [a].
static UnpackedArrayDim get(UnpackedType inner, unsigned size)
unsigned getSize() const
Get the size of the array, i.e. the a in [a].
An unpacked associative dimension, like [T] or [*].
static UnpackedAssocDim get(UnpackedType inner, UnpackedType indexType={})
UnpackedType getIndexType() const
Get the index type of the associative dimension.
UnpackedType resolved() const
Resolve one level of name or type reference indirection.
void format(llvm::raw_ostream &os, llvm::function_ref< void(llvm::raw_ostream &)> around={}) const
Format this type in SystemVerilog syntax.
const detail::DimStorage * getImpl() const
UnpackedType fullyResolved() const
Resolve all name or type reference indirections.
void formatDim(llvm::raw_ostream &os) const
Format just the dimension part, [...].
UnpackedType getInner() const
Get the element type of the dimension. This is the x in x[a:b].
An unpacked type indirection. See IndirectTypeBase for details.
An unpacked named type. See NamedTypeBase for details.
An unpacked queue dimension with optional bound, like [$] or [$:a].
static UnpackedQueueDim get(UnpackedType inner, std::optional< unsigned > bound={})
std::optional< unsigned > getBound() const
Get the bound of the queue, i.e.
An unpacked range dimension, like [a:b].
Range getRange() const
Get the range of this dimension.
static UnpackedRangeDim get(UnpackedType inner, Range range)
An unpacked named type. See NamedTypeBase for details.
const Struct & getStruct() const
Get the struct definition.
static UnpackedStructType get(StructKind kind, ArrayRef< StructMember > members, StringAttr name, Location loc)
An unpacked SystemVerilog type.
UnpackedType resolved() const
Resolve one level of name or type reference indirection.
SimpleBitVectorType getSimpleBitVectorOrNull() const
Get this type as a simple bit vector, if it is one.
SimpleBitVectorType castToSimpleBitVectorOrNull() const
Cast this type to a simple bit vector.
UnpackedType fullyResolved() const
Resolve all name or type reference indirections.
std::optional< unsigned > getBitSize() const
Get the size of this type in bits.
Domain getDomain() const
Get the value domain of this type.
Sign getSign() const
Get the sign for this type.
void format(llvm::raw_ostream &os, llvm::function_ref< void(llvm::raw_ostream &os)> around={}) const
Format this type in SystemVerilog syntax into an output stream.
An unpacked unsized dimension, like [].
static UnpackedUnsizedDim get(UnpackedType inner)
static VoidType get(MLIRContext *context)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
mlir::Type innerType(mlir::Type type)
UnpackedType getIndirectTypeInner(const TypeStorage *impl)
StringAttr getIndirectTypeName(const TypeStorage *impl)
Location getIndirectTypeLoc(const TypeStorage *impl)
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.
Sign
Whether a type is signed or unsigned.
@ Unsigned
An unsigned type.
StringRef getKeywordFromSign(const Sign &sign)
Map a Sign to the corresponding keyword.
StringRef getMnemonicFromStructKind(StructKind kind)
Map a StructKind to the corresponding mnemonic.
StructKind
Whether a struct is a struct, union, or union tagged.
@ TaggedUnion
A union tagged.
std::optional< StructKind > getStructKindFromMnemonic(StringRef mnemonic)
Map a mnemonic to the corresponding StructKind.
std::optional< Sign > getSignFromKeyword(StringRef keyword)
Map the keywords unsigned and signed to the corresponding Sign.
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
The [a:b] part in a vector/array type such as logic [a:b].
A simple bit vector type.
unsigned size
The size of the vector.
bool explicitSize
Whether the single-bit vector had an explicit range in the source text.
bool usedAtom
Whether the type used an integer atom like int in the source text.
bool explicitSign
Whether the sign was explicit in the source text.
PackedType getType(MLIRContext *context) const
Convert this SBVT to an actual type.
Range getRange() const
Get the range of the type.
Domain domain
The domain, which dictates whether this is a bit or logic vector.
UnpackedType type
The type of this member.
std::optional< unsigned > bitSize
The size of this struct in bits.
StructKind kind
Whether this is a struct, union, or union tagged.
StringAttr name
The name of the surrounding typedef, if this struct is embedded in a typedef.
void format(llvm::raw_ostream &os, bool packed=false, std::optional< Sign > signing={}) const
Format this struct in SystemVerilog syntax.
Domain domain
The value domain of this struct.
SmallVector< StructMember, 4 > members
The list of members.
Struct(StructKind kind, ArrayRef< StructMember > members, StringAttr name, Location loc)
Create a new struct.
AssocDimStorage(KeyTy key)
static AssocDimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
bool operator==(const KeyTy &key) const
static DimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
UnpackedType fullyResolved
bool operator==(const KeyTy &key) const
void finalize(ConcreteDim dim, Args... args) const
Each dimension type calls this function from its get method.
LogicalResult mutate(TypeStorageAllocator &allocator, UnpackedType newResolved, UnpackedType newFullyResolved)
EnumTypeStorage(KeyTy key)
bool operator==(const KeyTy &key) const
std::tuple< StringAttr, Location, PackedType, char > KeyTy
static EnumTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
bool operator==(const KeyTy &key) const
IndirectTypeStorage(UnpackedType inner, StringAttr name, LocationAttr loc)
std::tuple< UnpackedType, StringAttr, LocationAttr > KeyTy
static IndirectTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
IndirectTypeStorage(KeyTy key)
IntTypeStorage(KeyTy key)
static IntTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
static KeyTy pack(Kind kind, Sign sign, bool explicitSign)
bool operator==(const KeyTy &key) const
bool operator==(const KeyTy &key) const
static RangeDimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
RangeDimStorage(KeyTy key)
bool operator==(const KeyTy &key) const
static RealTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
RealTypeStorage(KeyTy key)
SizedDimStorage(KeyTy key)
bool operator==(const KeyTy &key) const
static SizedDimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
StructTypeStorage(KeyTy key)
static StructTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
std::tuple< unsigned, ArrayRef< StructMember >, StringAttr, Location > KeyTy
bool operator==(const KeyTy &key) const
static unsigned pack(StructKind kind, Sign sign, bool explicitSign)
UnsizedDimStorage(KeyTy key)
static UnsizedDimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)