CIRCT 24.0.0git
Loading...
Searching...
No Matches
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#include "mlir/IR/DialectInterface.h"
20#include "mlir/Interfaces/MemorySlotInterfaces.h"
21
22#include "circt/Support/LLVM.h"
23#include "mlir/IR/AttrTypeSubElements.h"
24#include "mlir/IR/BuiltinTypes.h"
25#include "mlir/IR/Types.h"
26
27namespace circt {
28namespace hw {
29
30struct ModulePort {
32 mlir::StringAttr name;
33 mlir::Type type;
35};
36
38 : public mlir::DialectInterface::Base<HWModulePortTypeInterface> {
39 HWModulePortTypeInterface(mlir::Dialect *dialect) : Base(dialect) {}
40
41 /// Return failure if `type` is not valid for a module port with the given
42 /// direction. Dialects can implement this to restrict non-HW-value handle
43 /// types in HW module signatures.
44 virtual mlir::LogicalResult verifyHWModulePortType(
45 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
46 ModulePort::Direction direction, mlir::Type type) const {
47 return mlir::success();
48 }
49};
50
51/// Interface for dialects to classify their types as valid probe payloads.
53 : public mlir::DialectInterface::Base<ProbeTypeDialectInterface> {
54 ProbeTypeDialectInterface(mlir::Dialect *dialect) : Base(dialect) {}
55
56 virtual bool isValidProbeElementType(mlir::Type type) const = 0;
57};
58
59/// Return true if `type` is a valid probe payload. Builtin integer types are
60/// always valid; other types are classified by their owning dialect.
61bool isValidProbeElementType(mlir::Type type);
62
63static bool operator==(const ModulePort &a, const ModulePort &b) {
64 return a.dir == b.dir && a.name == b.name && a.type == b.type;
65}
66static llvm::hash_code hash_value(const ModulePort &port) {
67 return llvm::hash_combine(port.dir, port.name, port.type);
68}
69
70namespace detail {
71struct ModuleTypeStorage : public TypeStorage {
72 ModuleTypeStorage(ArrayRef<ModulePort> inPorts);
73
74 using KeyTy = ArrayRef<ModulePort>;
75
76 /// Define the comparison function for the key type.
77 bool operator==(const KeyTy &key) const {
78 return std::equal(key.begin(), key.end(), ports.begin(), ports.end());
79 }
80
81 /// Define a hash function for the key type.
82 static llvm::hash_code hashKey(const KeyTy &key) {
83 return llvm::hash_combine_range(key.begin(), key.end());
84 }
85
86 /// Define a construction method for creating a new instance of this storage.
87 static ModuleTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
88 const KeyTy &key) {
89 return new (allocator.allocate<ModuleTypeStorage>()) ModuleTypeStorage(key);
90 }
91
92 /// Construct an instance of the key from this storage class.
93 KeyTy getAsKey() const { return ports; }
94
95 ArrayRef<ModulePort> getPorts() const { return ports; }
96
97 /// The parametric data held by the storage class.
98 SmallVector<ModulePort> ports;
99 // Cache of common lookups
100 SmallVector<size_t> inputToAbs;
101 SmallVector<size_t> outputToAbs;
102 SmallVector<size_t> absToInput;
103 SmallVector<size_t> absToOutput;
104};
105} // namespace detail
106
107class HWSymbolCache;
108class ParamDeclAttr;
109class TypedeclOp;
110class ModuleType;
111
112namespace detail {
113
114ModuleType fnToMod(Operation *op, ArrayRef<Attribute> inputNames,
115 ArrayRef<Attribute> outputNames);
116ModuleType fnToMod(FunctionType fn, ArrayRef<Attribute> inputNames,
117 ArrayRef<Attribute> outputNames);
118
119/// Struct defining a field. Used in structs.
120struct FieldInfo {
121 mlir::StringAttr name;
122 mlir::Type type;
123};
124
125/// Struct defining a field with an offset. Used in unions.
127 StringAttr name;
128 Type type;
129 size_t offset;
130};
131} // namespace detail
132} // namespace hw
133} // namespace circt
134
135namespace mlir {
136/// Expose the field names and types of struct and union types to the generic
137/// attribute and type walking and replacement infrastructure. This allows
138/// walkers to recurse into the fields of `!hw.struct` and `!hw.union` types,
139/// and replacers such as `mlir::AttrTypeReplacer` to replace types nested
140/// within the fields.
141template <>
142struct AttrTypeSubElementHandler<circt::hw::detail::FieldInfo> {
143 static void walk(const circt::hw::detail::FieldInfo &param,
144 AttrTypeImmediateSubElementWalker &walker) {
145 walker.walk(param.name);
146 walker.walk(param.type);
147 }
150 AttrSubElementReplacements &attrRepls,
151 TypeSubElementReplacements &typeRepls) {
152 return {cast<StringAttr>(attrRepls.take_front(1)[0]),
153 typeRepls.take_front(1)[0]};
154 }
155};
156template <>
157struct AttrTypeSubElementHandler<circt::hw::detail::OffsetFieldInfo> {
158 static void walk(const circt::hw::detail::OffsetFieldInfo &param,
159 AttrTypeImmediateSubElementWalker &walker) {
160 walker.walk(param.name);
161 walker.walk(param.type);
162 }
165 AttrSubElementReplacements &attrRepls,
166 TypeSubElementReplacements &typeRepls) {
167 return {cast<StringAttr>(attrRepls.take_front(1)[0]),
168 typeRepls.take_front(1)[0], param.offset};
169 }
170};
171} // namespace mlir
172
173#define GET_TYPEDEF_CLASSES
174#include "circt/Dialect/HW/HWTypes.h.inc"
175
176namespace circt {
177namespace hw {
178
179// Returns the canonical type of a HW type (inner type of a type alias).
180mlir::Type getCanonicalType(mlir::Type type);
181
182/// Return true if the specified type is a value HW Integer type. This checks
183/// that it is a signless standard dialect type.
184bool isHWIntegerType(mlir::Type type);
185
186/// Return true if the specified type is a HW Enum type.
187bool isHWEnumType(mlir::Type type);
188
189/// Return true if the specified type can be used as an HW value type, that is
190/// the set of types that can be composed together to represent synthesized,
191/// hardware but not marker types like InOutType or unknown types from other
192/// dialects.
193bool isHWValueType(mlir::Type type);
194
195/// Return the hardware bit width of a type. Does not reflect any encoding,
196/// padding, or storage scheme, just the bit (and wire width) of a
197/// statically-size type. Reflects the number of wires needed to transmit a
198/// value of this type. Returns -1 if the type is not known or cannot be
199/// statically computed.
200int64_t getBitWidth(mlir::Type type);
201
202/// Return true if the specified type contains known marker types like
203/// InOutType. Unlike isHWValueType, this is not conservative, it only returns
204/// false on known InOut types, rather than any unknown types.
205bool hasHWInOutType(mlir::Type type);
206
207/// Convert an APInt value into a nested aggregate attribute matching the given
208/// HWAggregateType. Returns failure() if the type is not an HWAggregateType or
209/// recursively contains a type other than HWAggregateType or IntegerType.
210LogicalResult apIntToAggregateAttr(mlir::Type aggregateType,
211 const APInt &intVal, ArrayAttr &result);
212
213/// Convert an ArrayAttr into an APInt value matching the given type.
214/// The type is used to determine the bit width of the resulting APInt.
215/// Returns failure() if the attribute recursively contains anything other than
216/// ArrayAttr or IntegerAttr.
217LogicalResult aggregateAttrToAPInt(mlir::Type type, ArrayAttr attr,
218 APInt &result);
219
220template <typename... BaseTy>
221bool type_isa(Type type) {
222 // First check if the type is the requested type.
223 if (isa<BaseTy...>(type))
224 return true;
225
226 // Then check if it is a type alias wrapping the requested type.
227 if (auto alias = dyn_cast<TypeAliasType>(type))
228 return type_isa<BaseTy...>(alias.getInnerType());
229
230 return false;
231}
232
233// type_isa for a nullable argument.
234template <typename... BaseTy>
235bool type_isa_and_nonnull(Type type) { // NOLINT(readability-identifier-naming)
236 if (!type)
237 return false;
238 return type_isa<BaseTy...>(type);
239}
240
241template <typename BaseTy>
242BaseTy type_cast(Type type) {
243 assert(type_isa<BaseTy>(type) && "type must convert to requested type");
244
245 // If the type is the requested type, return it.
246 if (isa<BaseTy>(type))
247 return cast<BaseTy>(type);
248
249 // Otherwise, it must be a type alias wrapping the requested type.
250 return type_cast<BaseTy>(cast<TypeAliasType>(type).getInnerType());
251}
252
253template <typename BaseTy>
254BaseTy type_dyn_cast(Type type) {
255 if (!type_isa<BaseTy>(type))
256 return BaseTy();
257
258 return type_cast<BaseTy>(type);
259}
260
261/// Utility type that wraps a type that may be one of several possible Types.
262/// This is similar to std::variant but is implemented for mlir::Type, and it
263/// understands how to handle type aliases.
264template <typename... Types>
266 : public ::mlir::Type::TypeBase<TypeVariant<Types...>, mlir::Type,
267 mlir::TypeStorage> {
268 using mlir::Type::TypeBase<TypeVariant<Types...>, mlir::Type,
269 mlir::TypeStorage>::Base::Base;
270
271public:
272 // Support LLVM isa/cast/dyn_cast to one of the possible types.
273 static bool classof(Type other) { return type_isa<Types...>(other); }
274};
275
276template <typename BaseTy>
278 : public ::mlir::Type::TypeBase<TypeAliasOr<BaseTy>, mlir::Type,
279 mlir::TypeStorage> {
281 mlir::TypeStorage>::Base::Base;
282
283public:
284 // Support LLVM isa/cast/dyn_cast to BaseTy.
285 static bool classof(Type other) { return type_isa<BaseTy>(other); }
286
287 // Support C++ implicit conversions to BaseTy.
288 operator BaseTy() const { return type_cast<BaseTy>(*this); }
289};
290
291} // namespace hw
292} // namespace circt
293
294#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:28
static bool classof(Type other)
Definition HWTypes.h:285
Utility type that wraps a type that may be one of several possible Types.
Definition HWTypes.h:267
static bool classof(Type other)
Definition HWTypes.h:273
ModuleType fnToMod(Operation *op, ArrayRef< Attribute > inputNames, ArrayRef< Attribute > outputNames)
Definition HWTypes.cpp:1176
BaseTy type_cast(Type type)
Definition HWTypes.h:242
bool isHWIntegerType(mlir::Type type)
Return true if the specified type is a value HW Integer type.
Definition HWTypes.cpp:60
bool type_isa_and_nonnull(Type type)
Definition HWTypes.h:235
BaseTy type_dyn_cast(Type type)
Definition HWTypes.h:254
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:221
static bool operator==(const ModulePort &a, const ModulePort &b)
Definition HWTypes.h:63
static llvm::hash_code hash_value(const ModulePort &port)
Definition HWTypes.h:66
bool isValidProbeElementType(mlir::Type type)
Return true if type is a valid probe payload.
LogicalResult aggregateAttrToAPInt(mlir::Type type, ArrayAttr attr, APInt &result)
Convert an ArrayAttr into an APInt value matching the given type.
int64_t getBitWidth(mlir::Type type)
Return the hardware bit width of a type.
Definition HWTypes.cpp:122
LogicalResult apIntToAggregateAttr(mlir::Type aggregateType, const APInt &intVal, ArrayAttr &result)
Convert an APInt value into a nested aggregate attribute matching the given HWAggregateType.
bool isHWEnumType(mlir::Type type)
Return true if the specified type is a HW Enum type.
Definition HWTypes.cpp:73
mlir::Type getCanonicalType(mlir::Type type)
Definition HWTypes.cpp:49
bool hasHWInOutType(mlir::Type type)
Return true if the specified type contains known marker types like InOutType.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition hw.py:1
virtual mlir::LogicalResult verifyHWModulePortType(llvm::function_ref< mlir::InFlightDiagnostic()> emitError, ModulePort::Direction direction, mlir::Type type) const
Return failure if type is not valid for a module port with the given direction.
Definition HWTypes.h:44
HWModulePortTypeInterface(mlir::Dialect *dialect)
Definition HWTypes.h:39
mlir::Type type
Definition HWTypes.h:33
mlir::StringAttr name
Definition HWTypes.h:32
Interface for dialects to classify their types as valid probe payloads.
Definition HWTypes.h:53
virtual bool isValidProbeElementType(mlir::Type type) const =0
ProbeTypeDialectInterface(mlir::Dialect *dialect)
Definition HWTypes.h:54
Struct defining a field. Used in structs.
Definition HWTypes.h:120
mlir::StringAttr name
Definition HWTypes.h:121
SmallVector< ModulePort > ports
The parametric data held by the storage class.
Definition HWTypes.h:98
static llvm::hash_code hashKey(const KeyTy &key)
Define a hash function for the key type.
Definition HWTypes.h:82
SmallVector< size_t > absToInput
Definition HWTypes.h:102
bool operator==(const KeyTy &key) const
Define the comparison function for the key type.
Definition HWTypes.h:77
SmallVector< size_t > outputToAbs
Definition HWTypes.h:101
SmallVector< size_t > inputToAbs
Definition HWTypes.h:100
ArrayRef< ModulePort > KeyTy
Definition HWTypes.h:74
static ModuleTypeStorage * construct(mlir::TypeStorageAllocator &allocator, const KeyTy &key)
Define a construction method for creating a new instance of this storage.
Definition HWTypes.h:87
ArrayRef< ModulePort > getPorts() const
Definition HWTypes.h:95
KeyTy getAsKey() const
Construct an instance of the key from this storage class.
Definition HWTypes.h:93
SmallVector< size_t > absToOutput
Definition HWTypes.h:103
Struct defining a field with an offset. Used in unions.
Definition HWTypes.h:126
static void walk(const circt::hw::detail::FieldInfo &param, AttrTypeImmediateSubElementWalker &walker)
Definition HWTypes.h:143
static circt::hw::detail::FieldInfo replace(const circt::hw::detail::FieldInfo &param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
Definition HWTypes.h:149
static void walk(const circt::hw::detail::OffsetFieldInfo &param, AttrTypeImmediateSubElementWalker &walker)
Definition HWTypes.h:158
static circt::hw::detail::OffsetFieldInfo replace(const circt::hw::detail::OffsetFieldInfo &param, AttrSubElementReplacements &attrRepls, TypeSubElementReplacements &typeRepls)
Definition HWTypes.h:164