-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathLLVMTypeUtils.cpp
144 lines (109 loc) · 3.89 KB
/
LLVMTypeUtils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*=====================================================================
LLVMTypeUtils.cpp
-------------------
Copyright Glare Technologies Limited 2018 -
Generated at Wed Oct 20 15:22:37 +1300 2010
=====================================================================*/
#include "LLVMTypeUtils.h"
#include "wnt_ASTNode.h"
#ifdef _MSC_VER // If compiling with Visual C++
#pragma warning(push, 0) // Disable warnings
#endif
#include "llvm/IR/Module.h"
#include <llvm/IR/DataLayout.h>
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/IPO.h"
#include <llvm/IR/IRBuilder.h>
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#ifdef _MSC_VER
#pragma warning(pop) // Re-enable warnings
#endif
using std::vector;
namespace Winter
{
namespace LLVMTypeUtils
{
llvm::Type* pointerType(llvm::Type& type)
{
return llvm::PointerType::get(
&type,
0 // AddressSpace
);
}
llvm::Type* pointerType(llvm::Type* type)
{
return llvm::PointerType::get(
type,
0 // AddressSpace
);
}
llvm::Type* voidPtrType(llvm::LLVMContext& context)
{
// Not sure if LLVM has a pointer to void type, so just use a pointer to int32.
return llvm::Type::getInt32PtrTy(context);
}
llvm::Type* getBaseCapturedVarStructType(llvm::Module& module)
{
const std::string struct_name = "base_captured_var_struct";
llvm::StructType* existing_struct_type = getStructureTypeForName(struct_name, module);
if(existing_struct_type)
return existing_struct_type;
std::vector<llvm::Type*> elements;
//elements.push_back(llvm::Type::getIntNTy(module.getContext(), 64)); // Dummy struct member
return llvm::StructType::create(
module.getContext(),
elements, // elements
struct_name
);
}
llvm::Type* getPtrToBaseCapturedVarStructType(llvm::Module& module)
{
return pointerType(*getBaseCapturedVarStructType(module));
}
llvm::StructType* getStructureTypeForName(const std::string& name, llvm::Module& module)
{
#if TARGET_LLVM_VERSION >= 150
return llvm::StructType::getTypeByName(module.getContext(), name);
#else
return module.getTypeByName(name);
#endif
}
llvm::FunctionType* llvmFunctionType(const vector<TypeVRef>& arg_types,
bool captured_var_struct_ptr_arg,
TypeVRef return_type,
llvm::Module& module)
{
if(return_type->passByValue())
{
llvm::SmallVector<llvm::Type*, 8> llvm_arg_types((unsigned int)arg_types.size());
for(unsigned int i=0; i<arg_types.size(); ++i)
llvm_arg_types[i] = arg_types[i]->passByValue() ? arg_types[i]->LLVMType(module) : LLVMTypeUtils::pointerType(*arg_types[i]->LLVMType(module));
if(captured_var_struct_ptr_arg)
llvm_arg_types.push_back(getPtrToBaseCapturedVarStructType(module));
return llvm::FunctionType::get(
return_type->LLVMType(module), // return type
llvm_arg_types,
false // varargs
);
}
else
{
// The return value is passed by reference, so that means the zero-th argument will be a pointer to memory where the return value will be placed (SRET).
llvm::SmallVector<llvm::Type*, 8> llvm_arg_types(1 + (unsigned int)arg_types.size());
llvm_arg_types[0] = LLVMTypeUtils::pointerType(*return_type->LLVMType(module)); // Arg 0 is SRET arg.
// Set normal arguments
for(unsigned int i=0; i<arg_types.size(); ++i)
llvm_arg_types[i + 1] = arg_types[i]->passByValue() ? arg_types[i]->LLVMType(module) : LLVMTypeUtils::pointerType(*arg_types[i]->LLVMType(module));
if(captured_var_struct_ptr_arg)
llvm_arg_types.push_back(getPtrToBaseCapturedVarStructType(module));
return llvm::FunctionType::get(
llvm::Type::getVoidTy(module.getContext()), // return type - void as return value will be written to mem via zero-th arg.
llvm_arg_types,
false // varargs
);
}
}
}; // end namespace LLVMTypeUtils
}; // end namespace Winter