1 //===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the C bindings for the ExecutionEngine library.
11 //===----------------------------------------------------------------------===//
13 #include "llvm-c/ExecutionEngine.h"
14 #include "llvm/ExecutionEngine/ExecutionEngine.h"
15 #include "llvm/ExecutionEngine/GenericValue.h"
16 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
17 #include "llvm/IR/DerivedTypes.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Target/CodeGenCWrappers.h"
21 #include "llvm/Target/TargetOptions.h"
27 #define DEBUG_TYPE "jit"
29 // Wrapping the C bindings types.
30 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue
, LLVMGenericValueRef
)
33 static LLVMTargetMachineRef
wrap(const TargetMachine
*P
) {
35 reinterpret_cast<LLVMTargetMachineRef
>(const_cast<TargetMachine
*>(P
));
38 /*===-- Operations on generic values --------------------------------------===*/
40 LLVMGenericValueRef
LLVMCreateGenericValueOfInt(LLVMTypeRef Ty
,
43 GenericValue
*GenVal
= new GenericValue();
44 GenVal
->IntVal
= APInt(unwrap
<IntegerType
>(Ty
)->getBitWidth(), N
, IsSigned
);
48 LLVMGenericValueRef
LLVMCreateGenericValueOfPointer(void *P
) {
49 GenericValue
*GenVal
= new GenericValue();
50 GenVal
->PointerVal
= P
;
54 LLVMGenericValueRef
LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef
, double N
) {
55 GenericValue
*GenVal
= new GenericValue();
56 switch (unwrap(TyRef
)->getTypeID()) {
60 case Type::DoubleTyID
:
61 GenVal
->DoubleVal
= N
;
64 llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
69 unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef
) {
70 return unwrap(GenValRef
)->IntVal
.getBitWidth();
73 unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef
,
75 GenericValue
*GenVal
= unwrap(GenValRef
);
77 return GenVal
->IntVal
.getSExtValue();
79 return GenVal
->IntVal
.getZExtValue();
82 void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal
) {
83 return unwrap(GenVal
)->PointerVal
;
86 double LLVMGenericValueToFloat(LLVMTypeRef TyRef
, LLVMGenericValueRef GenVal
) {
87 switch (unwrap(TyRef
)->getTypeID()) {
89 return unwrap(GenVal
)->FloatVal
;
90 case Type::DoubleTyID
:
91 return unwrap(GenVal
)->DoubleVal
;
93 llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
97 void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal
) {
98 delete unwrap(GenVal
);
101 /*===-- Operations on execution engines -----------------------------------===*/
103 LLVMBool
LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef
*OutEE
,
107 EngineBuilder
builder(std::unique_ptr
<Module
>(unwrap(M
)));
108 builder
.setEngineKind(EngineKind::Either
)
109 .setErrorStr(&Error
);
110 if (ExecutionEngine
*EE
= builder
.create()){
114 *OutError
= strdup(Error
.c_str());
118 LLVMBool
LLVMCreateInterpreterForModule(LLVMExecutionEngineRef
*OutInterp
,
122 EngineBuilder
builder(std::unique_ptr
<Module
>(unwrap(M
)));
123 builder
.setEngineKind(EngineKind::Interpreter
)
124 .setErrorStr(&Error
);
125 if (ExecutionEngine
*Interp
= builder
.create()) {
126 *OutInterp
= wrap(Interp
);
129 *OutError
= strdup(Error
.c_str());
133 LLVMBool
LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef
*OutJIT
,
138 EngineBuilder
builder(std::unique_ptr
<Module
>(unwrap(M
)));
139 builder
.setEngineKind(EngineKind::JIT
)
141 .setOptLevel((CodeGenOptLevel
)OptLevel
);
142 if (ExecutionEngine
*JIT
= builder
.create()) {
146 *OutError
= strdup(Error
.c_str());
150 void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions
*PassedOptions
,
151 size_t SizeOfPassedOptions
) {
152 LLVMMCJITCompilerOptions options
;
153 memset(&options
, 0, sizeof(options
)); // Most fields are zero by default.
154 options
.CodeModel
= LLVMCodeModelJITDefault
;
156 memcpy(PassedOptions
, &options
,
157 std::min(sizeof(options
), SizeOfPassedOptions
));
160 LLVMBool
LLVMCreateMCJITCompilerForModule(
161 LLVMExecutionEngineRef
*OutJIT
, LLVMModuleRef M
,
162 LLVMMCJITCompilerOptions
*PassedOptions
, size_t SizeOfPassedOptions
,
164 LLVMMCJITCompilerOptions options
;
165 // If the user passed a larger sized options struct, then they were compiled
166 // against a newer LLVM. Tell them that something is wrong.
167 if (SizeOfPassedOptions
> sizeof(options
)) {
169 "Refusing to use options struct that is larger than my own; assuming "
170 "LLVM library mismatch.");
174 // Defend against the user having an old version of the API by ensuring that
175 // any fields they didn't see are cleared. We must defend against fields being
176 // set to the bitwise equivalent of zero, and assume that this means "do the
177 // default" as if that option hadn't been available.
178 LLVMInitializeMCJITCompilerOptions(&options
, sizeof(options
));
179 memcpy(&options
, PassedOptions
, SizeOfPassedOptions
);
181 TargetOptions targetOptions
;
182 targetOptions
.EnableFastISel
= options
.EnableFastISel
;
183 std::unique_ptr
<Module
> Mod(unwrap(M
));
186 // Set function attribute "frame-pointer" based on
187 // NoFramePointerElim.
188 for (auto &F
: *Mod
) {
189 auto Attrs
= F
.getAttributes();
190 StringRef Value
= options
.NoFramePointerElim
? "all" : "none";
191 Attrs
= Attrs
.addFnAttribute(F
.getContext(), "frame-pointer", Value
);
192 F
.setAttributes(Attrs
);
196 EngineBuilder
builder(std::move(Mod
));
197 builder
.setEngineKind(EngineKind::JIT
)
199 .setOptLevel((CodeGenOptLevel
)options
.OptLevel
)
200 .setTargetOptions(targetOptions
);
202 if (std::optional
<CodeModel::Model
> CM
= unwrap(options
.CodeModel
, JIT
))
203 builder
.setCodeModel(*CM
);
205 builder
.setMCJITMemoryManager(
206 std::unique_ptr
<RTDyldMemoryManager
>(unwrap(options
.MCJMM
)));
207 if (ExecutionEngine
*JIT
= builder
.create()) {
211 *OutError
= strdup(Error
.c_str());
215 void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE
) {
219 void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE
) {
220 unwrap(EE
)->finalizeObject();
221 unwrap(EE
)->runStaticConstructorsDestructors(false);
224 void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE
) {
225 unwrap(EE
)->finalizeObject();
226 unwrap(EE
)->runStaticConstructorsDestructors(true);
229 int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE
, LLVMValueRef F
,
230 unsigned ArgC
, const char * const *ArgV
,
231 const char * const *EnvP
) {
232 unwrap(EE
)->finalizeObject();
234 std::vector
<std::string
> ArgVec(ArgV
, ArgV
+ ArgC
);
235 return unwrap(EE
)->runFunctionAsMain(unwrap
<Function
>(F
), ArgVec
, EnvP
);
238 LLVMGenericValueRef
LLVMRunFunction(LLVMExecutionEngineRef EE
, LLVMValueRef F
,
240 LLVMGenericValueRef
*Args
) {
241 unwrap(EE
)->finalizeObject();
243 std::vector
<GenericValue
> ArgVec
;
244 ArgVec
.reserve(NumArgs
);
245 for (unsigned I
= 0; I
!= NumArgs
; ++I
)
246 ArgVec
.push_back(*unwrap(Args
[I
]));
248 GenericValue
*Result
= new GenericValue();
249 *Result
= unwrap(EE
)->runFunction(unwrap
<Function
>(F
), ArgVec
);
253 void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE
, LLVMValueRef F
) {
256 void LLVMAddModule(LLVMExecutionEngineRef EE
, LLVMModuleRef M
){
257 unwrap(EE
)->addModule(std::unique_ptr
<Module
>(unwrap(M
)));
260 LLVMBool
LLVMRemoveModule(LLVMExecutionEngineRef EE
, LLVMModuleRef M
,
261 LLVMModuleRef
*OutMod
, char **OutError
) {
262 Module
*Mod
= unwrap(M
);
263 unwrap(EE
)->removeModule(Mod
);
268 LLVMBool
LLVMFindFunction(LLVMExecutionEngineRef EE
, const char *Name
,
269 LLVMValueRef
*OutFn
) {
270 if (Function
*F
= unwrap(EE
)->FindFunctionNamed(Name
)) {
277 void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE
,
282 LLVMTargetDataRef
LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE
) {
283 return wrap(&unwrap(EE
)->getDataLayout());
287 LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE
) {
288 return wrap(unwrap(EE
)->getTargetMachine());
291 void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE
, LLVMValueRef Global
,
293 unwrap(EE
)->addGlobalMapping(unwrap
<GlobalValue
>(Global
), Addr
);
296 void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE
, LLVMValueRef Global
) {
297 unwrap(EE
)->finalizeObject();
299 return unwrap(EE
)->getPointerToGlobal(unwrap
<GlobalValue
>(Global
));
302 uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE
, const char *Name
) {
303 return unwrap(EE
)->getGlobalValueAddress(Name
);
306 uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE
, const char *Name
) {
307 return unwrap(EE
)->getFunctionAddress(Name
);
310 LLVMBool
LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE
,
312 assert(OutError
&& "OutError must be non-null");
313 auto *ExecEngine
= unwrap(EE
);
314 if (ExecEngine
->hasError()) {
315 *OutError
= strdup(ExecEngine
->getErrorMessage().c_str());
316 ExecEngine
->clearErrorMessage();
322 /*===-- Operations on memory managers -------------------------------------===*/
326 struct SimpleBindingMMFunctions
{
327 LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection
;
328 LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection
;
329 LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory
;
330 LLVMMemoryManagerDestroyCallback Destroy
;
333 class SimpleBindingMemoryManager
: public RTDyldMemoryManager
{
335 SimpleBindingMemoryManager(const SimpleBindingMMFunctions
& Functions
,
337 ~SimpleBindingMemoryManager() override
;
339 uint8_t *allocateCodeSection(uintptr_t Size
, unsigned Alignment
,
341 StringRef SectionName
) override
;
343 uint8_t *allocateDataSection(uintptr_t Size
, unsigned Alignment
,
344 unsigned SectionID
, StringRef SectionName
,
345 bool isReadOnly
) override
;
347 bool finalizeMemory(std::string
*ErrMsg
) override
;
350 SimpleBindingMMFunctions Functions
;
354 SimpleBindingMemoryManager::SimpleBindingMemoryManager(
355 const SimpleBindingMMFunctions
& Functions
,
357 : Functions(Functions
), Opaque(Opaque
) {
358 assert(Functions
.AllocateCodeSection
&&
359 "No AllocateCodeSection function provided!");
360 assert(Functions
.AllocateDataSection
&&
361 "No AllocateDataSection function provided!");
362 assert(Functions
.FinalizeMemory
&&
363 "No FinalizeMemory function provided!");
364 assert(Functions
.Destroy
&&
365 "No Destroy function provided!");
368 SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
369 Functions
.Destroy(Opaque
);
372 uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
373 uintptr_t Size
, unsigned Alignment
, unsigned SectionID
,
374 StringRef SectionName
) {
375 return Functions
.AllocateCodeSection(Opaque
, Size
, Alignment
, SectionID
,
376 SectionName
.str().c_str());
379 uint8_t *SimpleBindingMemoryManager::allocateDataSection(
380 uintptr_t Size
, unsigned Alignment
, unsigned SectionID
,
381 StringRef SectionName
, bool isReadOnly
) {
382 return Functions
.AllocateDataSection(Opaque
, Size
, Alignment
, SectionID
,
383 SectionName
.str().c_str(),
387 bool SimpleBindingMemoryManager::finalizeMemory(std::string
*ErrMsg
) {
388 char *errMsgCString
= nullptr;
389 bool result
= Functions
.FinalizeMemory(Opaque
, &errMsgCString
);
390 assert((result
|| !errMsgCString
) &&
391 "Did not expect an error message if FinalizeMemory succeeded");
394 *ErrMsg
= errMsgCString
;
400 } // anonymous namespace
402 LLVMMCJITMemoryManagerRef
LLVMCreateSimpleMCJITMemoryManager(
404 LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection
,
405 LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection
,
406 LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory
,
407 LLVMMemoryManagerDestroyCallback Destroy
) {
409 if (!AllocateCodeSection
|| !AllocateDataSection
|| !FinalizeMemory
||
413 SimpleBindingMMFunctions functions
;
414 functions
.AllocateCodeSection
= AllocateCodeSection
;
415 functions
.AllocateDataSection
= AllocateDataSection
;
416 functions
.FinalizeMemory
= FinalizeMemory
;
417 functions
.Destroy
= Destroy
;
418 return wrap(new SimpleBindingMemoryManager(functions
, Opaque
));
421 void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM
) {
425 /*===-- JIT Event Listener functions -------------------------------------===*/
428 #if !LLVM_USE_INTEL_JITEVENTS
429 LLVMJITEventListenerRef
LLVMCreateIntelJITEventListener(void)
435 #if !LLVM_USE_OPROFILE
436 LLVMJITEventListenerRef
LLVMCreateOProfileJITEventListener(void)
443 LLVMJITEventListenerRef
LLVMCreatePerfJITEventListener(void)