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