1 #ifndef MEMOIR_IR_TYPES_H
2 #define MEMOIR_IR_TYPES_H
7 #include "llvm/ADT/ArrayRef.h"
8 #include "llvm/IR/Function.h"
9 #include "llvm/IR/Instruction.h"
10 #include "llvm/IR/Instructions.h"
11 #include "llvm/IR/Module.h"
12 #include "llvm/Support/raw_ostream.h"
14 #include "memoir/support/Assert.hpp"
15 #include "memoir/support/DataTypes.hpp"
17 #include "memoir/utility/FunctionNames.hpp"
19 #include "memoir/ir/Instructions.hpp"
21 namespace llvm::memoir {
46 struct AssocArrayType;
49 struct DefineTupleTypeInst;
64 static IntegerType &get_size_type(
const llvm::DataLayout &DL);
70 static Type &define_type(std::string name,
Type &type);
71 static Type &lookup_type(std::string name);
72 static TupleType &get_tuple_type(llvm::ArrayRef<Type *> fields);
73 static ArrayType &get_array_type(
Type &element_type,
size_t length);
75 static Type &from_code(std::string code);
77 static bool is_primitive_type(
Type &type);
78 static bool is_reference_type(
Type &type);
79 static bool is_struct_type(
Type &type);
80 static bool is_collection_type(
Type &type);
81 static bool is_unsized(
Type &type);
82 static bool value_is_object(llvm::Value &value);
83 static bool value_is_collection_type(llvm::Value &value);
84 static bool value_is_struct_type(llvm::Value &value);
86 TypeKind getKind()
const;
89 virtual llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const;
91 virtual std::string toString(std::string indent =
"")
const = 0;
92 virtual Option<std::string> get_code()
const;
94 friend std::ostream &operator<<(std::ostream &os,
const Type &T);
95 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
const Type &T);
97 virtual bool operator==(
const Type &other)
const;
98 virtual bool operator<=(
const Type &other)
const;
100 virtual ~
Type() =
default;
111 template <
unsigned BW,
bool S>
115 unsigned getBitWidth()
const;
116 bool isSigned()
const;
119 static bool classof(
const Type *T) {
120 return (T->getKind() == TypeKind::INTEGER);
124 std::string toString(std::string indent =
"")
const override;
125 Option<std::string> get_code()
const override;
127 llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const override;
142 static bool classof(
const Type *T) {
143 return (T->getKind() == TypeKind::FLOAT);
146 std::string toString(std::string indent =
"")
const override;
147 Option<std::string> get_code()
const override;
149 llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const override;
159 static bool classof(
const Type *T) {
160 return (T->getKind() == TypeKind::DOUBLE);
163 std::string toString(std::string indent =
"")
const override;
164 Option<std::string> get_code()
const override;
166 llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const override;
176 static bool classof(
const Type *T) {
177 return (T->getKind() == TypeKind::POINTER);
180 std::string toString(std::string indent =
"")
const override;
181 Option<std::string> get_code()
const override;
183 llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const override;
193 static bool classof(
const Type *T) {
194 return (T->getKind() == TypeKind::VOID);
197 std::string toString(std::string indent =
"")
const override;
198 Option<std::string> get_code()
const override;
200 llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const override;
210 Type &getReferencedType()
const;
212 static bool classof(
const Type *T) {
213 return (T->getKind() == TypeKind::REFERENCE);
216 std::string toString(std::string indent =
"")
const override;
217 Option<std::string> get_code()
const override;
219 llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const override;
222 Type &referenced_type;
224 static Map<Type *, ReferenceType *> *reference_types;
231 static bool classof(
const Type *T) {
232 switch (T->getKind()) {
235 case TypeKind::TUPLE:
236 case TypeKind::ARRAY:
237 case TypeKind::SEQUENCE:
238 case TypeKind::ASSOC_ARRAY:
250 static TupleType &get(llvm::ArrayRef<Type *> field_types);
253 unsigned getNumFields()
const;
254 Type &getFieldType(
unsigned field)
const;
255 llvm::ArrayRef<Type *> fields()
const;
257 llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const override;
260 static bool classof(
const Type *T) {
261 return (T->getKind() == TypeKind::TUPLE);
265 std::string toString(std::string indent =
"")
const override;
266 Option<std::string> get_code()
const override;
269 Vector<Type *> field_types;
271 static OrderedMultiMap<unsigned, TupleType *> *tuple_types;
273 TupleType(llvm::ArrayRef<Type *> fields);
278 virtual Type &getElementType()
const = 0;
280 static bool classof(
const Type *T) {
281 switch (T->getKind()) {
284 case TypeKind::ARRAY:
285 case TypeKind::SEQUENCE:
286 case TypeKind::ASSOC_ARRAY:
291 Option<std::string> get_code()
const override;
293 virtual Option<std::string> get_selection()
const;
294 virtual CollectionType &set_selection(Option<std::string> selection);
296 llvm::Type *get_llvm_type(llvm::LLVMContext &C)
const override;
306 Type &getElementType()
const override;
307 size_t getLength()
const;
309 static bool classof(
const Type *T) {
310 return (T->getKind() == TypeKind::ARRAY);
313 std::string toString(std::string indent =
"")
const override;
321 static OrderedMultiMap<Type *, ArrayType *> *array_types;
328 std::optional<std::string> selection = {});
330 Type &getKeyType()
const;
331 Type &getValueType()
const;
332 Type &getElementType()
const override;
334 Option<std::string> get_selection()
const override;
335 CollectionType &set_selection(Option<std::string> selection)
override;
337 static bool classof(
const Type *T) {
338 return (T->getKind() == TypeKind::ASSOC_ARRAY);
341 std::string toString(std::string indent =
"")
const override;
343 Option<std::string> get_code()
const override;
345 bool operator<=(
const Type &other)
const override;
350 Option<std::string> selection;
357 static Types *assoc_array_types;
361 Option<std::string> selection = {});
368 std::optional<std::string> selection = {});
370 Type &getElementType()
const override;
372 static bool classof(
const Type *T) {
373 return (T->getKind() == TypeKind::SEQUENCE);
376 std::string toString(std::string indent =
"")
const override;
378 Option<std::string> get_code()
const override;
380 Option<std::string> get_selection()
const override;
381 CollectionType &set_selection(Option<std::string> selection)
override;
383 bool operator<=(
const Type &other)
const override;
387 Option<std::string> selection;
389 typedef OrderedMap<
Type *,
392 static Types *sequence_types;
402 using TypeID = uint64_t;
405 static TypeID
id = 0;
411 bool operator==(
Type &T)
const {
412 if (
auto *tvar = dyn_cast<TypeVariable>(&T)) {
413 return tvar->id == this->id;
420 static bool classof(
const Type *t) {
421 return (t->getKind() == TypeKind::VARIABLE);
424 std::string toString(std::string indent =
"")
const override {
425 return "typevar(" + std::to_string(this->
id) +
")";
440 Type *type_of(llvm::Value &V);
Definition: Types.hpp:302
Definition: Types.hpp:324
Definition: Types.hpp:276
Definition: Types.hpp:155
Definition: Types.hpp:138
Definition: Types.hpp:108
Definition: Instructions.hpp:31
Definition: Types.hpp:229
Definition: Types.hpp:172
Definition: Types.hpp:206
Definition: Types.hpp:365
Definition: Types.hpp:247
Definition: Types.hpp:400
Definition: Types.hpp:189