CIRCT  20.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 #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 
25 namespace circt {
26 namespace hw {
27 
28 struct ModulePort {
30  mlir::StringAttr name;
31  mlir::Type type;
33 };
34 
35 static bool operator==(const ModulePort &a, const ModulePort &b) {
36  return a.dir == b.dir && a.name == b.name && a.type == b.type;
37 }
38 static llvm::hash_code hash_value(const ModulePort &port) {
39  return llvm::hash_combine(port.dir, port.name, port.type);
40 }
41 
42 namespace detail {
43 struct 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 
79 class HWSymbolCache;
80 class ParamDeclAttr;
81 class TypedeclOp;
82 class ModuleType;
83 
84 namespace detail {
85 
86 ModuleType fnToMod(Operation *op, ArrayRef<Attribute> inputNames,
87  ArrayRef<Attribute> outputNames);
88 ModuleType fnToMod(FunctionType fn, ArrayRef<Attribute> inputNames,
89  ArrayRef<Attribute> outputNames);
90 
91 /// Struct defining a field. Used in structs.
92 struct 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 
110 namespace circt {
111 namespace hw {
112 
113 // Returns the canonical type of a HW type (inner type of a type alias).
114 mlir::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.
118 bool isHWIntegerType(mlir::Type type);
119 
120 /// Return true if the specified type is a HW Enum type.
121 bool 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.
127 bool 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.
134 int64_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.
139 bool hasHWInOutType(mlir::Type type);
140 
141 template <typename... BaseTy>
142 bool 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.
155 template <typename... BaseTy>
156 bool type_isa_and_nonnull(Type type) { // NOLINT(readability-identifier-naming)
157  if (!type)
158  return false;
159  return type_isa<BaseTy...>(type);
160 }
161 
162 template <typename BaseTy>
163 BaseTy 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 
174 template <typename BaseTy>
175 BaseTy 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.
185 template <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 
192 public:
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 
197 template <typename BaseTy>
199  : public ::mlir::Type::TypeBase<TypeAliasOr<BaseTy>, mlir::Type,
200  mlir::TypeStorage> {
202  mlir::TypeStorage>::Base::Base;
203 
204 public:
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: DebugAnalysis.h:21
size_t hash_combine(size_t h1, size_t h2)
C++'s stdlib doesn't have a hash_combine function. This is a simple one.
Definition: Utils.h:32
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
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
SmallVector< ModulePort > ports
The parametric data held by the storage class.
Definition: HWTypes.h:70
ModuleTypeStorage(ArrayRef< ModulePort > inPorts)
Definition: HWTypes.cpp:1060
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
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