CIRCT  18.0.0git
HWTypes.h
Go to the documentation of this file.
1 //===- HWTypes.h - Types for the HW dialect ---------------------*- 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 // Types for the HW dialect are mostly in tablegen. This file should contain
10 // C++ types used in MLIR type parameters.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef CIRCT_DIALECT_HW_TYPES_H
15 #define CIRCT_DIALECT_HW_TYPES_H
16 
19 
20 #include "circt/Support/LLVM.h"
21 #include "mlir/IR/BuiltinTypes.h"
22 #include "mlir/IR/Types.h"
23 
24 namespace circt {
25 namespace hw {
26 
27 struct ModulePort {
29  mlir::StringAttr name;
30  mlir::Type type;
32 };
33 
34 class HWSymbolCache;
35 class ParamDeclAttr;
36 class TypedeclOp;
37 class ModuleType;
38 
39 namespace detail {
40 
41 ModuleType fnToMod(Operation *op, ArrayRef<Attribute> inputNames,
42  ArrayRef<Attribute> outputNames);
43 ModuleType fnToMod(FunctionType fn, ArrayRef<Attribute> inputNames,
44  ArrayRef<Attribute> outputNames);
45 
46 /// Struct defining a field. Used in structs.
47 struct FieldInfo {
48  mlir::StringAttr name;
49  mlir::Type type;
50 };
51 
52 /// Struct defining a field with an offset. Used in unions.
54  StringAttr name;
55  Type type;
56  size_t offset;
57 };
58 } // namespace detail
59 } // namespace hw
60 } // namespace circt
61 
62 #define GET_TYPEDEF_CLASSES
63 #include "circt/Dialect/HW/HWTypes.h.inc"
64 
65 namespace circt {
66 namespace hw {
67 
68 // Returns the canonical type of a HW type (inner type of a type alias).
69 mlir::Type getCanonicalType(mlir::Type type);
70 
71 /// Return true if the specified type is a value HW Integer type. This checks
72 /// that it is a signless standard dialect type.
73 bool isHWIntegerType(mlir::Type type);
74 
75 /// Return true if the specified type is a HW Enum type.
76 bool isHWEnumType(mlir::Type type);
77 
78 /// Return true if the specified type can be used as an HW value type, that is
79 /// the set of types that can be composed together to represent synthesized,
80 /// hardware but not marker types like InOutType or unknown types from other
81 /// dialects.
82 bool isHWValueType(mlir::Type type);
83 
84 /// Return the hardware bit width of a type. Does not reflect any encoding,
85 /// padding, or storage scheme, just the bit (and wire width) of a
86 /// statically-size type. Reflects the number of wires needed to transmit a
87 /// value of this type. Returns -1 if the type is not known or cannot be
88 /// statically computed.
89 int64_t getBitWidth(mlir::Type type);
90 
91 /// Return true if the specified type contains known marker types like
92 /// InOutType. Unlike isHWValueType, this is not conservative, it only returns
93 /// false on known InOut types, rather than any unknown types.
94 bool hasHWInOutType(mlir::Type type);
95 
96 template <typename... BaseTy>
97 bool type_isa(Type type) {
98  // First check if the type is the requested type.
99  if (type.isa<BaseTy...>())
100  return true;
101 
102  // Then check if it is a type alias wrapping the requested type.
103  if (auto alias = type.dyn_cast<TypeAliasType>())
104  return type_isa<BaseTy...>(alias.getInnerType());
105 
106  return false;
107 }
108 
109 // type_isa for a nullable argument.
110 template <typename... BaseTy>
111 bool type_isa_and_nonnull(Type type) { // NOLINT(readability-identifier-naming)
112  if (!type)
113  return false;
114  return type_isa<BaseTy...>(type);
115 }
116 
117 template <typename BaseTy>
118 BaseTy type_cast(Type type) {
119  assert(type_isa<BaseTy>(type) && "type must convert to requested type");
120 
121  // If the type is the requested type, return it.
122  if (type.isa<BaseTy>())
123  return type.cast<BaseTy>();
124 
125  // Otherwise, it must be a type alias wrapping the requested type.
126  return type_cast<BaseTy>(type.cast<TypeAliasType>().getInnerType());
127 }
128 
129 template <typename BaseTy>
130 BaseTy type_dyn_cast(Type type) {
131  if (!type_isa<BaseTy>(type))
132  return BaseTy();
133 
134  return type_cast<BaseTy>(type);
135 }
136 
137 /// Utility type that wraps a type that may be one of several possible Types.
138 /// This is similar to std::variant but is implemented for mlir::Type, and it
139 /// understands how to handle type aliases.
140 template <typename... Types>
142  : public ::mlir::Type::TypeBase<TypeVariant<Types...>, mlir::Type,
143  mlir::TypeStorage> {
144  using mlir::Type::TypeBase<TypeVariant<Types...>, mlir::Type,
145  mlir::TypeStorage>::Base::Base;
146 
147 public:
148  // Support LLVM isa/cast/dyn_cast to one of the possible types.
149  static bool classof(Type other) { return type_isa<Types...>(other); }
150 };
151 
152 template <typename BaseTy>
154  : public ::mlir::Type::TypeBase<TypeAliasOr<BaseTy>, mlir::Type,
155  mlir::TypeStorage> {
157  mlir::TypeStorage>::Base::Base;
158 
159 public:
160  // Support LLVM isa/cast/dyn_cast to BaseTy.
161  static bool classof(Type other) { return type_isa<BaseTy>(other); }
162 
163  // Support C++ implicit conversions to BaseTy.
164  operator BaseTy() const { return type_cast<BaseTy>(*this); }
165 };
166 
167 } // namespace hw
168 } // namespace circt
169 
170 #endif // CIRCT_DIALECT_HW_TYPES_H
assert(baseType &&"element must be base type")
This stores lookup tables to make manipulating and working with the IR more efficient.
Definition: HWSymCache.h:27
static bool classof(Type other)
Definition: HWTypes.h:161
Utility type that wraps a type that may be one of several possible Types.
Definition: HWTypes.h:143
static bool classof(Type other)
Definition: HWTypes.h:149
ModuleType fnToMod(Operation *op, ArrayRef< Attribute > inputNames, ArrayRef< Attribute > outputNames)
Definition: HWTypes.cpp:1091
BaseTy type_cast(Type type)
Definition: HWTypes.h:118
bool isHWIntegerType(mlir::Type type)
Return true if the specified type is a value HW Integer type.
Definition: HWTypes.cpp:52
bool type_isa_and_nonnull(Type type)
Definition: HWTypes.h:111
BaseTy type_dyn_cast(Type type)
Definition: HWTypes.h:130
bool isHWValueType(mlir::Type type)
Return true if the specified type can be used as an HW value type, that is the set of types that can ...
bool type_isa(Type type)
Definition: HWTypes.h:97
int64_t getBitWidth(mlir::Type type)
Return the hardware bit width of a type.
Definition: HWTypes.cpp:102
bool isHWEnumType(mlir::Type type)
Return true if the specified type is a HW Enum type.
Definition: HWTypes.cpp:65
mlir::Type getCanonicalType(mlir::Type type)
Definition: HWTypes.cpp:41
bool hasHWInOutType(mlir::Type type)
Return true if the specified type contains known marker types like InOutType.
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
Definition: DebugAnalysis.h:21
Definition: hw.py:1
mlir::Type type
Definition: HWTypes.h:30
mlir::StringAttr name
Definition: HWTypes.h:29
Struct defining a field. Used in structs.
Definition: HWTypes.h:47
mlir::StringAttr name
Definition: HWTypes.h:48
Struct defining a field with an offset. Used in unions.
Definition: HWTypes.h:53