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/TypeSwitch.h"
28 struct FIRRTLBaseTypeStorage;
29 struct WidthTypeStorage;
30 struct BundleTypeStorage;
31 struct FVectorTypeStorage;
32 struct FEnumTypeStorage;
33 struct CMemoryTypeStorage;
34 struct RefTypeStorage;
35 struct BaseTypeAliasStorage;
36 struct OpenBundleTypeStorage;
37 struct OpenVectorTypeStorage;
38 struct ClassTypeStorage;
62 class BaseTypeAliasType;
87 return llvm::isa<FIRRTLDialect>(type.getDialect());
141 :
public FIRRTLType::TypeBase<FIRRTLBaseType, FIRRTLType,
142 detail::FIRRTLBaseTypeStorage> {
152 bool isPassive()
const {
return getRecursiveTypeProperties().isPassive; }
184 return llvm::isa<FIRRTLDialect>(type.getDialect()) &&
185 !llvm::isa<PropertyType, RefType, OpenBundleType, OpenVectorType>(
211 bool destOuterTypeIsConst =
false,
212 bool srcOuterTypeIsConst =
false,
213 bool requireSameWidths =
false);
220 bool destFlip =
false,
bool srcFlip =
false,
221 bool destOuterTypeIsConst =
false,
222 bool srcOuterTypeIsConst =
false);
226 bool srcOuterTypeIsConst =
false);
240 bool isTypeLarger(FIRRTLBaseType dstType, FIRRTLBaseType srcType);
264 template <
typename ConcreteType>
266 :
public mlir::TypeTrait::TraitBase<ConcreteType, WidthQualifiedTypeTrait> {
271 auto width =
static_cast<const ConcreteType *
>(
this)->getWidthOrSentinel();
279 return 0 <=
static_cast<const ConcreteType *
>(
this)->getWidthOrSentinel();
293 using FIRRTLBaseType::FIRRTLBaseType;
298 int32_t widthOrSentinel = -1,
bool isConst =
false);
309 static bool classof(Type type) {
return llvm::isa<SIntType, UIntType>(type); }
320 return llvm::isa<AnyRefType, ClassType, StringType, FIntegerType, ListType,
321 PathType, BoolType, DoubleType>(type);
325 using FIRRTLType::FIRRTLType;
377 std::optional<int64_t>
getBitWidth(FIRRTLBaseType type,
378 bool ignoreFlip =
false);
396 #define GET_TYPEDEF_CLASSES
397 #include "circt/Dialect/FIRRTL/FIRRTLTypes.h.inc"
403 struct DenseMapInfo<
circt::firrtl::FIRRTLType> {
406 auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
407 return FIRRTLType(
static_cast<mlir::Type::ImplType *
>(pointer));
410 auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
411 return FIRRTLType(
static_cast<mlir::Type::ImplType *
>(pointer));
429 template <
typename head,
typename... tail>
436 template <
typename BaseTy>
438 static constexpr
bool isFIRRTLBaseType =
440 !std::is_same_v<FIRRTLBaseType, BaseTy>;
441 static constexpr
bool isFIRRTLType =
445 static constexpr
bool value = isFIRRTLBaseType || !isFIRRTLType;
448 template <
typename...
BaseTy>
451 if (isa<BaseTy...>(type))
457 if (
auto alias = dyn_cast<BaseTypeAliasType>(type))
465 template <
typename...
BaseTy>
472 template <
typename BaseTy>
474 assert(type_isa<BaseTy>(type) &&
"type must convert to requested type");
477 if (isa<BaseTy>(type))
478 return cast<BaseTy>(type);
482 if (
auto alias = dyn_cast<BaseTypeAliasType>(type))
483 return type_cast<BaseTy>(alias.getInnerType());
488 return cast<BaseTy>(type);
491 template <
typename BaseTy>
493 if (type_isa<BaseTy>(type))
494 return type_cast<BaseTy>(type);
498 template <
typename BaseTy>
501 if (type_isa_and_nonnull<BaseTy>(type))
502 return type_cast<BaseTy>(type);
513 template <
typename T,
typename ResultT =
void>
523 template <
typename CaseT,
typename CallableT>
530 if (
auto caseValue = circt::firrtl::type_dyn_cast<CaseT>(this->
value))
531 result.emplace(caseFn(caseValue));
536 template <
typename CallableT>
537 [[nodiscard]] ResultT
540 return std::move(*
result);
541 return defaultFn(this->
value);
545 [[nodiscard]] ResultT
548 return std::move(*
result);
549 return defaultResult;
552 [[nodiscard]]
operator ResultT() {
554 return std::move(*
result);
564 template <
typename T>
574 template <
typename CaseT,
typename CallableT>
581 if (
auto caseValue = circt::firrtl::type_dyn_cast<CaseT>(this->
value)) {
589 template <
typename CallableT>
592 defaultFn(this->
value);
597 bool foundMatch =
false;
600 template <
typename BaseTy>
603 firrtl::FIRRTLBaseType,
604 detail::FIRRTLBaseTypeStorage> {
610 static bool classof(Type other) {
return type_isa<BaseTy>(other); }
613 operator BaseTy()
const {
return circt::firrtl::type_cast<BaseTy>(*
this); }
615 BaseTy get()
const {
return circt::firrtl::type_cast<BaseTy>(*
this); }
assert(baseType &&"element must be base type")
static bool classof(Type other)
A struct to check if there is a type derived from FIRRTLBaseType.
static constexpr bool value
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...
bool isConst()
Returns true if this is a 'const' type that can only hold compile-time constant values.
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 getConstType(bool isConst)
Return a 'const' or non-'const' version of this type.
FIRRTLBaseType getWidthlessType()
Return this type with widths of all ground types removed.
Specialization of FIRRTLTypeSwitch for void returning callables.
FIRRTLTypeSwitch< T, void > & Case(CallableT &&caseFn)
Add a case on the given type.
void Default(CallableT &&defaultFn)
As a default, invoke the given callable within the root value.
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.
bool isConst()
Returns true if this is a 'const' type that can only hold compile-time constant values.
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 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.
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.
IntType getConstType(bool isConst)
Return a 'const' or non-'const' version of this type.
static bool classof(Type type)
Support method to enable LLVM-style type casting.
Trait for types which have a width.
std::optional< int32_t > getWidth() const
Return an optional containing the width, if the width is known (or empty if width is unknown).
bool hasWidth() const
Return true if this integer type has a known width.
BaseTy type_cast(Type type)
Direction
This represents the direction of a single port.
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
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.
ParseResult parseNestedPropertyType(PropertyType &result, AsmParser &parser)
std::optional< int64_t > getBitWidth(FIRRTLBaseType type, bool ignoreFlip=false)
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
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 FIRRTLType getTombstoneKey()
static FIRRTLType getEmptyKey()
static unsigned getHashValue(FIRRTLType val)
static bool isEqual(FIRRTLType LHS, FIRRTLType RHS)