Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/ExecutionEngineBindings.cpp
35233 views
1
//===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===//
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
// This file defines the C bindings for the ExecutionEngine library.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm-c/ExecutionEngine.h"
14
#include "llvm/ExecutionEngine/ExecutionEngine.h"
15
#include "llvm/ExecutionEngine/GenericValue.h"
16
#include "llvm/ExecutionEngine/JITEventListener.h"
17
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
18
#include "llvm/IR/DerivedTypes.h"
19
#include "llvm/IR/Module.h"
20
#include "llvm/Support/ErrorHandling.h"
21
#include "llvm/Target/CodeGenCWrappers.h"
22
#include "llvm/Target/TargetOptions.h"
23
#include <cstring>
24
#include <optional>
25
26
using namespace llvm;
27
28
#define DEBUG_TYPE "jit"
29
30
// Wrapping the C bindings types.
31
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef)
32
33
34
static LLVMTargetMachineRef wrap(const TargetMachine *P) {
35
return
36
reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
37
}
38
39
/*===-- Operations on generic values --------------------------------------===*/
40
41
LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
42
unsigned long long N,
43
LLVMBool IsSigned) {
44
GenericValue *GenVal = new GenericValue();
45
GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned);
46
return wrap(GenVal);
47
}
48
49
LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) {
50
GenericValue *GenVal = new GenericValue();
51
GenVal->PointerVal = P;
52
return wrap(GenVal);
53
}
54
55
LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N) {
56
GenericValue *GenVal = new GenericValue();
57
switch (unwrap(TyRef)->getTypeID()) {
58
case Type::FloatTyID:
59
GenVal->FloatVal = N;
60
break;
61
case Type::DoubleTyID:
62
GenVal->DoubleVal = N;
63
break;
64
default:
65
llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
66
}
67
return wrap(GenVal);
68
}
69
70
unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) {
71
return unwrap(GenValRef)->IntVal.getBitWidth();
72
}
73
74
unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,
75
LLVMBool IsSigned) {
76
GenericValue *GenVal = unwrap(GenValRef);
77
if (IsSigned)
78
return GenVal->IntVal.getSExtValue();
79
else
80
return GenVal->IntVal.getZExtValue();
81
}
82
83
void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) {
84
return unwrap(GenVal)->PointerVal;
85
}
86
87
double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal) {
88
switch (unwrap(TyRef)->getTypeID()) {
89
case Type::FloatTyID:
90
return unwrap(GenVal)->FloatVal;
91
case Type::DoubleTyID:
92
return unwrap(GenVal)->DoubleVal;
93
default:
94
llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
95
}
96
}
97
98
void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
99
delete unwrap(GenVal);
100
}
101
102
/*===-- Operations on execution engines -----------------------------------===*/
103
104
LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
105
LLVMModuleRef M,
106
char **OutError) {
107
std::string Error;
108
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
109
builder.setEngineKind(EngineKind::Either)
110
.setErrorStr(&Error);
111
if (ExecutionEngine *EE = builder.create()){
112
*OutEE = wrap(EE);
113
return 0;
114
}
115
*OutError = strdup(Error.c_str());
116
return 1;
117
}
118
119
LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
120
LLVMModuleRef M,
121
char **OutError) {
122
std::string Error;
123
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
124
builder.setEngineKind(EngineKind::Interpreter)
125
.setErrorStr(&Error);
126
if (ExecutionEngine *Interp = builder.create()) {
127
*OutInterp = wrap(Interp);
128
return 0;
129
}
130
*OutError = strdup(Error.c_str());
131
return 1;
132
}
133
134
LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
135
LLVMModuleRef M,
136
unsigned OptLevel,
137
char **OutError) {
138
std::string Error;
139
EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
140
builder.setEngineKind(EngineKind::JIT)
141
.setErrorStr(&Error)
142
.setOptLevel((CodeGenOptLevel)OptLevel);
143
if (ExecutionEngine *JIT = builder.create()) {
144
*OutJIT = wrap(JIT);
145
return 0;
146
}
147
*OutError = strdup(Error.c_str());
148
return 1;
149
}
150
151
void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions,
152
size_t SizeOfPassedOptions) {
153
LLVMMCJITCompilerOptions options;
154
memset(&options, 0, sizeof(options)); // Most fields are zero by default.
155
options.CodeModel = LLVMCodeModelJITDefault;
156
157
memcpy(PassedOptions, &options,
158
std::min(sizeof(options), SizeOfPassedOptions));
159
}
160
161
LLVMBool LLVMCreateMCJITCompilerForModule(
162
LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
163
LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions,
164
char **OutError) {
165
LLVMMCJITCompilerOptions options;
166
// If the user passed a larger sized options struct, then they were compiled
167
// against a newer LLVM. Tell them that something is wrong.
168
if (SizeOfPassedOptions > sizeof(options)) {
169
*OutError = strdup(
170
"Refusing to use options struct that is larger than my own; assuming "
171
"LLVM library mismatch.");
172
return 1;
173
}
174
175
// Defend against the user having an old version of the API by ensuring that
176
// any fields they didn't see are cleared. We must defend against fields being
177
// set to the bitwise equivalent of zero, and assume that this means "do the
178
// default" as if that option hadn't been available.
179
LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
180
memcpy(&options, PassedOptions, SizeOfPassedOptions);
181
182
TargetOptions targetOptions;
183
targetOptions.EnableFastISel = options.EnableFastISel;
184
std::unique_ptr<Module> Mod(unwrap(M));
185
186
if (Mod)
187
// Set function attribute "frame-pointer" based on
188
// NoFramePointerElim.
189
for (auto &F : *Mod) {
190
auto Attrs = F.getAttributes();
191
StringRef Value = options.NoFramePointerElim ? "all" : "none";
192
Attrs = Attrs.addFnAttribute(F.getContext(), "frame-pointer", Value);
193
F.setAttributes(Attrs);
194
}
195
196
std::string Error;
197
EngineBuilder builder(std::move(Mod));
198
builder.setEngineKind(EngineKind::JIT)
199
.setErrorStr(&Error)
200
.setOptLevel((CodeGenOptLevel)options.OptLevel)
201
.setTargetOptions(targetOptions);
202
bool JIT;
203
if (std::optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
204
builder.setCodeModel(*CM);
205
if (options.MCJMM)
206
builder.setMCJITMemoryManager(
207
std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
208
if (ExecutionEngine *JIT = builder.create()) {
209
*OutJIT = wrap(JIT);
210
return 0;
211
}
212
*OutError = strdup(Error.c_str());
213
return 1;
214
}
215
216
void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
217
delete unwrap(EE);
218
}
219
220
void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
221
unwrap(EE)->finalizeObject();
222
unwrap(EE)->runStaticConstructorsDestructors(false);
223
}
224
225
void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
226
unwrap(EE)->finalizeObject();
227
unwrap(EE)->runStaticConstructorsDestructors(true);
228
}
229
230
int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
231
unsigned ArgC, const char * const *ArgV,
232
const char * const *EnvP) {
233
unwrap(EE)->finalizeObject();
234
235
std::vector<std::string> ArgVec(ArgV, ArgV + ArgC);
236
return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
237
}
238
239
LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
240
unsigned NumArgs,
241
LLVMGenericValueRef *Args) {
242
unwrap(EE)->finalizeObject();
243
244
std::vector<GenericValue> ArgVec;
245
ArgVec.reserve(NumArgs);
246
for (unsigned I = 0; I != NumArgs; ++I)
247
ArgVec.push_back(*unwrap(Args[I]));
248
249
GenericValue *Result = new GenericValue();
250
*Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
251
return wrap(Result);
252
}
253
254
void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
255
}
256
257
void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
258
unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
259
}
260
261
LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
262
LLVMModuleRef *OutMod, char **OutError) {
263
Module *Mod = unwrap(M);
264
unwrap(EE)->removeModule(Mod);
265
*OutMod = wrap(Mod);
266
return 0;
267
}
268
269
LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
270
LLVMValueRef *OutFn) {
271
if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
272
*OutFn = wrap(F);
273
return 0;
274
}
275
return 1;
276
}
277
278
void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
279
LLVMValueRef Fn) {
280
return nullptr;
281
}
282
283
LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
284
return wrap(&unwrap(EE)->getDataLayout());
285
}
286
287
LLVMTargetMachineRef
288
LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) {
289
return wrap(unwrap(EE)->getTargetMachine());
290
}
291
292
void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
293
void* Addr) {
294
unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
295
}
296
297
void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
298
unwrap(EE)->finalizeObject();
299
300
return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
301
}
302
303
uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) {
304
return unwrap(EE)->getGlobalValueAddress(Name);
305
}
306
307
uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) {
308
return unwrap(EE)->getFunctionAddress(Name);
309
}
310
311
LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE,
312
char **OutError) {
313
assert(OutError && "OutError must be non-null");
314
auto *ExecEngine = unwrap(EE);
315
if (ExecEngine->hasError()) {
316
*OutError = strdup(ExecEngine->getErrorMessage().c_str());
317
ExecEngine->clearErrorMessage();
318
return true;
319
}
320
return false;
321
}
322
323
/*===-- Operations on memory managers -------------------------------------===*/
324
325
namespace {
326
327
struct SimpleBindingMMFunctions {
328
LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection;
329
LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection;
330
LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory;
331
LLVMMemoryManagerDestroyCallback Destroy;
332
};
333
334
class SimpleBindingMemoryManager : public RTDyldMemoryManager {
335
public:
336
SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
337
void *Opaque);
338
~SimpleBindingMemoryManager() override;
339
340
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
341
unsigned SectionID,
342
StringRef SectionName) override;
343
344
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
345
unsigned SectionID, StringRef SectionName,
346
bool isReadOnly) override;
347
348
bool finalizeMemory(std::string *ErrMsg) override;
349
350
private:
351
SimpleBindingMMFunctions Functions;
352
void *Opaque;
353
};
354
355
SimpleBindingMemoryManager::SimpleBindingMemoryManager(
356
const SimpleBindingMMFunctions& Functions,
357
void *Opaque)
358
: Functions(Functions), Opaque(Opaque) {
359
assert(Functions.AllocateCodeSection &&
360
"No AllocateCodeSection function provided!");
361
assert(Functions.AllocateDataSection &&
362
"No AllocateDataSection function provided!");
363
assert(Functions.FinalizeMemory &&
364
"No FinalizeMemory function provided!");
365
assert(Functions.Destroy &&
366
"No Destroy function provided!");
367
}
368
369
SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
370
Functions.Destroy(Opaque);
371
}
372
373
uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
374
uintptr_t Size, unsigned Alignment, unsigned SectionID,
375
StringRef SectionName) {
376
return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
377
SectionName.str().c_str());
378
}
379
380
uint8_t *SimpleBindingMemoryManager::allocateDataSection(
381
uintptr_t Size, unsigned Alignment, unsigned SectionID,
382
StringRef SectionName, bool isReadOnly) {
383
return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID,
384
SectionName.str().c_str(),
385
isReadOnly);
386
}
387
388
bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
389
char *errMsgCString = nullptr;
390
bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
391
assert((result || !errMsgCString) &&
392
"Did not expect an error message if FinalizeMemory succeeded");
393
if (errMsgCString) {
394
if (ErrMsg)
395
*ErrMsg = errMsgCString;
396
free(errMsgCString);
397
}
398
return result;
399
}
400
401
} // anonymous namespace
402
403
LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
404
void *Opaque,
405
LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
406
LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
407
LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
408
LLVMMemoryManagerDestroyCallback Destroy) {
409
410
if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
411
!Destroy)
412
return nullptr;
413
414
SimpleBindingMMFunctions functions;
415
functions.AllocateCodeSection = AllocateCodeSection;
416
functions.AllocateDataSection = AllocateDataSection;
417
functions.FinalizeMemory = FinalizeMemory;
418
functions.Destroy = Destroy;
419
return wrap(new SimpleBindingMemoryManager(functions, Opaque));
420
}
421
422
void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) {
423
delete unwrap(MM);
424
}
425
426
/*===-- JIT Event Listener functions -------------------------------------===*/
427
428
429
#if !LLVM_USE_INTEL_JITEVENTS
430
LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
431
{
432
return nullptr;
433
}
434
#endif
435
436
#if !LLVM_USE_OPROFILE
437
LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
438
{
439
return nullptr;
440
}
441
#endif
442
443
#if !LLVM_USE_PERF
444
LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
445
{
446
return nullptr;
447
}
448
#endif
449
450