13#ifndef CIRCT_DIALECT_FIRRTL_TYPES_H
14#define CIRCT_DIALECT_FIRRTL_TYPES_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"
34struct CMemoryTypeStorage;
41struct DomainTypeStorage;
68class BaseTypeAliasType;
96 return llvm::isa<FIRRTLDialect>(type.getDialect());
150 :
public FIRRTLType::TypeBase<FIRRTLBaseType, FIRRTLType,
151 detail::FIRRTLBaseTypeStorage> {
161 bool isPassive()
const {
return getRecursiveTypeProperties().isPassive; }
193 return llvm::isa<FIRRTLDialect>(type.getDialect()) &&
194 !llvm::isa<
PropertyType, RefType, LHSType, OpenBundleType,
195 OpenVectorType, FStringType, DomainType>(type);
223 bool destOuterTypeIsConst =
false,
224 bool srcOuterTypeIsConst =
false,
225 bool requireSameWidths =
false);
232 bool destFlip =
false,
bool srcFlip =
false,
233 bool destOuterTypeIsConst =
false,
234 bool srcOuterTypeIsConst =
false);
238 bool srcOuterTypeIsConst =
false);
279template <
typename ConcreteType>
281 :
public mlir::TypeTrait::TraitBase<ConcreteType, WidthQualifiedTypeTrait> {
286 auto width =
static_cast<const ConcreteType *
>(
this)->getWidthOrSentinel();
294 return 0 <=
static_cast<const ConcreteType *
>(
this)->getWidthOrSentinel();
308 using FIRRTLBaseType::FIRRTLBaseType;
313 int32_t widthOrSentinel = -1,
bool isConst =
false);
315 bool isSigned() {
return mlir::isa<SIntType>(*
this); }
324 static bool classof(Type type) {
return mlir::isa<SIntType, UIntType>(type); }
335 return llvm::isa<AnyRefType, ClassType, StringType, FIntegerType, ListType,
336 RegistryType, PathType, BoolType, DoubleType>(type);
340 using FIRRTLType::FIRRTLType;
392std::optional<int64_t>
getBitWidth(FIRRTLBaseType type,
393 bool ignoreFlip =
false);
411#define GET_TYPEDEF_CLASSES
412#include "circt/Dialect/FIRRTL/FIRRTLTypes.h.inc"
436template <
typename head,
typename... tail>
443template <
typename BaseTy>
446 std::is_base_of<FIRRTLBaseType, BaseTy>::value &&
447 !std::is_same_v<FIRRTLBaseType, BaseTy>;
449 std::is_base_of<FIRRTLType, BaseTy>::value;
455template <
typename... BaseTy>
458 if (isa<BaseTy...>(type))
464 if (
auto alias = dyn_cast<BaseTypeAliasType>(type))
465 return type_isa<BaseTy...>(alias.getInnerType());
472template <
typename... BaseTy>
479template <
typename BaseTy>
484 if (isa<BaseTy>(type))
485 return cast<BaseTy>(type);
489 if (
auto alias = dyn_cast<BaseTypeAliasType>(type))
495 return cast<BaseTy>(type);
498template <
typename BaseTy>
505template <
typename BaseTy>
520template <
typename T,
typename ResultT =
void>
522 :
public llvm::detail::TypeSwitchBase<FIRRTLTypeSwitch<T, ResultT>, T> {
524 using BaseT = llvm::detail::TypeSwitchBase<FIRRTLTypeSwitch<T, ResultT>, T>;
530 template <
typename CaseT,
typename CallableT>
538 result.emplace(caseFn(caseValue));
543 template <
typename CallableT>
544 [[nodiscard]] ResultT
547 return std::move(*
result);
548 return defaultFn(this->value);
552 [[nodiscard]] ResultT
555 return std::move(*
result);
556 return defaultResult;
559 [[nodiscard]]
operator ResultT() {
561 return std::move(*
result);
573 :
public llvm::detail::TypeSwitchBase<FIRRTLTypeSwitch<T, void>, T> {
575 using BaseT = llvm::detail::TypeSwitchBase<FIRRTLTypeSwitch<T, void>, T>;
581 template <
typename CaseT,
typename CallableT>
596 template <
typename CallableT>
599 defaultFn(this->value);
607template <
typename BaseTy>
610 firrtl::FIRRTLBaseType,
611 detail::FIRRTLBaseTypeStorage> {
634struct mlir::AttrTypeSubElementHandler<
circt::firrtl::ClassElement> {
638 AttrTypeImmediateSubElementWalker &walker) {
639 walker.walk(param.
name);
640 walker.walk(param.
type);
643 AttrSubElementReplacements &attrRepls,
644 TypeSubElementReplacements &typeRepls) {
645 return ClassElement(cast<StringAttr>(attrRepls.take_front(1)[0]),
646 typeRepls.take_front(1)[0], param.
direction);
652struct mlir::AttrTypeSubElementHandler<
653 circt::firrtl::BundleType::BundleElement> {
657 AttrTypeImmediateSubElementWalker &walker) {
658 walker.walk(param.name);
659 walker.walk(param.type);
662 AttrSubElementReplacements &attrRepls,
663 TypeSubElementReplacements &typeRepls) {
665 cast<StringAttr>(attrRepls.take_front(1)[0]), param.isFlip,
666 cast<circt::firrtl::FIRRTLBaseType>(typeRepls.take_front(1)[0]));
672struct mlir::AttrTypeSubElementHandler<
673 circt::firrtl::OpenBundleType::BundleElement> {
677 AttrTypeImmediateSubElementWalker &walker) {
678 walker.walk(param.name);
679 walker.walk(param.type);
682 AttrSubElementReplacements &attrRepls,
683 TypeSubElementReplacements &typeRepls) {
685 cast<StringAttr>(attrRepls.take_front(1)[0]), param.isFlip,
686 cast<circt::firrtl::FIRRTLType>(typeRepls.take_front(1)[0]));
692struct mlir::AttrTypeSubElementHandler<
circt::firrtl::FEnumType::EnumElement> {
696 AttrTypeImmediateSubElementWalker &walker) {
697 walker.walk(param.name);
698 walker.walk(param.value);
699 walker.walk(param.type);
702 AttrSubElementReplacements &attrRepls,
703 TypeSubElementReplacements &typeRepls) {
704 auto attrs = attrRepls.take_front(2);
706 cast<StringAttr>(
attrs[0]), cast<IntegerAttr>(
attrs[1]),
707 cast<circt::firrtl::FIRRTLBaseType>(typeRepls.take_front(1)[0]));
assert(baseType &&"element must be base type")
static std::unique_ptr< Context > context
static bool classof(Type other)
static constexpr bool value
static constexpr bool isFIRRTLType
static constexpr bool isFIRRTLBaseType
A struct to check if there is a type derived from FIRRTLBaseType.
static constexpr bool value
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.
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.
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
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.
bool containsReference
Whether the type contains a reference type.
bool isPassive
Whether the type only contains passive elements.
bool containsAnalog
Whether the type contains an analog type.
bool hasUninferredReset
Whether the type has any uninferred reset.
bool containsTypeAlias
Whether the type contains a type alias.
bool containsConst
Whether the type contains a const type.
bool hasUninferredWidth
Whether the type has any uninferred bit widths.
static unsigned getHashValue(FIRRTLType val)
static bool isEqual(FIRRTLType LHS, FIRRTLType RHS)
circt::firrtl::FIRRTLType FIRRTLType
static BundleElement replace(const BundleElement ¶m, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
circt::firrtl::BundleType::BundleElement BundleElement
static void walk(const BundleElement ¶m, AttrTypeImmediateSubElementWalker &walker)
static ClassElement replace(ClassElement param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
circt::firrtl::ClassElement ClassElement
static void walk(ClassElement param, AttrTypeImmediateSubElementWalker &walker)
circt::firrtl::FEnumType::EnumElement EnumElement
static void walk(const EnumElement ¶m, AttrTypeImmediateSubElementWalker &walker)
static EnumElement replace(const EnumElement ¶m, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
static BundleElement replace(const BundleElement ¶m, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
circt::firrtl::OpenBundleType::BundleElement BundleElement
static void walk(const BundleElement ¶m, AttrTypeImmediateSubElementWalker &walker)