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() {
44 #define GET_TYPEDEF_LIST
45 #include "circt/Dialect/Moore/MooreTypes.cpp.inc"
60 llvm_unreachable(
"all signs should be handled");
64 return StringSwitch<std::optional<Sign>>(keyword)
77 std::optional<Sign> maybeSign;
102 return TypeSwitch<UnpackedType, UnpackedType>(*
this)
104 [&](
auto type) {
return type.resolved(); })
105 .Default([](
auto type) {
return type; });
109 return TypeSwitch<UnpackedType, UnpackedType>(*
this)
111 [&](
auto type) {
return type.fullyResolved(); })
112 .Default([](
auto type) {
return type; });
116 return TypeSwitch<UnpackedType, Domain>(*
this)
117 .Case<
PackedType>([](
auto type) {
return type.getDomain(); })
118 .Case<UnpackedIndirectType, UnpackedDim>(
119 [&](
auto type) {
return type.getInner().getDomain(); })
120 .Case<UnpackedStructType>(
121 [](
auto type) {
return type.getStruct().domain; })
126 return TypeSwitch<UnpackedType, Sign>(*
this)
127 .Case<
PackedType>([](
auto type) {
return type.getSign(); })
128 .Case<UnpackedIndirectType, UnpackedDim>(
129 [&](
auto type) {
return type.getInner().getSign(); })
134 return TypeSwitch<UnpackedType, std::optional<unsigned>>(*this)
136 .Case<UnpackedUnsizedDim>([](
auto) {
return std::nullopt; })
137 .Case<UnpackedArrayDim>([](
auto type) -> std::optional<unsigned> {
138 if (
auto size = type.getInner().getBitSize())
139 return (*size) * type.getSize();
142 .Case<UnpackedRangeDim>([](
auto type) -> std::optional<unsigned> {
143 if (
auto size = type.getInner().getBitSize())
144 return (*size) * type.getRange().size;
147 .Case<UnpackedIndirectType>(
148 [](
auto type) {
return type.getInner().getBitSize(); })
149 .Case<UnpackedStructType>(
150 [](
auto type) {
return type.getStruct().bitSize; })
151 .Default([](
auto) {
return std::nullopt; });
157 bool usedAtom = bitSize > 1;
163 return TypeSwitch<UnpackedType, SimpleBitVectorType>(
fullyResolved())
168 .Case<PackedRangeDim>([](
auto rangeType) {
171 llvm::dyn_cast<IntType>(rangeType.getInner().fullyResolved());
183 if (range.size == 0 || range.offset != 0 || range.dir !=
RangeDir::Down)
186 sbv.size = range.size;
203 auto bitSize = packed.getBitSize();
204 if (!bitSize || *bitSize == 0)
213 llvm::raw_ostream &os,
214 llvm::function_ref<
void(llvm::raw_ostream &os)> around)
const {
215 TypeSwitch<UnpackedType>(*
this)
216 .Case<
StringType>([&](
auto) { os <<
"string"; })
217 .Case<ChandleType>([&](
auto) { os <<
"chandle"; })
218 .Case<EventType>([&](
auto) { os <<
"event"; })
219 .Case<RealType>([&](
auto type) { os << type.getKeyword(); })
220 .Case<PackedType, UnpackedStructType>([&](
auto type) { type.format(os); })
221 .Case<UnpackedDim>([&](
auto type) { type.format(os, around); })
222 .Case<UnpackedNamedType>(
223 [&](
auto type) { os << type.getName().getValue(); })
224 .Case<UnpackedRefType>(
225 [&](
auto type) { os <<
"type(" << type.getInner() <<
")"; })
226 .Default([](
auto) { llvm_unreachable(
"all types should be handled"); });
233 if (!isa<UnpackedDim>() && around) {
244 return TypeSwitch<PackedType, PackedType>(*
this)
246 [&](
auto type) {
return type.resolved(); })
247 .Default([](
auto type) {
return type; });
251 return TypeSwitch<PackedType, PackedType>(*
this)
253 [&](
auto type) {
return type.fullyResolved(); })
254 .Default([](
auto type) {
return type; });
258 return TypeSwitch<PackedType, Domain>(*
this)
260 .Case<IntType>([&](
auto type) {
return type.getDomain(); })
261 .Case<PackedIndirectType, PackedDim>(
262 [&](
auto type) {
return type.getInner().getDomain(); })
263 .Case<EnumType>([](
auto type) {
return type.getBase().getDomain(); })
264 .Case<PackedStructType>(
265 [](
auto type) {
return type.getStruct().domain; });
269 return TypeSwitch<PackedType, Sign>(*
this)
271 .Case<IntType, PackedStructType>(
272 [&](
auto type) {
return type.getSign(); })
273 .Case<PackedIndirectType, PackedDim>(
274 [&](
auto type) {
return type.getInner().getSign(); })
275 .Case<EnumType>([](
auto type) {
return type.getBase().getSign(); });
279 return TypeSwitch<PackedType, std::optional<unsigned>>(*this)
280 .Case<
VoidType>([](
auto) {
return 0; })
281 .Case<IntType>([](
auto type) {
return type.getBitSize(); })
282 .Case<PackedUnsizedDim>([](
auto) {
return std::nullopt; })
283 .Case<PackedRangeDim>([](
auto type) -> std::optional<unsigned> {
284 if (
auto size = type.getInner().getBitSize())
285 return (*size) * type.getRange().size;
288 .Case<PackedIndirectType>(
289 [](
auto type) {
return type.getInner().getBitSize(); })
290 .Case<EnumType>([](
auto type) {
return type.getBase().getBitSize(); })
291 .Case<PackedStructType>(
292 [](
auto type) {
return type.getStruct().bitSize; });
296 TypeSwitch<PackedType>(*
this)
297 .Case<
VoidType>([&](
auto) { os <<
"void"; })
300 .Case<PackedNamedType>(
301 [&](
auto type) { os << type.getName().getValue(); })
302 .Case<PackedRefType>(
303 [&](
auto type) { os <<
"type(" << type.getInner() <<
")"; })
304 .Default([](
auto) { llvm_unreachable(
"all types should be handled"); });
333 : kind(static_cast<
Kind>((key >> 16) & 0xFF)),
334 sign(static_cast<
Sign>((key >> 8) & 0xFF)), explicitSign(key & 1) {}
336 return static_cast<unsigned>(kind) << 16 |
337 static_cast<unsigned>(sign) << 8 | explicitSign;
340 return pack(kind, sign, explicitSign) == key;
356 return StringSwitch<std::optional<Kind>>(keyword)
390 llvm_unreachable(
"all kinds should be handled");
407 llvm_unreachable(
"all kinds should be handled");
424 llvm_unreachable(
"all kinds should be handled");
446 llvm_unreachable(
"all kinds should be handled");
456 llvm_unreachable(
"all domains should be handled");
485 llvm_unreachable(
"all domains should be handled");
489 std::optional<Sign> sign) {
521 return kind ==
static_cast<Kind>(key);
535 return StringSwitch<std::optional<Kind>>(keyword)
551 llvm_unreachable(
"all kinds should be handled");
563 llvm_unreachable(
"all kinds should be handled");
567 return Base::get(context,
static_cast<unsigned>(kind));
581 using KeyTy = std::tuple<UnpackedType, StringAttr, LocationAttr>;
587 : inner(inner), name(name), loc(loc) {}
589 return std::get<0>(key) == inner && std::get<1>(key) == name &&
590 std::get<2>(key) == loc;
621 PackedType inner, StringAttr name, Location loc) {
622 return Base::get(inner.getContext(), inner, name, loc);
628 return Base::get(inner.getContext(), inner, name, loc);
635 return Base::get(inner.getContext(), inner, StringAttr{}, loc);
642 return Base::get(inner.getContext(), inner, StringAttr{}, loc);
664 LogicalResult
mutate(TypeStorageAllocator &allocator,
691 template <
class ConcreteDim,
typename... Args>
692 void finalize(ConcreteDim dim, Args... args)
const {
695 auto inner = dim.getInner();
696 auto newResolved = dim;
697 auto newFullyResolved = dim;
702 auto result = dim.mutate(newResolved, newFullyResolved);
704 assert(succeeded(result));
721 using KeyTy = std::pair<UnpackedType, Range>;
725 return key.first ==
inner && key.second ==
range;
740 return llvm::cast<PackedType>(
getImpl()->inner);
744 SmallVector<PackedDim> dims;
745 dims.push_back(*
this);
748 if (
auto dim = llvm::dyn_cast<PackedDim>(inner)) {
756 for (
auto dim : dims) {
762 TypeSwitch<PackedDim>(*
this)
764 [&](
auto dim) { os <<
"[" << dim.getRange() <<
"]"; })
765 .Case<PackedUnsizedDim>([&](
auto dim) { os <<
"[]"; })
766 .Default([&](
auto) { llvm_unreachable(
"unhandled dim type"); });
778 if (
auto dim = dyn_cast<PackedRangeDim>())
779 return dim.getRange();
784 return llvm::transformOptional(
getRange(), [](
auto r) {
return r.size; });
792 auto type =
Base::get(inner.getContext(), inner);
798 auto type =
Base::get(inner.getContext(), inner, range);
814 using KeyTy = std::pair<UnpackedType, unsigned>;
818 return key.first == inner && key.second == size;
829 using KeyTy = std::pair<UnpackedType, UnpackedType>;
833 return key.first == inner && key.second == indexType;
850 llvm::raw_ostream &os,
851 llvm::function_ref<
void(llvm::raw_ostream &)> around)
const {
852 SmallVector<UnpackedDim> dims;
853 dims.push_back(*
this);
856 if (
auto dim = llvm::dyn_cast<UnpackedDim>(inner)) {
869 for (
auto dim : dims) {
875 TypeSwitch<UnpackedDim>(*
this)
877 .Case<UnpackedArrayDim>(
878 [&](
auto dim) { os <<
"[" << dim.getSize() <<
"]"; })
879 .Case<UnpackedRangeDim>(
880 [&](
auto dim) { os <<
"[" << dim.getRange() <<
"]"; })
881 .Case<UnpackedAssocDim>([&](
auto dim) {
883 if (
auto indexType = dim.getIndexType())
884 indexType.format(os);
889 .Case<UnpackedQueueDim>([&](
auto dim) {
891 if (
auto bound = dim.getBound())
895 .Default([&](
auto) { llvm_unreachable(
"unhandled dim type"); });
909 auto type =
Base::get(inner.getContext(), inner);
915 auto type =
Base::get(inner.getContext(), inner, size);
923 auto type =
Base::get(inner.getContext(), inner, range);
932 auto type =
Base::get(inner.getContext(), inner, indexType);
938 return getImpl()->indexType;
942 std::optional<unsigned> bound) {
943 auto type =
Base::get(inner.getContext(), inner, bound.value_or(-1));
949 unsigned bound = getImpl()->size;
950 if (bound ==
static_cast<unsigned>(-1))
964 using KeyTy = std::tuple<StringAttr, Location, PackedType, char>;
967 : name(std::
get<0>(key)), loc(std::
get<1>(key)), base(std::
get<2>(key)),
968 explicitBase(std::
get<3>(key)) {}
970 return std::get<0>(key) == name && std::get<1>(key) == loc &&
971 std::get<2>(key) == base && std::get<3>(key) == explicitBase;
1006 os <<
" " <<
name.getValue();
1026 return "tagged_union";
1028 llvm_unreachable(
"all struct kinds should be handled");
1032 return StringSwitch<std::optional<StructKind>>(mnemonic)
1041 : kind(kind), members(members.begin(), members.end()), name(name),
1055 for (
const auto &member :
members) {
1056 if (
auto memberSize = member.type.getBitSize()) {
1066 std::optional<Sign> signing)
const {
1071 os <<
" " << *signing;
1075 os <<
" " <<
name.getValue();
1082 os <<
" " << member.type <<
" " << member.name.getValue() <<
";";
1094 std::tuple<unsigned, ArrayRef<StructMember>, StringAttr, Location>;
1097 : strukt(static_cast<
StructKind>((std::
get<0>(key) >> 16) & 0xFF),
1098 std::
get<1>(key), std::
get<2>(key), std::
get<3>(key)),
1099 sign(static_cast<
Sign>((std::
get<0>(key) >> 8) & 0xFF)),
1100 explicitSign((std::
get<0>(key) >> 0) & 1) {}
1102 return static_cast<unsigned>(kind) << 16 |
1103 static_cast<unsigned>(sign) << 8 | explicitSign;
1106 return std::get<0>(key) == pack(strukt.kind, sign, explicitSign) &&
1107 std::get<1>(key) == ArrayRef<StructMember>(strukt.members) &&
1108 std::get<2>(key) == strukt.name && std::get<3>(key) == strukt.loc;
1125 ArrayRef<StructMember> members,
1126 StringAttr name, Location loc,
1127 std::optional<Sign> sign) {
1128 assert(llvm::all_of(members,
1130 return llvm::isa<PackedType>(member.
type);
1132 "packed struct members must be packed");
1136 members,
name, loc);
1142 return getImpl()->explicitSign;
1148 ArrayRef<StructMember> members,
1149 StringAttr name, Location loc) {
1152 members,
name, loc);
1156 return getImpl()->strukt;
1164 enum { None, Unpacked, Packed } implied = None;
1165 bool allowUnpacked =
true;
1170 static void printMooreType(Type type, DialectAsmPrinter &printer,
1175 StringRef mnemonic,
Subset subset,
1176 llvm::SMLoc loc, Type &type) {
1177 auto *context = parser.getContext();
1185 parser.emitError(loc)
1186 <<
"unpacked type " << x <<
" where only packed types are allowed";
1193 [&](llvm::function_ref<
PackedType()> ifPacked,
1196 return yieldPacked(ifPacked());
1198 return yieldUnpacked(ifUnpacked());
1199 parser.emitError(loc)
1200 <<
"ambiguous packing; wrap `" << mnemonic
1201 <<
"` in `packed<...>` or `unpacked<...>` to disambiguate";
1206 if (mnemonic ==
"unpacked") {
1208 if (parser.parseLess() ||
1210 parser.parseGreater())
1212 return yieldUnpacked(inner);
1214 if (mnemonic ==
"packed") {
1216 if (parser.parseLess() ||
1218 parser.parseGreater())
1220 return yieldPacked(inner);
1224 if (mnemonic ==
"void")
1228 std::optional<Sign> sign;
1229 if (succeeded(parser.parseOptionalLess())) {
1230 StringRef signKeyword;
1231 if (parser.parseKeyword(&signKeyword) || parser.parseGreater())
1235 parser.emitError(parser.getCurrentLocation())
1236 <<
"expected keyword `unsigned` or `signed`";
1240 return yieldPacked(
IntType::get(context, *kind, sign));
1244 if (mnemonic ==
"string")
1246 if (mnemonic ==
"chandle")
1248 if (mnemonic ==
"event")
1254 if (mnemonic ==
"enum") {
1255 if (parser.parseLess())
1258 auto result = parser.parseOptionalAttribute(name);
1259 if (result.has_value())
1260 if (*result || parser.parseComma())
1264 result = parser.parseOptionalAttribute(loc);
1265 if (result.has_value()) {
1270 parser.parseComma() || parser.parseAttribute(loc))
1273 if (parser.parseGreater())
1286 if (mnemonic ==
"named") {
1290 if (parser.parseLess() || parser.parseAttribute(name) ||
1292 parser.parseComma() || parser.parseAttribute(loc) ||
1293 parser.parseGreater())
1295 return yieldImplied(
1301 if (mnemonic ==
"ref") {
1304 if (parser.parseLess() ||
parseMooreType(parser, subset, inner) ||
1305 parser.parseComma() || parser.parseAttribute(loc) ||
1306 parser.parseGreater())
1308 return yieldImplied(
1314 if (mnemonic ==
"unsized") {
1316 if (parser.parseLess() ||
parseMooreType(parser, subset, inner) ||
1317 parser.parseGreater())
1319 return yieldImplied(
1323 if (mnemonic ==
"range") {
1326 if (parser.parseLess() ||
parseMooreType(parser, subset, inner) ||
1327 parser.parseComma() || parser.parseInteger(left) ||
1328 parser.parseColon() || parser.parseInteger(right) ||
1329 parser.parseGreater())
1331 return yieldImplied(
1337 if (mnemonic ==
"array") {
1340 if (parser.parseLess() ||
parseMooreType(parser, subset, inner) ||
1341 parser.parseComma() || parser.parseInteger(size) ||
1342 parser.parseGreater())
1346 if (mnemonic ==
"assoc") {
1351 if (succeeded(parser.parseOptionalComma())) {
1355 if (parser.parseGreater())
1359 if (mnemonic ==
"queue") {
1361 std::optional<unsigned> size;
1364 if (succeeded(parser.parseOptionalComma())) {
1366 if (parser.parseInteger(tmpSize))
1370 if (parser.parseGreater())
1377 if (parser.parseLess())
1381 auto result = parser.parseOptionalAttribute(name);
1382 if (result.has_value())
1383 if (*result || parser.parseComma())
1386 std::optional<Sign> sign;
1388 if (succeeded(parser.parseOptionalKeyword(&keyword))) {
1391 parser.emitError(loc) <<
"expected keyword `unsigned` or `signed`";
1395 parser.emitError(loc) <<
"unpacked struct cannot have a sign";
1398 if (parser.parseComma())
1402 SmallVector<StructMember> members;
1404 parser.parseCommaSeparatedList(OpAsmParser::Delimiter::Braces, [&]() {
1405 if (parser.parseKeyword(&keyword))
1409 if (parser.parseColon() ||
parseMooreType(parser, subset, type) ||
1410 parser.parseAttribute(loc))
1420 if (parser.parseComma() || parser.parseAttribute(loc) ||
1421 parser.parseGreater())
1424 return yieldImplied(
1440 if (llvm::isa<PackedDim>(type) || llvm::isa<UnpackedDim>(type) ||
1441 llvm::isa<PackedIndirectType>(type) ||
1442 llvm::isa<UnpackedIndirectType>(type) ||
1443 llvm::isa<PackedStructType>(type) ||
1444 llvm::isa<UnpackedStructType>(type)) {
1447 if (needed != subset.
implied) {
1448 printer << (needed ==
Subset::Packed ?
"packed" :
"unpacked") <<
"<";
1455 return TypeSwitch<Type, LogicalResult>(type)
1461 .Case<StringType>([&](
auto) {
1462 printer <<
"string";
1465 .Case<ChandleType>([&](
auto) {
1466 printer <<
"chandle";
1469 .Case<EventType>([&](
auto) {
1475 .Case<IntType>([&](
auto type) {
1476 printer << type.getKeyword();
1477 auto sign = type.getSign();
1478 if (type.isSignExplicit())
1483 [&](
auto type) {
return printer << type.getKeyword(), success(); })
1486 .Case<EnumType>([&](
auto type) {
1489 printer << type.getName() <<
", ";
1490 if (type.isBaseExplicit()) {
1494 printer << type.getLoc() <<
">";
1499 .Case<PackedNamedType, UnpackedNamedType>([&](
auto type) {
1500 printer <<
"named<" << type.getName() <<
", ";
1502 printer <<
", " << type.getLoc() <<
">";
1505 .Case<PackedRefType, UnpackedRefType>([&](
auto type) {
1508 printer <<
", " << type.getLoc() <<
">";
1513 .Case<PackedUnsizedDim, UnpackedUnsizedDim>([&](
auto type) {
1514 printer <<
"unsized<";
1519 .Case<PackedRangeDim, UnpackedRangeDim>([&](
auto type) {
1520 printer <<
"range<";
1522 printer <<
", " << type.getRange() <<
">";
1525 .Case<UnpackedArrayDim>([&](
auto type) {
1526 printer <<
"array<";
1528 printer <<
", " << type.getSize() <<
">";
1531 .Case<UnpackedAssocDim>([&](
auto type) {
1532 printer <<
"assoc<";
1534 if (
auto indexType = type.getIndexType()) {
1541 .Case<UnpackedQueueDim>([&](
auto type) {
1542 printer <<
"queue<";
1544 if (
auto bound = type.getBound())
1545 printer <<
", " << *bound;
1551 .Case<PackedStructType, UnpackedStructType>([&](
auto type) {
1552 const auto &strukt = type.getStruct();
1555 printer << strukt.name <<
", ";
1556 auto packed = llvm::dyn_cast<PackedStructType>(type);
1557 if (packed && packed.isSignExplicit())
1558 printer << packed.getSign() <<
", ";
1560 llvm::interleaveComma(strukt.members, printer, [&](
const auto &member) {
1561 printer << member.name.getValue() <<
": ";
1562 printMooreType(member.type, printer, subset);
1563 printer <<
" " << member.loc;
1566 printer << strukt.loc <<
">";
1570 .Default([](
auto) {
return failure(); });
1576 llvm::SMLoc loc = parser.getCurrentLocation();
1578 if (parser.parseKeyword(&mnemonic))
1583 return result.value();
1585 parser.emitError(loc) <<
"unknown type `" << mnemonic
1586 <<
"` in dialect `moore`";
1595 assert(
false &&
"no printer for unknown `moore` dialect type");
1607 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.
static constexpr StringLiteral name
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 Kind getAtomForDomain(Domain domain)
Get the integer type that corresponds to a single bit of the given domain.
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.
static constexpr StringLiteral name
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 constexpr StringLiteral name
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.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
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)