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