CIRCT 24.0.0git
Loading...
Searching...
No Matches
FIRRTLTypes.h
Go to the documentation of this file.
1//===- FIRRTLTypes.h - FIRRTL Type System -----------------------*- C++ -*-===//
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 defines the type system for the FIRRTL Dialect.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef CIRCT_DIALECT_FIRRTL_TYPES_H
14#define CIRCT_DIALECT_FIRRTL_TYPES_H
15
20#include "circt/Support/LLVM.h"
21#include "mlir/IR/OpDefinition.h"
22#include "mlir/IR/Types.h"
23#include "llvm/ADT/TypeSwitch.h"
24
25namespace circt {
26namespace firrtl {
27namespace detail {
28struct FIRRTLBaseTypeStorage;
29struct WidthTypeStorage;
30struct BundleTypeStorage;
31struct FVectorTypeStorage;
32struct FEnumTypeStorage;
33struct CMemoryTypeStorage;
34struct RefTypeStorage;
35struct LHSTypeStorage;
36struct BaseTypeAliasStorage;
37struct OpenBundleTypeStorage;
38struct OpenVectorTypeStorage;
39struct ClassTypeStorage;
40struct DomainTypeStorage;
41} // namespace detail.
42
43class AnyRefType;
44class ClassType;
45class ClockType;
46class ResetType;
47class AsyncResetType;
48class SIntType;
49class UIntType;
50class AnalogType;
51class BundleType;
52class OpenBundleType;
53class OpenVectorType;
54class FVectorType;
55class FEnumType;
56class RefType;
57class LHSType;
58class PropertyType;
59class StringType;
60class FIntegerType;
61class DomainFieldAttr;
62class ListType;
63class RegistryType;
64class PathType;
65class BoolType;
66class DoubleType;
67class BaseTypeAliasType;
68class FStringType;
69class DomainType;
70class DomainOp;
71
72/// A collection of bits indicating the recursive properties of a type.
74 /// Whether the type only contains passive elements.
75 bool isPassive : 1;
76 /// Whether the type contains a reference type.
78 /// Whether the type contains an analog type.
80 /// Whether the type contains a const type.
81 bool containsConst : 1;
82 /// Whether the type contains a type alias.
84 /// Whether the type has any uninferred bit widths.
86 /// Whether the type has any uninferred reset.
88};
89
90// This is a common base class for all FIRRTL types.
91class FIRRTLType : public Type {
92public:
93 /// Support method to enable LLVM-style type casting.
94 static bool classof(Type type) {
95 return llvm::isa<FIRRTLDialect>(type.getDialect());
96 }
97
98 /// Return the recursive properties of the type, containing the `isPassive`,
99 /// `containsAnalog`, and `hasUninferredWidth` bits, among others.
101
102 //===--------------------------------------------------------------------===//
103 // Convenience methods for accessing recursive type properties
104 //===--------------------------------------------------------------------===//
105
106 /// Returns true if this is or contains a 'const' type.
108
109 /// Return true if this is or contains an Analog type.
111
112 /// Return true if this is or contains a Reference type.
116
117 /// Return true if this is an anonymous type (no type alias).
121
122 /// Return true if this type contains an uninferred bit width.
126
127 /// Return true if this type contains an uninferred bit reset.
131
132 //===--------------------------------------------------------------------===//
133 // Type classifications
134 //===--------------------------------------------------------------------===//
135
136 /// Return true if this is a 'ground' type, aka a non-aggregate type.
137 bool isGround();
138
139 /// Returns true if this is a 'const' type that can only hold compile-time
140 /// constant values
141 bool isConst() const;
142
143protected:
144 using Type::Type;
145};
146
147// Common base class for all base FIRRTL types.
149 : public FIRRTLType::TypeBase<FIRRTLBaseType, FIRRTLType,
150 detail::FIRRTLBaseTypeStorage> {
151public:
152 using Base::Base;
153
154 /// Returns true if this is a 'const' type that can only hold compile-time
155 /// constant values
156 bool isConst() const;
157
158 /// Return true if this is a "passive" type - one that contains no "flip"
159 /// types recursively within itself.
160 bool isPassive() const { return getRecursiveTypeProperties().isPassive; }
161
162 /// Return this type with any flip types recursively removed from itself.
164
165 /// Return this type with any type alias types recursively removed from
166 /// itself.
168
169 /// Return a 'const' or non-'const' version of this type.
171
172 /// Return this type with a 'const' modifiers dropped
174
175 /// Return this type with all ground types replaced with UInt<1>. This is
176 /// used for `mem` operations.
178
179 /// Return this type with widths of all ground types removed. This
180 /// enables two types to be compared by structure and name ignoring
181 /// widths.
183
184 /// If this is an IntType, AnalogType, or sugar type for a single bit (Clock,
185 /// Reset, etc) then return the bitwidth. Return -1 if the is one of these
186 /// types but without a specified bitwidth. Return -2 if this isn't a simple
187 /// type.
188 int32_t getBitWidthOrSentinel();
189
190 /// Support method to enable LLVM-style type casting.
191 static bool classof(Type type) {
192 return llvm::isa<FIRRTLDialect>(type.getDialect()) &&
193 !llvm::isa<PropertyType, RefType, LHSType, OpenBundleType,
194 OpenVectorType, FStringType, DomainType>(type);
195 }
196
197 /// Returns true if this is a non-const "passive" that which is not analog.
199 return isPassive() && !containsAnalog() && !containsConst();
200 }
201
202 /// Return true if this is a valid "reset" type.
203 bool isResetType();
204};
205
206/// Returns true if this is a 'const' type whose value is guaranteed to be
207/// unchanging at circuit execution time
208bool isConst(Type type);
209
210/// Returns true if the type is or contains a 'const' type whose value is
211/// guaranteed to be unchanging at circuit execution time
212bool containsConst(Type type);
213
214/// Return true if the type has zero bit width.
215bool hasZeroBitWidth(FIRRTLType type);
216
217/// Returns whether the two types are equivalent. This implements the exact
218/// definition of type equivalence in the FIRRTL spec. If the types being
219/// compared have any outer flips that encode FIRRTL module directions (input or
220/// output), these should be stripped before using this method.
221bool areTypesEquivalent(FIRRTLType destType, FIRRTLType srcType,
222 bool destOuterTypeIsConst = false,
223 bool srcOuterTypeIsConst = false,
224 bool requireSameWidths = false);
225
226/// Returns true if two types are weakly equivalent. See the FIRRTL spec,
227/// Section 4.6, for a full definition of this. Roughly, the oriented types
228/// (the types with any flips pushed to the leaves) must match. This allows for
229/// types with flips in different positions to be equivalent.
231 bool destFlip = false, bool srcFlip = false,
232 bool destOuterTypeIsConst = false,
233 bool srcOuterTypeIsConst = false);
234
235/// Returns whether the srcType can be const-casted to the destType.
236bool areTypesConstCastable(FIRRTLType destType, FIRRTLType srcType,
237 bool srcOuterTypeIsConst = false);
238
239/// Return true if destination ref type can be cast from source ref type,
240/// per FIRRTL spec rules they must be identical or destination has
241/// more general versions of the corresponding type in the source.
242bool areTypesRefCastable(Type dstType, Type srcType);
243
244/// Returns true if the destination is at least as wide as a source. The source
245/// and destination types must be equivalent non-analog types. The types are
246/// recursively connected to ensure that the destination is larger than the
247/// source: ground types are compared on width, vector types are checked
248/// recursively based on their elements and bundles are compared
249/// field-by-field. Types with unresolved widths are assumed to fit into or
250/// hold their counterparts.
251bool isTypeLarger(FIRRTLBaseType dstType, FIRRTLBaseType srcType);
252
253/// Return true if anonymous types of given arguments are equivalent by pointer
254/// comparison.
256bool areAnonymousTypesEquivalent(mlir::Type lhs, mlir::Type rhs);
257
258mlir::Type getPassiveType(mlir::Type anyBaseFIRRTLType);
259
260/// Returns true if the given type has some flipped (aka unaligned) dataflow.
261/// This will be true if the port contains either bi-directional signals or
262/// analog types. Non-HW types (e.g., ref types) are never considered InOut.
263bool isTypeInOut(mlir::Type type);
264
265/// Return true if the given type contains any elements of hardware types.
267
268//===----------------------------------------------------------------------===//
269// Width Qualified Ground Types
270//===----------------------------------------------------------------------===//
271
272/// Trait for types which have a width.
273/// Users must implement:
274/// ```c++
275/// /// Return the width if known, or -1 if unknown.
276/// int32_t getWidthOrSentinel();
277/// ```
278template <typename ConcreteType>
280 : public mlir::TypeTrait::TraitBase<ConcreteType, WidthQualifiedTypeTrait> {
281public:
282 /// Return an optional containing the width, if the width is known (or empty
283 /// if width is unknown).
284 std::optional<int32_t> getWidth() const {
285 auto width = static_cast<const ConcreteType *>(this)->getWidthOrSentinel();
286 if (width < 0)
287 return std::nullopt;
288 return width;
289 }
290
291 /// Return true if this integer type has a known width.
292 bool hasWidth() const {
293 return 0 <= static_cast<const ConcreteType *>(this)->getWidthOrSentinel();
294 }
295};
296
297//===----------------------------------------------------------------------===//
298// IntType
299//===----------------------------------------------------------------------===//
300
301class SIntType;
302class UIntType;
303
304/// This is the common base class between SIntType and UIntType.
305class IntType : public FIRRTLBaseType, public WidthQualifiedTypeTrait<IntType> {
306public:
307 using FIRRTLBaseType::FIRRTLBaseType;
308
309 /// Return an SIntType or UIntType with the specified signedness, width, and
310 /// constness.
311 static IntType get(MLIRContext *context, bool isSigned,
312 int32_t widthOrSentinel = -1, bool isConst = false);
313
314 bool isSigned() { return mlir::isa<SIntType>(*this); }
315 bool isUnsigned() { return mlir::isa<UIntType>(*this); }
316
317 /// Return the width of this type, or -1 if it has none specified.
318 int32_t getWidthOrSentinel() const;
319
320 /// Return a 'const' or non-'const' version of this type.
321 IntType getConstType(bool isConst) const;
322
323 static bool classof(Type type) { return mlir::isa<SIntType, UIntType>(type); }
324};
325
326//===----------------------------------------------------------------------===//
327// PropertyTypes
328//===----------------------------------------------------------------------===//
329
330class PropertyType : public FIRRTLType {
331public:
332 /// Support method to enable LLVM-style type casting.
333 static bool classof(Type type) {
334 return llvm::isa<AnyRefType, ClassType, StringType, FIntegerType, ListType,
335 RegistryType, PathType, BoolType, DoubleType>(type);
336 }
337
338protected:
339 using FIRRTLType::FIRRTLType;
340};
341
342//===----------------------------------------------------------------------===//
343// ClassElement
344//===----------------------------------------------------------------------===//
345
349
350 StringAttr name;
351 Type type;
353
354 StringRef getName() const { return name.getValue(); }
355
356 /// Return true if this is a simple output-only element. If you want the
357 /// direction of the port, use the \p direction field directly.
358 bool isInput() const { return direction == Direction::In && !isInOut(); }
359
360 /// Return true if this is a simple input-only element. If you want the
361 /// direction of the port, use the \p direction field directly.
362 bool isOutput() const { return direction == Direction::Out && !isInOut(); }
363
364 /// Return true if this is an inout port. This will be true if the port
365 /// contains either bi-directional signals or analog types.
366 /// Non-HW types (e.g., ref types) are never considered InOut.
367 bool isInOut() const { return isTypeInOut(type); }
368
369 bool operator==(const ClassElement &rhs) const {
370 return name == rhs.name && type == rhs.type;
371 }
372
373 bool operator!=(const ClassElement &rhs) const { return !(*this == rhs); }
374};
375
376// NOLINTNEXTLINE(readability-identifier-naming)
377inline llvm::hash_code hash_value(const ClassElement &element) {
378 return llvm::hash_combine(element.name, element.type, element.direction);
379}
380
381//===----------------------------------------------------------------------===//
382// Type helpers
383//===----------------------------------------------------------------------===//
384
385// Get the bit width for this type, return None if unknown. Unlike
386// getBitWidthOrSentinel(), this can recursively compute the bitwidth of
387// aggregate types. For bundle and vectors, recursively get the width of each
388// field element and return the total bit width of the aggregate type. This
389// returns None, if any of the bundle fields is a flip type, or ground type with
390// unknown bit width.
391std::optional<int64_t> getBitWidth(FIRRTLBaseType type,
392 bool ignoreFlip = false);
393
394// Parse a FIRRTL type without a leading `!firrtl.` dialect tag.
395ParseResult parseNestedType(FIRRTLType &result, AsmParser &parser);
396ParseResult parseNestedBaseType(FIRRTLBaseType &result, AsmParser &parser);
397ParseResult parseNestedPropertyType(PropertyType &result, AsmParser &parser);
398
399// Print a FIRRTL type without a leading `!firrtl.` dialect tag.
400void printNestedType(Type type, AsmPrinter &os);
401
402using FIRRTLValue = mlir::TypedValue<FIRRTLType>;
403using FIRRTLBaseValue = mlir::TypedValue<FIRRTLBaseType>;
404using FIRRTLPropertyValue = mlir::TypedValue<PropertyType>;
405
406} // namespace firrtl
407} // namespace circt
408
409// Include generated types.
410#define GET_TYPEDEF_CLASSES
411#include "circt/Dialect/FIRRTL/FIRRTLTypes.h.inc"
412
413namespace llvm {
414
415// Type hash just like pointers.
416template <>
417struct DenseMapInfo<circt::firrtl::FIRRTLType> {
419 static unsigned getHashValue(FIRRTLType val) { return mlir::hash_value(val); }
420 static bool isEqual(FIRRTLType LHS, FIRRTLType RHS) { return LHS == RHS; }
421};
422
423} // namespace llvm
424
425namespace circt {
426namespace firrtl {
427//===--------------------------------------------------------------------===//
428// Utility for type aliases
429//===--------------------------------------------------------------------===//
430
431/// A struct to check if there is a type derived from FIRRTLBaseType.
432/// `ContainAliasableTypes<BaseTy>::value` returns true if `BaseTy` is derived
433/// from `FIRRTLBaseType` and not `FIRRTLBaseType` itself, or is not FIRRTL type
434/// to cover type interfaces.
435template <typename head, typename... tail>
437public:
438 static constexpr bool value = ContainAliasableTypes<head>::value ||
440};
441
442template <typename BaseTy>
444 static constexpr bool isFIRRTLBaseType =
445 std::is_base_of<FIRRTLBaseType, BaseTy>::value &&
446 !std::is_same_v<FIRRTLBaseType, BaseTy>;
447 static constexpr bool isFIRRTLType =
448 std::is_base_of<FIRRTLType, BaseTy>::value;
449
450public:
451 static constexpr bool value = isFIRRTLBaseType || !isFIRRTLType;
452};
453
454template <typename... BaseTy>
455bool type_isa(Type type) { // NOLINT(readability-identifier-naming)
456 // First check if the type is the requested type.
457 if (isa<BaseTy...>(type))
458 return true;
459
460 // If the requested type is a subtype of FIRRTLBaseType, then check if it is a
461 // type alias wrapping the requested type.
462 if constexpr (ContainAliasableTypes<BaseTy...>::value) {
463 if (auto alias = dyn_cast<BaseTypeAliasType>(type))
464 return type_isa<BaseTy...>(alias.getInnerType());
465 }
466
467 return false;
468}
469
470// type_isa for a nullable argument.
471template <typename... BaseTy>
472bool type_isa_and_nonnull(Type type) { // NOLINT(readability-identifier-naming)
473 if (!type)
474 return false;
475 return type_isa<BaseTy...>(type);
476}
477
478template <typename BaseTy>
479BaseTy type_cast(Type type) { // NOLINT(readability-identifier-naming)
480 assert(type_isa<BaseTy>(type) && "type must convert to requested type");
481
482 // If the type is the requested type, return it.
483 if (isa<BaseTy>(type))
484 return cast<BaseTy>(type);
485
486 // Otherwise, it must be a type alias wrapping the requested type.
488 if (auto alias = dyn_cast<BaseTypeAliasType>(type))
489 return type_cast<BaseTy>(alias.getInnerType());
490 }
491
492 // Otherwise, it should fail. `cast` should cause a better assertion failure,
493 // so just use it.
494 return cast<BaseTy>(type);
495}
496
497template <typename BaseTy>
498BaseTy type_dyn_cast(Type type) { // NOLINT(readability-identifier-naming)
499 if (type_isa<BaseTy>(type))
500 return type_cast<BaseTy>(type);
501 return {};
502}
503
504template <typename BaseTy>
505BaseTy
506type_dyn_cast_or_null(Type type) { // NOLINT(readability-identifier-naming)
507 if (type_isa_and_nonnull<BaseTy>(type))
508 return type_cast<BaseTy>(type);
509 return {};
510}
511
512//===--------------------------------------------------------------------===//
513// Type alias aware TypeSwitch.
514//===--------------------------------------------------------------------===//
515
516/// This class implements the same functionality as TypeSwitch except that
517/// it uses firrtl::type_dyn_cast for dynamic cast. llvm::TypeSwitch is not
518/// customizable so this class currently duplicates the code.
519template <typename T, typename ResultT = void>
521 : public llvm::detail::TypeSwitchBase<FIRRTLTypeSwitch<T, ResultT>, T> {
522public:
524 using BaseT::BaseT;
525 using BaseT::Case;
527
528 /// Add a case on the given type.
529 template <typename CaseT, typename CallableT>
531 Case(CallableT &&caseFn) { // NOLINT(readability-identifier-naming)
532 if (result)
533 return *this;
534
535 // Check to see if CaseT applies to 'value'. Use `type_dyn_cast` here.
536 if (auto caseValue = circt::firrtl::type_dyn_cast<CaseT>(this->value))
537 result.emplace(caseFn(caseValue));
538 return *this;
539 }
540
541 /// As a default, invoke the given callable within the root value.
542 template <typename CallableT>
543 [[nodiscard]] ResultT
544 Default(CallableT &&defaultFn) { // NOLINT(readability-identifier-naming)
545 if (result)
546 return std::move(*result);
547 return defaultFn(this->value);
548 }
549
550 /// As a default, return the given value.
551 [[nodiscard]] ResultT
552 Default(ResultT defaultResult) { // NOLINT(readability-identifier-naming)
553 if (result)
554 return std::move(*result);
555 return defaultResult;
556 }
557
558 [[nodiscard]] operator ResultT() {
559 assert(result && "Fell off the end of a type-switch");
560 return std::move(*result);
561 }
562
563private:
564 /// The pointer to the result of this switch statement, once known,
565 /// null before that.
566 std::optional<ResultT> result;
567};
568
569/// Specialization of FIRRTLTypeSwitch for void returning callables.
570template <typename T>
571class FIRRTLTypeSwitch<T, void>
572 : public llvm::detail::TypeSwitchBase<FIRRTLTypeSwitch<T, void>, T> {
573public:
575 using BaseT::BaseT;
576 using BaseT::Case;
578
579 /// Add a case on the given type.
580 template <typename CaseT, typename CallableT>
582 Case(CallableT &&caseFn) { // NOLINT(readability-identifier-naming)
583 if (foundMatch)
584 return *this;
585
586 // Check to see if any of the types apply to 'value'.
587 if (auto caseValue = circt::firrtl::type_dyn_cast<CaseT>(this->value)) {
588 caseFn(caseValue);
589 foundMatch = true;
590 }
591 return *this;
592 }
593
594 /// As a default, invoke the given callable within the root value.
595 template <typename CallableT>
596 void Default(CallableT &&defaultFn) { // NOLINT(readability-identifier-naming)
597 if (!foundMatch)
598 defaultFn(this->value);
599 }
600
601private:
602 /// A flag detailing if we have already found a match.
603 bool foundMatch = false;
604};
605
606template <typename BaseTy>
608 : public ::mlir::Type::TypeBase<BaseTypeAliasOr<BaseTy>,
609 firrtl::FIRRTLBaseType,
610 detail::FIRRTLBaseTypeStorage> {
611
612public:
615 // Support LLVM isa/cast/dyn_cast to BaseTy.
616 static bool classof(Type other) { return type_isa<BaseTy>(other); }
617
618 // Support C++ implicit conversions to BaseTy.
619 operator BaseTy() const { return circt::firrtl::type_cast<BaseTy>(*this); }
620
621 BaseTy base() const { return circt::firrtl::type_cast<BaseTy>(*this); }
622};
623
624} // namespace firrtl
625} // namespace circt
626
627//===--------------------------------------------------------------------===//
628// Subelement Visitors
629//===--------------------------------------------------------------------===//
630
631/// Allow walking and replacing the subelements of a ClassElement.
632template <>
633struct mlir::AttrTypeSubElementHandler<circt::firrtl::ClassElement> {
635
636 static void walk(ClassElement param,
637 AttrTypeImmediateSubElementWalker &walker) {
638 walker.walk(param.name);
639 walker.walk(param.type);
640 }
642 AttrSubElementReplacements &attrRepls,
643 TypeSubElementReplacements &typeRepls) {
644 return ClassElement(cast<StringAttr>(attrRepls.take_front(1)[0]),
645 typeRepls.take_front(1)[0], param.direction);
646 }
647};
648
649/// Allow walking and replacing the subelements of a BundleElement.
650template <>
651struct mlir::AttrTypeSubElementHandler<
652 circt::firrtl::BundleType::BundleElement> {
653 using BundleElement = circt::firrtl::BundleType::BundleElement;
654
655 static void walk(const BundleElement &param,
656 AttrTypeImmediateSubElementWalker &walker) {
657 walker.walk(param.name);
658 walker.walk(param.type);
659 }
661 AttrSubElementReplacements &attrRepls,
662 TypeSubElementReplacements &typeRepls) {
663 return BundleElement(
664 cast<StringAttr>(attrRepls.take_front(1)[0]), param.isFlip,
665 cast<circt::firrtl::FIRRTLBaseType>(typeRepls.take_front(1)[0]));
666 }
667};
668
669/// Allow walking and replacing the subelements of an OpenBundleElement.
670template <>
671struct mlir::AttrTypeSubElementHandler<
672 circt::firrtl::OpenBundleType::BundleElement> {
673 using BundleElement = circt::firrtl::OpenBundleType::BundleElement;
674
675 static void walk(const BundleElement &param,
676 AttrTypeImmediateSubElementWalker &walker) {
677 walker.walk(param.name);
678 walker.walk(param.type);
679 }
681 AttrSubElementReplacements &attrRepls,
682 TypeSubElementReplacements &typeRepls) {
683 return BundleElement(
684 cast<StringAttr>(attrRepls.take_front(1)[0]), param.isFlip,
685 cast<circt::firrtl::FIRRTLType>(typeRepls.take_front(1)[0]));
686 }
687};
688
689/// Allow walking and replacing the subelements of an EnumElement.
690template <>
691struct mlir::AttrTypeSubElementHandler<circt::firrtl::FEnumType::EnumElement> {
692 using EnumElement = circt::firrtl::FEnumType::EnumElement;
693
694 static void walk(const EnumElement &param,
695 AttrTypeImmediateSubElementWalker &walker) {
696 walker.walk(param.name);
697 walker.walk(param.value);
698 walker.walk(param.type);
699 }
700 static EnumElement replace(const EnumElement &param,
701 AttrSubElementReplacements &attrRepls,
702 TypeSubElementReplacements &typeRepls) {
703 auto attrs = attrRepls.take_front(2);
704 return EnumElement(
705 cast<StringAttr>(attrs[0]), cast<IntegerAttr>(attrs[1]),
706 cast<circt::firrtl::FIRRTLBaseType>(typeRepls.take_front(1)[0]));
707 }
708};
709
710#endif // CIRCT_DIALECT_FIRRTL_TYPES_H
assert(baseType &&"element must be base type")
static std::unique_ptr< Context > context
static bool classof(Type other)
A struct to check if there is a type derived from FIRRTLBaseType.
FIRRTLBaseType getConstType(bool isConst) const
Return a 'const' or non-'const' version of this type.
FIRRTLBaseType getAnonymousType()
Return this type with any type alias types recursively removed from itself.
static bool classof(Type type)
Support method to enable LLVM-style type casting.
bool isResetType()
Return true if this is a valid "reset" type.
bool isRegisterType()
Returns true if this is a non-const "passive" that which is not analog.
FIRRTLBaseType getMaskType()
Return this type with all ground types replaced with UInt<1>.
FIRRTLBaseType getPassiveType()
Return this type with any flip types recursively removed from itself.
int32_t getBitWidthOrSentinel()
If this is an IntType, AnalogType, or sugar type for a single bit (Clock, Reset, etc) then return the...
FIRRTLBaseType getAllConstDroppedType()
Return this type with a 'const' modifiers dropped.
bool isPassive() const
Return true if this is a "passive" type - one that contains no "flip" types recursively within itself...
FIRRTLBaseType getWidthlessType()
Return this type with widths of all ground types removed.
bool isConst() const
Returns true if this is a 'const' type that can only hold compile-time constant values.
void Default(CallableT &&defaultFn)
As a default, invoke the given callable within the root value.
FIRRTLTypeSwitch< T, void > & Case(CallableT &&caseFn)
Add a case on the given type.
FIRRTLTypeSwitch(FIRRTLTypeSwitch &&other)=default
This class implements the same functionality as TypeSwitch except that it uses firrtl::type_dyn_cast ...
ResultT Default(ResultT defaultResult)
As a default, return the given value.
FIRRTLTypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
FIRRTLTypeSwitch(FIRRTLTypeSwitch &&other)=default
ResultT Default(CallableT &&defaultFn)
As a default, invoke the given callable within the root value.
std::optional< ResultT > result
The pointer to the result of this switch statement, once known, null before that.
bool containsReference()
Return true if this is or contains a Reference type.
bool isGround()
Return true if this is a 'ground' type, aka a non-aggregate type.
static bool classof(Type type)
Support method to enable LLVM-style type casting.
Definition FIRRTLTypes.h:94
bool hasUninferredWidth()
Return true if this type contains an uninferred bit width.
bool containsTypeAlias()
Return true if this is an anonymous type (no type alias).
RecursiveTypeProperties getRecursiveTypeProperties() const
Return the recursive properties of the type, containing the isPassive, containsAnalog,...
bool hasUninferredReset()
Return true if this type contains an uninferred bit reset.
bool isConst() const
Returns true if this is a 'const' type that can only hold compile-time constant values.
bool containsAnalog()
Return true if this is or contains an Analog type.
bool containsConst()
Returns true if this is or contains a 'const' type.
This is the common base class between SIntType and UIntType.
IntType getConstType(bool isConst) const
Return a 'const' or non-'const' version of this type.
static bool classof(Type type)
int32_t getWidthOrSentinel() const
Return the width of this type, or -1 if it has none specified.
static IntType get(MLIRContext *context, bool isSigned, int32_t widthOrSentinel=-1, bool isConst=false)
Return an SIntType or UIntType with the specified signedness, width, and constness.
static bool classof(Type type)
Support method to enable LLVM-style type casting.
Trait for types which have a width.
bool hasWidth() const
Return true if this integer type has a known width.
std::optional< int32_t > getWidth() const
Return an optional containing the width, if the width is known (or empty if width is unknown).
BaseTy type_cast(Type type)
Direction
This represents the direction of a single port.
Definition FIRRTLEnums.h:27
mlir::TypedValue< FIRRTLBaseType > FIRRTLBaseValue
ParseResult parseNestedType(FIRRTLType &result, AsmParser &parser)
Parse a FIRRTLType.
bool areAnonymousTypesEquivalent(FIRRTLBaseType lhs, FIRRTLBaseType rhs)
Return true if anonymous types of given arguments are equivalent by pointer comparison.
bool type_isa_and_nonnull(Type type)
ParseResult parseNestedBaseType(FIRRTLBaseType &result, AsmParser &parser)
bool isTypeInOut(mlir::Type type)
Returns true if the given type has some flipped (aka unaligned) dataflow.
bool areTypesRefCastable(Type dstType, Type srcType)
Return true if destination ref type can be cast from source ref type, per FIRRTL spec rules they must...
bool areTypesEquivalent(FIRRTLType destType, FIRRTLType srcType, bool destOuterTypeIsConst=false, bool srcOuterTypeIsConst=false, bool requireSameWidths=false)
Returns whether the two types are equivalent.
bool areTypesWeaklyEquivalent(FIRRTLType destType, FIRRTLType srcType, bool destFlip=false, bool srcFlip=false, bool destOuterTypeIsConst=false, bool srcOuterTypeIsConst=false)
Returns true if two types are weakly equivalent.
mlir::Type getPassiveType(mlir::Type anyBaseFIRRTLType)
bool isTypeLarger(FIRRTLBaseType dstType, FIRRTLBaseType srcType)
Returns true if the destination is at least as wide as a source.
bool containsConst(Type type)
Returns true if the type is or contains a 'const' type whose value is guaranteed to be unchanging at ...
mlir::TypedValue< FIRRTLType > FIRRTLValue
bool hasZeroBitWidth(FIRRTLType type)
Return true if the type has zero bit width.
BaseTy type_dyn_cast(Type type)
void printNestedType(Type type, AsmPrinter &os)
Print a type defined by this dialect.
BaseTy type_dyn_cast_or_null(Type type)
mlir::TypedValue< PropertyType > FIRRTLPropertyValue
bool isConst(Type type)
Returns true if this is a 'const' type whose value is guaranteed to be unchanging at circuit executio...
bool hasHardwareElements(FIRRTLType type)
Return true if the given type contains any elements of hardware types.
llvm::hash_code hash_value(const ClassElement &element)
bool areTypesConstCastable(FIRRTLType destType, FIRRTLType srcType, bool srcOuterTypeIsConst=false)
Returns whether the srcType can be const-casted to the destType.
bool type_isa(Type type)
ParseResult parseNestedPropertyType(PropertyType &result, AsmParser &parser)
std::optional< int64_t > getBitWidth(FIRRTLBaseType type, bool ignoreFlip=false)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
llvm::hash_code hash_value(const T &e)
bool isInOut() const
Return true if this is an inout port.
ClassElement(StringAttr name, Type type, Direction direction)
bool isOutput() const
Return true if this is a simple input-only element.
bool isInput() const
Return true if this is a simple output-only element.
StringRef getName() const
bool operator!=(const ClassElement &rhs) const
bool operator==(const ClassElement &rhs) const
A collection of bits indicating the recursive properties of a type.
Definition FIRRTLTypes.h:73
bool containsReference
Whether the type contains a reference type.
Definition FIRRTLTypes.h:77
bool isPassive
Whether the type only contains passive elements.
Definition FIRRTLTypes.h:75
bool containsAnalog
Whether the type contains an analog type.
Definition FIRRTLTypes.h:79
bool hasUninferredReset
Whether the type has any uninferred reset.
Definition FIRRTLTypes.h:87
bool containsTypeAlias
Whether the type contains a type alias.
Definition FIRRTLTypes.h:83
bool containsConst
Whether the type contains a const type.
Definition FIRRTLTypes.h:81
bool hasUninferredWidth
Whether the type has any uninferred bit widths.
Definition FIRRTLTypes.h:85
static unsigned getHashValue(FIRRTLType val)
static bool isEqual(FIRRTLType LHS, FIRRTLType RHS)
static BundleElement replace(const BundleElement &param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
static void walk(const BundleElement &param, AttrTypeImmediateSubElementWalker &walker)
static ClassElement replace(ClassElement param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
static void walk(ClassElement param, AttrTypeImmediateSubElementWalker &walker)
static void walk(const EnumElement &param, AttrTypeImmediateSubElementWalker &walker)
static EnumElement replace(const EnumElement &param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
static BundleElement replace(const BundleElement &param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
static void walk(const BundleElement &param, AttrTypeImmediateSubElementWalker &walker)