CIRCT 20.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/Interfaces/MemorySlotInterfaces.h"
20
21#include "circt/Support/LLVM.h"
22#include "mlir/IR/BuiltinTypes.h"
23#include "mlir/IR/Types.h"
24
25namespace circt {
26namespace hw {
27
28struct ModulePort {
30 mlir::StringAttr name;
31 mlir::Type type;
33};
34
35static bool operator==(const ModulePort &a, const ModulePort &b) {
36 return a.dir == b.dir && a.name == b.name && a.type == b.type;
37}
38static llvm::hash_code hash_value(const ModulePort &port) {
39 return llvm::hash_combine(port.dir, port.name, port.type);
40}
41
42namespace detail {
43struct ModuleTypeStorage : public TypeStorage {
44 ModuleTypeStorage(ArrayRef<ModulePort> inPorts);
45
46 using KeyTy = ArrayRef<ModulePort>;
47
48 /// Define the comparison function for the key type.
49 bool operator==(const KeyTy &key) const {
50 return std::equal(key.begin(), key.end(), ports.begin(), ports.end());
51 }
52
53 /// Define a hash function for the key type.
54 static llvm::hash_code hashKey(const KeyTy &key) {
55 return llvm::hash_combine_range(key.begin(), key.end());
56 }
57
58 /// Define a construction method for creating a new instance of this storage.
59 static ModuleTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
60 const KeyTy &key) {
61 return new (allocator.allocate<ModuleTypeStorage>()) ModuleTypeStorage(key);
62 }
63
64 /// Construct an instance of the key from this storage class.
65 KeyTy getAsKey() const { return ports; }
66
67 ArrayRef<ModulePort> getPorts() const { return ports; }
68
69 /// The parametric data held by the storage class.
70 SmallVector<ModulePort> ports;
71 // Cache of common lookups
72 SmallVector<size_t> inputToAbs;
73 SmallVector<size_t> outputToAbs;
74 SmallVector<size_t> absToInput;
75 SmallVector<size_t> absToOutput;
76};
77} // namespace detail
78
79class HWSymbolCache;
80class ParamDeclAttr;
81class TypedeclOp;
82class ModuleType;
83
84namespace detail {
85
86ModuleType fnToMod(Operation *op, ArrayRef<Attribute> inputNames,
87 ArrayRef<Attribute> outputNames);
88ModuleType fnToMod(FunctionType fn, ArrayRef<Attribute> inputNames,
89 ArrayRef<Attribute> outputNames);
90
91/// Struct defining a field. Used in structs.
92struct FieldInfo {
93 mlir::StringAttr name;
94 mlir::Type type;
95};
96
97/// Struct defining a field with an offset. Used in unions.
99 StringAttr name;
100 Type type;
101 size_t offset;
102};
103} // namespace detail
104} // namespace hw
105} // namespace circt
106
107#define GET_TYPEDEF_CLASSES
108#include "circt/Dialect/HW/HWTypes.h.inc"
109
110namespace circt {
111namespace hw {
112
113// Returns the canonical type of a HW type (inner type of a type alias).
114mlir::Type getCanonicalType(mlir::Type type);
115
116/// Return true if the specified type is a value HW Integer type. This checks
117/// that it is a signless standard dialect type.
118bool isHWIntegerType(mlir::Type type);
119
120/// Return true if the specified type is a HW Enum type.
121bool isHWEnumType(mlir::Type type);
122
123/// Return true if the specified type can be used as an HW value type, that is
124/// the set of types that can be composed together to represent synthesized,
125/// hardware but not marker types like InOutType or unknown types from other
126/// dialects.
127bool isHWValueType(mlir::Type type);
128
129/// Return the hardware bit width of a type. Does not reflect any encoding,
130/// padding, or storage scheme, just the bit (and wire width) of a
131/// statically-size type. Reflects the number of wires needed to transmit a
132/// value of this type. Returns -1 if the type is not known or cannot be
133/// statically computed.
134int64_t getBitWidth(mlir::Type type);
135
136/// Return true if the specified type contains known marker types like
137/// InOutType. Unlike isHWValueType, this is not conservative, it only returns
138/// false on known InOut types, rather than any unknown types.
139bool hasHWInOutType(mlir::Type type);
140
141template <typename... BaseTy>
142bool type_isa(Type type) {
143 // First check if the type is the requested type.
144 if (isa<BaseTy...>(type))
145 return true;
146
147 // Then check if it is a type alias wrapping the requested type.
148 if (auto alias = dyn_cast<TypeAliasType>(type))
149 return type_isa<BaseTy...>(alias.getInnerType());
150
151 return false;
152}
153
154// type_isa for a nullable argument.
155template <typename... BaseTy>
156bool type_isa_and_nonnull(Type type) { // NOLINT(readability-identifier-naming)
157 if (!type)
158 return false;
159 return type_isa<BaseTy...>(type);
160}
161
162template <typename BaseTy>
163BaseTy type_cast(Type type) {
164 assert(type_isa<BaseTy>(type) && "type must convert to requested type");
165
166 // If the type is the requested type, return it.
167 if (isa<BaseTy>(type))
168 return cast<BaseTy>(type);
169
170 // Otherwise, it must be a type alias wrapping the requested type.
171 return type_cast<BaseTy>(cast<TypeAliasType>(type).getInnerType());
172}
173
174template <typename BaseTy>
175BaseTy type_dyn_cast(Type type) {
176 if (!type_isa<BaseTy>(type))
177 return BaseTy();
178
179 return type_cast<BaseTy>(type);
180}
181
182/// Utility type that wraps a type that may be one of several possible Types.
183/// This is similar to std::variant but is implemented for mlir::Type, and it
184/// understands how to handle type aliases.
185template <typename... Types>
187 : public ::mlir::Type::TypeBase<TypeVariant<Types...>, mlir::Type,
188 mlir::TypeStorage> {
189 using mlir::Type::TypeBase<TypeVariant<Types...>, mlir::Type,
190 mlir::TypeStorage>::Base::Base;
191
192public:
193 // Support LLVM isa/cast/dyn_cast to one of the possible types.
194 static bool classof(Type other) { return type_isa<Types...>(other); }
195};
196
197template <typename BaseTy>
199 : public ::mlir::Type::TypeBase<TypeAliasOr<BaseTy>, mlir::Type,
200 mlir::TypeStorage> {
202 mlir::TypeStorage>::Base::Base;
203
204public:
205 // Support LLVM isa/cast/dyn_cast to BaseTy.
206 static bool classof(Type other) { return type_isa<BaseTy>(other); }
207
208 // Support C++ implicit conversions to BaseTy.
209 operator BaseTy() const { return type_cast<BaseTy>(*this); }
210};
211
212} // namespace hw
213} // namespace circt
214
215#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:206
Utility type that wraps a type that may be one of several possible Types.
Definition HWTypes.h:188
static bool classof(Type other)
Definition HWTypes.h:194
ModuleType fnToMod(Operation *op, ArrayRef< Attribute > inputNames, ArrayRef< Attribute > outputNames)
Definition HWTypes.cpp:1023
BaseTy type_cast(Type type)
Definition HWTypes.h:163
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:156
BaseTy type_dyn_cast(Type type)
Definition HWTypes.h:175
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:142
static bool operator==(const ModulePort &a, const ModulePort &b)
Definition HWTypes.h:35
static llvm::hash_code hash_value(const ModulePort &port)
Definition HWTypes.h:38
int64_t getBitWidth(mlir::Type type)
Return the hardware bit width of a type.
Definition HWTypes.cpp:110
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
mlir::Type type
Definition HWTypes.h:31
mlir::StringAttr name
Definition HWTypes.h:30
Struct defining a field. Used in structs.
Definition HWTypes.h:92
mlir::StringAttr name
Definition HWTypes.h:93
SmallVector< ModulePort > ports
The parametric data held by the storage class.
Definition HWTypes.h:70
static llvm::hash_code hashKey(const KeyTy &key)
Define a hash function for the key type.
Definition HWTypes.h:54
SmallVector< size_t > absToInput
Definition HWTypes.h:74
bool operator==(const KeyTy &key) const
Define the comparison function for the key type.
Definition HWTypes.h:49
SmallVector< size_t > outputToAbs
Definition HWTypes.h:73
SmallVector< size_t > inputToAbs
Definition HWTypes.h:72
ArrayRef< ModulePort > KeyTy
Definition HWTypes.h:46
static ModuleTypeStorage * construct(mlir::TypeStorageAllocator &allocator, const KeyTy &key)
Define a construction method for creating a new instance of this storage.
Definition HWTypes.h:59
ArrayRef< ModulePort > getPorts() const
Definition HWTypes.h:67
KeyTy getAsKey() const
Construct an instance of the key from this storage class.
Definition HWTypes.h:65
SmallVector< size_t > absToOutput
Definition HWTypes.h:75
Struct defining a field with an offset. Used in unions.
Definition HWTypes.h:98