CIRCT  19.0.0git
MooreTypes.cpp
Go to the documentation of this file.
1 //===- MooreTypes.cpp - Implement the Moore types -------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implement the Moore dialect type system.
10 //
11 //===----------------------------------------------------------------------===//
12 
15 #include "mlir/IR/Builders.h"
16 #include "mlir/IR/DialectImplementation.h"
17 #include "llvm/ADT/TypeSwitch.h"
18 
19 using namespace circt;
20 using namespace circt::moore;
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;
28 
29 //===----------------------------------------------------------------------===//
30 // Generated logic
31 //===----------------------------------------------------------------------===//
32 
33 #define GET_TYPEDEF_CLASSES
34 #include "circt/Dialect/Moore/MooreTypes.cpp.inc"
35 
36 void MooreDialect::registerTypes() {
40 
41  addTypes<
42 #define GET_TYPEDEF_LIST
43 #include "circt/Dialect/Moore/MooreTypes.cpp.inc"
44  >();
45 }
46 
47 //===----------------------------------------------------------------------===//
48 // Utilities
49 //===----------------------------------------------------------------------===//
50 
51 StringRef moore::getKeywordFromSign(const Sign &sign) {
52  switch (sign) {
53  case Sign::Unsigned:
54  return "unsigned";
55  case Sign::Signed:
56  return "signed";
57  }
58  llvm_unreachable("all signs should be handled");
59 }
60 
61 //===----------------------------------------------------------------------===//
62 // Unpacked Type
63 //===----------------------------------------------------------------------===//
64 
66  return TypeSwitch<UnpackedType, Domain>(*this)
67  .Case<PackedType>([](auto type) { return type.getDomain(); })
68  .Case<UnpackedDim>([&](auto type) { return type.getInner().getDomain(); })
69  .Case<UnpackedStructType>(
70  [](auto type) { return type.getStruct().domain; })
71  .Default([](auto) { return Domain::TwoValued; });
72 }
73 
74 std::optional<unsigned> UnpackedType::getBitSize() const {
75  return TypeSwitch<UnpackedType, std::optional<unsigned>>(*this)
76  .Case<PackedType>([](auto type) { return type.getBitSize(); })
77  .Case<RealType>([](auto type) { return 64; })
78  .Case<UnpackedUnsizedDim>([](auto) { return std::nullopt; })
79  .Case<UnpackedArrayDim>([](auto type) -> std::optional<unsigned> {
80  if (auto size = type.getInner().getBitSize())
81  return (*size) * type.getSize();
82  return {};
83  })
84  .Case<UnpackedRangeDim>([](auto type) -> std::optional<unsigned> {
85  if (auto size = type.getInner().getBitSize())
86  return (*size) * type.getRange().size;
87  return {};
88  })
89  .Case<UnpackedStructType>(
90  [](auto type) { return type.getStruct().bitSize; })
91  .Default([](auto) { return std::nullopt; });
92 }
93 
94 //===----------------------------------------------------------------------===//
95 // Packed Type
96 //===----------------------------------------------------------------------===//
97 
99  return TypeSwitch<PackedType, Domain>(*this)
100  .Case<VoidType>([](auto) { return Domain::TwoValued; })
101  .Case<IntType>([&](auto type) { return type.getDomain(); })
102  .Case<PackedDim>([&](auto type) { return type.getInner().getDomain(); })
103  .Case<PackedStructType>(
104  [](auto type) { return type.getStruct().domain; });
105 }
106 
107 std::optional<unsigned> PackedType::getBitSize() const {
108  return TypeSwitch<PackedType, std::optional<unsigned>>(*this)
109  .Case<VoidType>([](auto) { return 0; })
110  .Case<IntType>([](auto type) { return type.getWidth(); })
111  .Case<PackedUnsizedDim>([](auto) { return std::nullopt; })
112  .Case<PackedRangeDim>([](auto type) -> std::optional<unsigned> {
113  if (auto size = type.getInner().getBitSize())
114  return (*size) * type.getRange().size;
115  return {};
116  })
117  .Case<PackedStructType>(
118  [](auto type) { return type.getStruct().bitSize; });
119 }
120 
121 //===----------------------------------------------------------------------===//
122 // Packed Dimensions
123 //===----------------------------------------------------------------------===//
124 
125 namespace circt {
126 namespace moore {
127 namespace detail {
128 
129 struct DimStorage : TypeStorage {
131 
132  DimStorage(KeyTy key) : inner(key) {}
133  bool operator==(const KeyTy &key) const { return key == inner; }
134  static DimStorage *construct(TypeStorageAllocator &allocator,
135  const KeyTy &key) {
136  return new (allocator.allocate<DimStorage>()) DimStorage(key);
137  }
138 
140 };
141 
144  static UnsizedDimStorage *construct(TypeStorageAllocator &allocator,
145  const KeyTy &key) {
146  return new (allocator.allocate<UnsizedDimStorage>()) UnsizedDimStorage(key);
147  }
148 };
149 
151  using KeyTy = std::pair<UnpackedType, Range>;
152 
153  RangeDimStorage(KeyTy key) : DimStorage(key.first), range(key.second) {}
154  bool operator==(const KeyTy &key) const {
155  return key.first == inner && key.second == range;
156  }
157  static RangeDimStorage *construct(TypeStorageAllocator &allocator,
158  const KeyTy &key) {
159  return new (allocator.allocate<RangeDimStorage>()) RangeDimStorage(key);
160  }
161 
163 };
164 
165 } // namespace detail
166 } // namespace moore
167 } // namespace circt
168 
170  return llvm::cast<PackedType>(getImpl()->inner);
171 }
172 
173 std::optional<Range> PackedDim::getRange() const {
174  if (auto dim = llvm::dyn_cast<PackedRangeDim>(*this))
175  return dim.getRange();
176  return {};
177 }
178 
179 std::optional<unsigned> PackedDim::getSize() const {
180  return llvm::transformOptional(getRange(), [](auto r) { return r.size; });
181 }
182 
184  return static_cast<detail::DimStorage *>(this->impl);
185 }
186 
188  return Base::get(inner.getContext(), inner);
189 }
190 
192  return Base::get(inner.getContext(), inner, range);
193 }
194 
195 Range PackedRangeDim::getRange() const { return getImpl()->range; }
196 
197 //===----------------------------------------------------------------------===//
198 // Unpacked Dimensions
199 //===----------------------------------------------------------------------===//
200 
201 namespace circt {
202 namespace moore {
203 namespace detail {
204 
206  using KeyTy = std::pair<UnpackedType, unsigned>;
207 
208  SizedDimStorage(KeyTy key) : DimStorage(key.first), size(key.second) {}
209  bool operator==(const KeyTy &key) const {
210  return key.first == inner && key.second == size;
211  }
212  static SizedDimStorage *construct(TypeStorageAllocator &allocator,
213  const KeyTy &key) {
214  return new (allocator.allocate<SizedDimStorage>()) SizedDimStorage(key);
215  }
216 
217  unsigned size;
218 };
219 
221  using KeyTy = std::pair<UnpackedType, UnpackedType>;
222 
223  AssocDimStorage(KeyTy key) : DimStorage(key.first), indexType(key.second) {}
224  bool operator==(const KeyTy &key) const {
225  return key.first == inner && key.second == indexType;
226  }
227  static AssocDimStorage *construct(TypeStorageAllocator &allocator,
228  const KeyTy &key) {
229  return new (allocator.allocate<AssocDimStorage>()) AssocDimStorage(key);
230  }
231 
233 };
234 
235 } // namespace detail
236 } // namespace moore
237 } // namespace circt
238 
240 
242  return static_cast<detail::DimStorage *>(this->impl);
243 }
244 
246  return Base::get(inner.getContext(), inner);
247 }
248 
250  return Base::get(inner.getContext(), inner, size);
251 }
252 
253 unsigned UnpackedArrayDim::getSize() const { return getImpl()->size; }
254 
256  return Base::get(inner.getContext(), inner, range);
257 }
258 
259 Range UnpackedRangeDim::getRange() const { return getImpl()->range; }
260 
262  UnpackedType indexType) {
263  return Base::get(inner.getContext(), inner, indexType);
264 }
265 
267  return getImpl()->indexType;
268 }
269 
271  std::optional<unsigned> bound) {
272  return Base::get(inner.getContext(), inner, bound.value_or(-1));
273 }
274 
275 std::optional<unsigned> UnpackedQueueDim::getBound() const {
276  unsigned bound = getImpl()->size;
277  if (bound == static_cast<unsigned>(-1))
278  return {};
279  return bound;
280 }
281 
282 //===----------------------------------------------------------------------===//
283 // Packed and Unpacked Structs
284 //===----------------------------------------------------------------------===//
285 
287  switch (kind) {
288  case StructKind::Struct:
289  return "struct";
290  case StructKind::Union:
291  return "union";
293  return "tagged_union";
294  }
295  llvm_unreachable("all struct kinds should be handled");
296 }
297 
298 std::optional<StructKind> moore::getStructKindFromMnemonic(StringRef mnemonic) {
299  return StringSwitch<std::optional<StructKind>>(mnemonic)
300  .Case("struct", StructKind::Struct)
301  .Case("union", StructKind::Union)
302  .Case("tagged_union", StructKind::TaggedUnion)
303  .Default({});
304 }
305 
306 Struct::Struct(StructKind kind, ArrayRef<StructMember> members)
307  : kind(kind), members(members.begin(), members.end()) {
308  // The struct's value domain is two-valued if all members are two-valued.
309  // Otherwise it is four-valued.
310  domain = llvm::all_of(members,
311  [](auto &member) {
312  return member.type.getDomain() == Domain::TwoValued;
313  })
316 
317  // The bit size is the sum of all member bit sizes, or `None` if any of the
318  // member bit sizes are `None`.
319  bitSize = 0;
320  for (const auto &member : members) {
321  if (auto memberSize = member.type.getBitSize()) {
322  *bitSize += *memberSize;
323  } else {
324  bitSize = std::nullopt;
325  break;
326  }
327  }
328 }
329 
330 namespace circt {
331 namespace moore {
332 namespace detail {
333 
334 struct StructTypeStorage : TypeStorage {
335  using KeyTy = std::tuple<unsigned, ArrayRef<StructMember>>;
336 
338  : strukt(static_cast<StructKind>(std::get<0>(key)), std::get<1>(key)) {}
339  bool operator==(const KeyTy &key) const {
340  return std::get<0>(key) == static_cast<unsigned>(strukt.kind) &&
341  std::get<1>(key) == ArrayRef<StructMember>(strukt.members);
342  }
343  static StructTypeStorage *construct(TypeStorageAllocator &allocator,
344  const KeyTy &key) {
345  return new (allocator.allocate<StructTypeStorage>()) StructTypeStorage(key);
346  }
347 
349 };
350 
351 } // namespace detail
352 } // namespace moore
353 } // namespace circt
354 
356  ArrayRef<StructMember> members) {
357  assert(llvm::all_of(members,
358  [](const StructMember &member) {
359  return llvm::isa<PackedType>(member.type);
360  }) &&
361  "packed struct members must be packed");
362  return Base::get(context, static_cast<unsigned>(kind), members);
363 }
364 
365 const Struct &PackedStructType::getStruct() const { return getImpl()->strukt; }
366 
368  StructKind kind,
369  ArrayRef<StructMember> members) {
370  return Base::get(context, static_cast<unsigned>(kind), members);
371 }
372 
374  return getImpl()->strukt;
375 }
376 
377 //===----------------------------------------------------------------------===//
378 // Parsing and Printing
379 //===----------------------------------------------------------------------===//
380 
381 struct Subset {
382  enum { None, Unpacked, Packed } implied = None;
383  bool allowUnpacked = true;
384 };
385 
386 static ParseResult parseMooreType(DialectAsmParser &parser, Subset subset,
387  Type &type);
388 static void printMooreType(Type type, DialectAsmPrinter &printer,
389  Subset subset);
390 
391 /// Parse a type with custom syntax.
392 static OptionalParseResult customTypeParser(DialectAsmParser &parser,
393  StringRef mnemonic, Subset subset,
394  llvm::SMLoc loc, Type &type) {
395  auto *context = parser.getContext();
396 
397  auto yieldPacked = [&](PackedType x) {
398  type = x;
399  return success();
400  };
401  auto yieldUnpacked = [&](UnpackedType x) {
402  if (!subset.allowUnpacked) {
403  parser.emitError(loc)
404  << "unpacked type " << x << " where only packed types are allowed";
405  return failure();
406  }
407  type = x;
408  return success();
409  };
410  auto yieldImplied =
411  [&](llvm::function_ref<PackedType()> ifPacked,
412  llvm::function_ref<UnpackedType()> ifUnpacked) {
413  if (subset.implied == Subset::Packed)
414  return yieldPacked(ifPacked());
415  if (subset.implied == Subset::Unpacked)
416  return yieldUnpacked(ifUnpacked());
417  parser.emitError(loc)
418  << "ambiguous packing; wrap `" << mnemonic
419  << "` in `packed<...>` or `unpacked<...>` to disambiguate";
420  return failure();
421  };
422 
423  // Explicit packing indicators, like `unpacked.named`.
424  if (mnemonic == "unpacked") {
425  UnpackedType inner;
426  if (parser.parseLess() ||
427  parseMooreType(parser, {Subset::Unpacked, true}, inner) ||
428  parser.parseGreater())
429  return failure();
430  return yieldUnpacked(inner);
431  }
432  if (mnemonic == "packed") {
433  PackedType inner;
434  if (parser.parseLess() ||
435  parseMooreType(parser, {Subset::Packed, false}, inner) ||
436  parser.parseGreater())
437  return failure();
438  return yieldPacked(inner);
439  }
440 
441  // Packed primary types.
442  if (mnemonic.size() > 1 && (mnemonic[0] == 'i' || mnemonic[0] == 'l') &&
443  isdigit(mnemonic[1])) {
444  auto domain = mnemonic[0] == 'i' ? Domain::TwoValued : Domain::FourValued;
445  auto spelling = mnemonic.drop_front(1);
446  unsigned width;
447  if (spelling.getAsInteger(10, width))
448  return parser.emitError(loc, "integer width invalid");
449  return yieldPacked(IntType::get(context, width, domain));
450  }
451 
452  // Everything that follows can be packed or unpacked. The packing is inferred
453  // from the last `packed<...>` or `unpacked<...>` that we've seen. The
454  // `yieldImplied` function will call the first lambda to construct a packed
455  // type, or the second lambda to construct an unpacked type. If the
456  // `subset.implied` field is not set, which means there hasn't been any prior
457  // `packed` or `unpacked`, the function will emit an error properly.
458 
459  // Packed and unpacked ranges.
460  if (mnemonic == "unsized") {
461  UnpackedType inner;
462  if (parser.parseLess() || parseMooreType(parser, subset, inner) ||
463  parser.parseGreater())
464  return failure();
465  return yieldImplied(
466  [&]() { return PackedUnsizedDim::get(cast<PackedType>(inner)); },
467  [&]() { return UnpackedUnsizedDim::get(inner); });
468  }
469  if (mnemonic == "range") {
470  UnpackedType inner;
471  int left, right;
472  if (parser.parseLess() || parseMooreType(parser, subset, inner) ||
473  parser.parseComma() || parser.parseInteger(left) ||
474  parser.parseColon() || parser.parseInteger(right) ||
475  parser.parseGreater())
476  return failure();
477  return yieldImplied(
478  [&]() {
479  return PackedRangeDim::get(cast<PackedType>(inner), left, right);
480  },
481  [&]() { return UnpackedRangeDim::get(inner, left, right); });
482  }
483  if (mnemonic == "array") {
484  UnpackedType inner;
485  unsigned size;
486  if (parser.parseLess() || parseMooreType(parser, subset, inner) ||
487  parser.parseComma() || parser.parseInteger(size) ||
488  parser.parseGreater())
489  return failure();
490  return yieldUnpacked(UnpackedArrayDim::get(inner, size));
491  }
492  if (mnemonic == "assoc") {
493  UnpackedType inner;
494  UnpackedType index;
495  if (parser.parseLess() || parseMooreType(parser, subset, inner))
496  return failure();
497  if (succeeded(parser.parseOptionalComma())) {
498  if (parseMooreType(parser, {Subset::Unpacked, true}, index))
499  return failure();
500  }
501  if (parser.parseGreater())
502  return failure();
503  return yieldUnpacked(UnpackedAssocDim::get(inner, index));
504  }
505  if (mnemonic == "queue") {
506  UnpackedType inner;
507  std::optional<unsigned> size;
508  if (parser.parseLess() || parseMooreType(parser, subset, inner))
509  return failure();
510  if (succeeded(parser.parseOptionalComma())) {
511  unsigned tmpSize;
512  if (parser.parseInteger(tmpSize))
513  return failure();
514  size = tmpSize;
515  }
516  if (parser.parseGreater())
517  return failure();
518  return yieldUnpacked(UnpackedQueueDim::get(inner, size));
519  }
520 
521  // Structs
522  if (auto kind = getStructKindFromMnemonic(mnemonic)) {
523  if (parser.parseLess())
524  return failure();
525 
526  StringRef keyword;
527  SmallVector<StructMember> members;
528  auto result2 =
529  parser.parseCommaSeparatedList(OpAsmParser::Delimiter::Braces, [&]() {
530  if (parser.parseKeyword(&keyword))
531  return failure();
532  UnpackedType type;
533  if (parser.parseColon() || parseMooreType(parser, subset, type))
534  return failure();
535  members.push_back(
536  {StringAttr::get(parser.getContext(), keyword), type});
537  return success();
538  });
539  if (result2)
540  return failure();
541 
542  return yieldImplied(
543  [&]() {
544  return PackedStructType::get(parser.getContext(), *kind, members);
545  },
546  [&]() {
547  return UnpackedStructType::get(parser.getContext(), *kind, members);
548  });
549  }
550 
551  return {};
552 }
553 
554 /// Print a type with custom syntax.
555 static LogicalResult customTypePrinter(Type type, DialectAsmPrinter &printer,
556  Subset subset) {
557  // If we are printing a type that may be both packed or unpacked, emit a
558  // wrapping `packed<...>` or `unpacked<...>` accordingly if not done so
559  // previously, in order to disambiguate between the two.
560  if (llvm::isa<PackedDim>(type) || llvm::isa<UnpackedDim>(type) ||
561  llvm::isa<PackedStructType>(type) ||
562  llvm::isa<UnpackedStructType>(type)) {
563  auto needed =
564  llvm::isa<PackedType>(type) ? Subset::Packed : Subset::Unpacked;
565  if (needed != subset.implied) {
566  printer << (needed == Subset::Packed ? "packed" : "unpacked") << "<";
567  printMooreType(type, printer, {needed, true});
568  printer << ">";
569  return success();
570  }
571  }
572 
573  return TypeSwitch<Type, LogicalResult>(type)
574  // Integers and reals
575  .Case<IntType>([&](auto type) {
576  printer << (type.getDomain() == Domain::TwoValued ? "i" : "l");
577  printer << type.getWidth();
578  return success();
579  })
580 
581  // Packed and unpacked dimensions
582  .Case<PackedUnsizedDim, UnpackedUnsizedDim>([&](auto type) {
583  printer << "unsized<";
584  printMooreType(type.getInner(), printer, subset);
585  printer << ">";
586  return success();
587  })
588  .Case<PackedRangeDim, UnpackedRangeDim>([&](auto type) {
589  printer << "range<";
590  printMooreType(type.getInner(), printer, subset);
591  printer << ", " << type.getRange() << ">";
592  return success();
593  })
594  .Case<UnpackedArrayDim>([&](auto type) {
595  printer << "array<";
596  printMooreType(type.getInner(), printer, subset);
597  printer << ", " << type.getSize() << ">";
598  return success();
599  })
600  .Case<UnpackedAssocDim>([&](auto type) {
601  printer << "assoc<";
602  printMooreType(type.getInner(), printer, subset);
603  if (auto indexType = type.getIndexType()) {
604  printer << ", ";
605  printMooreType(indexType, printer, {Subset::Unpacked, true});
606  }
607  printer << ">";
608  return success();
609  })
610  .Case<UnpackedQueueDim>([&](auto type) {
611  printer << "queue<";
612  printMooreType(type.getInner(), printer, subset);
613  if (auto bound = type.getBound())
614  printer << ", " << *bound;
615  printer << ">";
616  return success();
617  })
618 
619  // Structs
620  .Case<PackedStructType, UnpackedStructType>([&](auto type) {
621  const auto &strukt = type.getStruct();
622  printer << getMnemonicFromStructKind(strukt.kind) << "<{";
623  llvm::interleaveComma(strukt.members, printer, [&](const auto &member) {
624  printer << member.name.getValue() << ": ";
625  printMooreType(member.type, printer, subset);
626  });
627  printer << "}>";
628  return success();
629  })
630 
631  .Default([](auto) { return failure(); });
632 }
633 
634 /// Parse a type registered with this dialect.
635 static ParseResult parseMooreType(DialectAsmParser &parser, Subset subset,
636  Type &type) {
637  llvm::SMLoc loc = parser.getCurrentLocation();
638  StringRef mnemonic;
639  if (auto result = generatedTypeParser(parser, &mnemonic, type);
640  result.has_value())
641  return result.value();
642 
643  if (auto result = customTypeParser(parser, mnemonic, subset, loc, type);
644  result.has_value())
645  return result.value();
646 
647  parser.emitError(loc) << "unknown type `" << mnemonic
648  << "` in dialect `moore`";
649  return failure();
650 }
651 
652 /// Print a type registered with this dialect.
653 static void printMooreType(Type type, DialectAsmPrinter &printer,
654  Subset subset) {
655  if (succeeded(generatedTypePrinter(type, printer)))
656  return;
657  if (succeeded(customTypePrinter(type, printer, subset)))
658  return;
659  assert(false && "no printer for unknown `moore` dialect type");
660 }
661 
662 /// Parse a type registered with this dialect.
663 Type MooreDialect::parseType(DialectAsmParser &parser) const {
664  Type type;
665  if (parseMooreType(parser, {Subset::None, true}, type))
666  return {};
667  return type;
668 }
669 
670 /// Print a type registered with this dialect.
671 void MooreDialect::printType(Type type, DialectAsmPrinter &printer) const {
672  printMooreType(type, printer, {Subset::None, true});
673 }
assert(baseType &&"element must be base type")
#define isdigit(x)
Definition: FIRLexer.cpp:26
static ParseResult parseType(Type &result, StringRef name, AsmParser &parser)
Parse a type defined by this dialect.
int32_t width
Definition: FIRRTL.cpp:36
static void printMooreType(Type type, DialectAsmPrinter &printer, Subset subset)
Print a type registered with this dialect.
Definition: MooreTypes.cpp:653
static LogicalResult customTypePrinter(Type type, DialectAsmPrinter &printer, Subset subset)
Print a type with custom syntax.
Definition: MooreTypes.cpp:555
static ParseResult parseMooreType(DialectAsmParser &parser, Subset subset, Type &type)
Parse a type registered with this dialect.
Definition: MooreTypes.cpp:635
static OptionalParseResult customTypeParser(DialectAsmParser &parser, StringRef mnemonic, Subset subset, llvm::SMLoc loc, Type &type)
Parse a type with custom syntax.
Definition: MooreTypes.cpp:392
std::optional< Range > getRange() const
Get the dimension's range, or None if it is unsized.
Definition: MooreTypes.cpp:173
const detail::DimStorage * getImpl() const
Definition: MooreTypes.cpp:183
PackedType getInner() const
Get the element type of the dimension. This is the x in x[a:b].
Definition: MooreTypes.cpp:169
std::optional< unsigned > getSize() const
Get the dimension's size, or None if it is unsized.
Definition: MooreTypes.cpp:179
A packed range dimension, like [a:b].
Definition: MooreTypes.h:294
Range getRange() const
Get the range of this dimension.
Definition: MooreTypes.cpp:195
static PackedRangeDim get(PackedType inner, Range range)
Definition: MooreTypes.cpp:191
const Struct & getStruct() const
Get the struct definition.
Definition: MooreTypes.cpp:365
static PackedStructType get(MLIRContext *context, StructKind kind, ArrayRef< StructMember > members)
Definition: MooreTypes.cpp:355
A packed SystemVerilog type.
Definition: MooreTypes.h:231
std::optional< unsigned > getBitSize() const
Get the size of this type in bits.
Definition: MooreTypes.cpp:107
Domain getDomain() const
Get the value domain of this type.
Definition: MooreTypes.cpp:98
A packed unsized dimension, like [].
Definition: MooreTypes.h:280
static PackedUnsizedDim get(PackedType inner)
Definition: MooreTypes.cpp:187
An unpacked array dimension, like [a].
Definition: MooreTypes.h:365
static UnpackedArrayDim get(UnpackedType inner, unsigned size)
Definition: MooreTypes.cpp:249
unsigned getSize() const
Get the size of the array, i.e. the a in [a].
Definition: MooreTypes.cpp:253
An unpacked associative dimension, like [T] or [*].
Definition: MooreTypes.h:421
static UnpackedAssocDim get(UnpackedType inner, UnpackedType indexType={})
Definition: MooreTypes.cpp:261
UnpackedType getIndexType() const
Get the index type of the associative dimension.
Definition: MooreTypes.cpp:266
const detail::DimStorage * getImpl() const
Definition: MooreTypes.cpp:241
UnpackedType getInner() const
Get the element type of the dimension. This is the x in x[a:b].
Definition: MooreTypes.cpp:239
An unpacked queue dimension with optional bound, like [$] or [$:a].
Definition: MooreTypes.h:439
static UnpackedQueueDim get(UnpackedType inner, std::optional< unsigned > bound={})
Definition: MooreTypes.cpp:270
std::optional< unsigned > getBound() const
Get the bound of the queue, i.e.
Definition: MooreTypes.cpp:275
An unpacked range dimension, like [a:b].
Definition: MooreTypes.h:382
Range getRange() const
Get the range of this dimension.
Definition: MooreTypes.cpp:259
static UnpackedRangeDim get(UnpackedType inner, Range range)
Definition: MooreTypes.cpp:255
const Struct & getStruct() const
Get the struct definition.
Definition: MooreTypes.cpp:373
static UnpackedStructType get(MLIRContext *context, StructKind kind, ArrayRef< StructMember > members)
Definition: MooreTypes.cpp:367
An unpacked SystemVerilog type.
Definition: MooreTypes.h:179
std::optional< unsigned > getBitSize() const
Get the size of this type in bits.
Definition: MooreTypes.cpp:74
Domain getDomain() const
Get the value domain of this type.
Definition: MooreTypes.cpp:65
An unpacked unsized dimension, like [].
Definition: MooreTypes.h:351
static UnpackedUnsizedDim get(UnpackedType inner)
Definition: MooreTypes.cpp:245
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:54
Domain
The number of values each bit of a type can assume.
Definition: MooreTypes.h:27
@ 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.
Definition: MooreTypes.h:35
@ Signed
A signed type.
@ Unsigned
An unsigned type.
StringRef getKeywordFromSign(const Sign &sign)
Map a Sign to the corresponding keyword.
Definition: MooreTypes.cpp:51
StringRef getMnemonicFromStructKind(StructKind kind)
Map a StructKind to the corresponding mnemonic.
Definition: MooreTypes.cpp:286
StructKind
Whether a struct is a struct, union, or union tagged.
Definition: MooreTypes.h:460
@ TaggedUnion
A union tagged.
std::optional< StructKind > getStructKindFromMnemonic(StringRef mnemonic)
Map a mnemonic to the corresponding StructKind.
Definition: MooreTypes.cpp:298
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
enum Subset::@7 implied
bool allowUnpacked
Definition: MooreTypes.cpp:383
The [a:b] part in a vector/array type such as logic [a:b].
Definition: MooreTypes.h:62
A member of a struct.
Definition: MooreTypes.h:482
UnpackedType type
The type of this member.
Definition: MooreTypes.h:486
std::optional< unsigned > bitSize
The size of this struct in bits.
Definition: MooreTypes.h:515
Struct(StructKind kind, ArrayRef< StructMember > members)
Create a new struct.
Definition: MooreTypes.cpp:306
Domain domain
The value domain of this struct.
Definition: MooreTypes.h:511
SmallVector< StructMember, 4 > members
The list of members.
Definition: MooreTypes.h:508
static AssocDimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
Definition: MooreTypes.cpp:227
bool operator==(const KeyTy &key) const
Definition: MooreTypes.cpp:224
static DimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
Definition: MooreTypes.cpp:134
bool operator==(const KeyTy &key) const
Definition: MooreTypes.cpp:133
bool operator==(const KeyTy &key) const
Definition: MooreTypes.cpp:154
static RangeDimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
Definition: MooreTypes.cpp:157
bool operator==(const KeyTy &key) const
Definition: MooreTypes.cpp:209
static SizedDimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
Definition: MooreTypes.cpp:212
static StructTypeStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
Definition: MooreTypes.cpp:343
bool operator==(const KeyTy &key) const
Definition: MooreTypes.cpp:339
std::tuple< unsigned, ArrayRef< StructMember > > KeyTy
Definition: MooreTypes.cpp:335
static UnsizedDimStorage * construct(TypeStorageAllocator &allocator, const KeyTy &key)
Definition: MooreTypes.cpp:144