Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
numba
GitHub Repository: numba/llvmlite
Path: blob/main/ffi/targets.cpp
1154 views
1
#include "core.h"
2
#include "llvm-c/Target.h"
3
#include "llvm-c/TargetMachine.h"
4
#include "llvm/Analysis/TargetLibraryInfo.h"
5
#include "llvm/IR/LegacyPassManager.h"
6
#include "llvm/IR/Type.h"
7
#include "llvm/MC/TargetRegistry.h"
8
#include "llvm/Target/TargetMachine.h"
9
#include "llvm/TargetParser/Host.h"
10
#include "llvm/TargetParser/Triple.h"
11
12
#include <cstdio>
13
#include <cstring>
14
#include <sstream>
15
16
namespace llvm {
17
18
inline Target *unwrap(LLVMTargetRef T) { return reinterpret_cast<Target *>(T); }
19
20
inline TargetMachine *unwrap(LLVMTargetMachineRef TM) {
21
return reinterpret_cast<TargetMachine *>(TM);
22
}
23
24
inline LLVMTargetMachineRef wrap(TargetMachine *TM) {
25
return reinterpret_cast<LLVMTargetMachineRef>(TM);
26
}
27
28
} // namespace llvm
29
30
extern "C" {
31
32
API_EXPORT(void)
33
LLVMPY_GetProcessTriple(const char **Out) {
34
*Out = LLVMPY_CreateString(llvm::sys::getProcessTriple().c_str());
35
}
36
37
API_EXPORT(void)
38
LLVMPY_GetTripleParts(const char *triple_str, const char **arch_out,
39
const char **vendor_out, const char **os_out,
40
const char **environment_out) {
41
// Normalize the triple string
42
auto triple_str_norm = llvm::Triple::normalize(triple_str);
43
auto triple = llvm::Triple(triple_str_norm);
44
45
*arch_out = LLVMPY_CreateString(
46
llvm::Triple::getArchTypeName(triple.getArch()).data());
47
*vendor_out = LLVMPY_CreateString(
48
llvm::Triple::getVendorTypeName(triple.getVendor()).data());
49
*os_out =
50
LLVMPY_CreateString(llvm::Triple::getOSTypeName(triple.getOS()).data());
51
*environment_out = LLVMPY_CreateString(
52
llvm::Triple::getEnvironmentTypeName(triple.getEnvironment()).data());
53
}
54
55
/**
56
* Output the feature string to the output argument.
57
* Features are prefixed with '+' or '-' for enabled or disabled, respectively.
58
* Features are separated by ','.
59
*/
60
API_EXPORT(int)
61
LLVMPY_GetHostCPUFeatures(const char **Out) {
62
// https://github.com/llvm/llvm-project/pull/97824
63
llvm::StringMap<bool> features = llvm::sys::getHostCPUFeatures();
64
std::ostringstream buf;
65
if (!features.empty()) {
66
for (auto &F : features) {
67
if (buf.tellp()) {
68
buf << ',';
69
}
70
buf << ((F.second ? "+" : "-") + F.first()).str();
71
}
72
*Out = LLVMPY_CreateString(buf.str().c_str());
73
return 1;
74
}
75
return 0;
76
}
77
78
API_EXPORT(void)
79
LLVMPY_GetDefaultTargetTriple(const char **Out) {
80
*Out = LLVMPY_CreateString(llvm::sys::getDefaultTargetTriple().c_str());
81
}
82
83
API_EXPORT(void)
84
LLVMPY_GetHostCPUName(const char **Out) {
85
*Out = LLVMPY_CreateString(llvm::sys::getHostCPUName().data());
86
}
87
88
API_EXPORT(int)
89
LLVMPY_GetTripleObjectFormat(const char *tripleStr) {
90
return llvm::Triple(tripleStr).getObjectFormat();
91
}
92
93
API_EXPORT(LLVMTargetDataRef)
94
LLVMPY_CreateTargetData(const char *StringRep) {
95
return LLVMCreateTargetData(StringRep);
96
}
97
98
API_EXPORT(void)
99
LLVMPY_CopyStringRepOfTargetData(LLVMTargetDataRef TD, char **Out) {
100
*Out = LLVMCopyStringRepOfTargetData(TD);
101
}
102
103
API_EXPORT(void)
104
LLVMPY_DisposeTargetData(LLVMTargetDataRef TD) { LLVMDisposeTargetData(TD); }
105
106
API_EXPORT(long long)
107
LLVMPY_ABISizeOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
108
return (long long)LLVMABISizeOfType(TD, Ty);
109
}
110
111
API_EXPORT(long long)
112
LLVMPY_OffsetOfElement(LLVMTargetDataRef TD, LLVMTypeRef Ty, int Element) {
113
llvm::Type *tp = llvm::unwrap(Ty);
114
if (!tp->isStructTy())
115
return -1;
116
return (long long)LLVMOffsetOfElement(TD, Ty, Element);
117
}
118
119
API_EXPORT(long long)
120
LLVMPY_ABIAlignmentOfType(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
121
return (long long)LLVMABIAlignmentOfType(TD, Ty);
122
}
123
124
API_EXPORT(LLVMTargetRef)
125
LLVMPY_GetTargetFromTriple(const char *Triple, const char **ErrOut) {
126
char *ErrorMessage;
127
LLVMTargetRef T;
128
if (LLVMGetTargetFromTriple(Triple, &T, &ErrorMessage)) {
129
*ErrOut = LLVMPY_CreateString(ErrorMessage);
130
LLVMDisposeMessage(ErrorMessage);
131
return NULL;
132
}
133
return T;
134
}
135
136
API_EXPORT(const char *)
137
LLVMPY_GetTargetName(LLVMTargetRef T) { return LLVMGetTargetName(T); }
138
139
API_EXPORT(const char *)
140
LLVMPY_GetTargetDescription(LLVMTargetRef T) {
141
return LLVMGetTargetDescription(T);
142
}
143
144
API_EXPORT(LLVMTargetMachineRef)
145
LLVMPY_CreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU,
146
const char *Features, int OptLevel,
147
const char *RelocModel, const char *CodeModel,
148
int PrintMC, int JIT, const char *ABIName) {
149
using namespace llvm;
150
151
// https://github.com/llvm/llvm-project/pull/66295
152
CodeGenOptLevel cgol;
153
switch (OptLevel) {
154
case 0:
155
cgol = CodeGenOptLevel::None;
156
break;
157
case 1:
158
cgol = CodeGenOptLevel::Less;
159
break;
160
case 3:
161
cgol = CodeGenOptLevel::Aggressive;
162
break;
163
case 2:
164
default:
165
cgol = CodeGenOptLevel::Default;
166
}
167
168
CodeModel::Model cm;
169
std::string cms(CodeModel);
170
if (cms == "small")
171
cm = CodeModel::Small;
172
else if (cms == "kernel")
173
cm = CodeModel::Kernel;
174
else if (cms == "medium")
175
cm = CodeModel::Medium;
176
else if (cms == "large")
177
cm = CodeModel::Large;
178
else if (cms == "default") // As per LLVM 5, needed for AOT
179
cm = CodeModel::Small;
180
else { // catches "jitdefault" and not set, as per LLVM 5, needed for MCJIT
181
// fall through, use model based on bitness
182
int bits = sizeof(void *);
183
if (bits == 4)
184
cm = CodeModel::Small;
185
else
186
cm = CodeModel::Large;
187
}
188
189
// llvm::Optional removed in llvm17
190
std::optional<Reloc::Model> rm;
191
std::string rms(RelocModel);
192
if (rms == "static")
193
rm = Reloc::Static;
194
else if (rms == "pic")
195
rm = Reloc::PIC_;
196
else if (rms == "dynamicnopic")
197
rm = Reloc::DynamicNoPIC;
198
199
TargetOptions opt;
200
opt.MCOptions.ShowMCInst = PrintMC;
201
opt.MCOptions.ABIName = ABIName;
202
203
bool jit = JIT;
204
205
return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, rm,
206
cm, cgol, jit));
207
}
208
209
API_EXPORT(void)
210
LLVMPY_DisposeTargetMachine(LLVMTargetMachineRef TM) {
211
return LLVMDisposeTargetMachine(TM);
212
}
213
214
API_EXPORT(void)
215
LLVMPY_GetTargetMachineTriple(LLVMTargetMachineRef TM, const char **Out) {
216
// result is already strdup()ed by LLVMGetTargetMachineTriple
217
*Out = LLVMGetTargetMachineTriple(TM);
218
}
219
220
API_EXPORT(void)
221
LLVMPY_SetTargetMachineAsmVerbosity(LLVMTargetMachineRef TM, int verbose) {
222
LLVMSetTargetMachineAsmVerbosity(TM, verbose);
223
}
224
225
API_EXPORT(LLVMMemoryBufferRef)
226
LLVMPY_TargetMachineEmitToMemory(LLVMTargetMachineRef TM, LLVMModuleRef M,
227
int use_object, const char **ErrOut) {
228
LLVMCodeGenFileType filetype = LLVMAssemblyFile;
229
if (use_object)
230
filetype = LLVMObjectFile;
231
232
char *ErrorMessage;
233
LLVMMemoryBufferRef BufOut;
234
int err = LLVMTargetMachineEmitToMemoryBuffer(TM, M, filetype,
235
&ErrorMessage, &BufOut);
236
if (err) {
237
*ErrOut = LLVMPY_CreateString(ErrorMessage);
238
LLVMDisposeMessage(ErrorMessage);
239
return NULL;
240
}
241
242
return BufOut;
243
}
244
245
API_EXPORT(LLVMTargetDataRef)
246
LLVMPY_CreateTargetMachineData(LLVMTargetMachineRef TM) {
247
return llvm::wrap(
248
new llvm::DataLayout(llvm::unwrap(TM)->createDataLayout()));
249
}
250
251
API_EXPORT(void)
252
LLVMPY_AddAnalysisPasses(LLVMTargetMachineRef TM, LLVMPassManagerRef PM) {
253
LLVMAddAnalysisPasses(TM, PM);
254
}
255
256
API_EXPORT(const void *)
257
LLVMPY_GetBufferStart(LLVMMemoryBufferRef MB) { return LLVMGetBufferStart(MB); }
258
259
API_EXPORT(size_t)
260
LLVMPY_GetBufferSize(LLVMMemoryBufferRef MB) { return LLVMGetBufferSize(MB); }
261
262
API_EXPORT(void)
263
LLVMPY_DisposeMemoryBuffer(LLVMMemoryBufferRef MB) {
264
return LLVMDisposeMemoryBuffer(MB);
265
}
266
267
API_EXPORT(void)
268
LLVMPY_AddTargetLibraryInfoPass(LLVMPassManagerRef PM, const char *TripleStr) {
269
using namespace llvm;
270
unwrap(PM)->add(new TargetLibraryInfoWrapperPass(Triple(TripleStr)));
271
}
272
273
} // end extern "C"
274
275