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/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"
28 #define DEBUG_TYPE "jit"
30 // Wrapping the C bindings types.
31 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue
, LLVMGenericValueRef
)
34 static LLVMTargetMachineRef
wrap(const TargetMachine
*P
) {
36 reinterpret_cast<LLVMTargetMachineRef
>(const_cast<TargetMachine
*>(P
));
39 /*===-- Operations on generic values --------------------------------------===*/
41 LLVMGenericValueRef
LLVMCreateGenericValueOfInt(LLVMTypeRef Ty
,
44 GenericValue
*GenVal
= new GenericValue();
45 GenVal
->IntVal
= APInt(unwrap
<IntegerType
>(Ty
)->getBitWidth(), N
, IsSigned
);
49 LLVMGenericValueRef
LLVMCreateGenericValueOfPointer(void *P
) {
50 GenericValue
*GenVal
= new GenericValue();
51 GenVal
->PointerVal
= P
;
55 LLVMGenericValueRef
LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef
, double N
) {
56 GenericValue
*GenVal
= new GenericValue();
57 switch (unwrap(TyRef
)->getTypeID()) {
61 case Type::DoubleTyID
:
62 GenVal
->DoubleVal
= N
;
65 llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
70 unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef
) {
71 return unwrap(GenValRef
)->IntVal
.getBitWidth();
74 unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef
,
76 GenericValue
*GenVal
= unwrap(GenValRef
);
78 return GenVal
->IntVal
.getSExtValue();
80 return GenVal
->IntVal
.getZExtValue();
83 void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal
) {
84 return unwrap(GenVal
)->PointerVal
;
87 double LLVMGenericValueToFloat(LLVMTypeRef TyRef
, LLVMGenericValueRef GenVal
) {
88 switch (unwrap(TyRef
)->getTypeID()) {
90 return unwrap(GenVal
)->FloatVal
;
91 case Type::DoubleTyID
:
92 return unwrap(GenVal
)->DoubleVal
;
94 llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
98 void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal
) {
99 delete unwrap(GenVal
);
102 /*===-- Operations on execution engines -----------------------------------===*/
104 LLVMBool
LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef
*OutEE
,
108 EngineBuilder
builder(std::unique_ptr
<Module
>(unwrap(M
)));
109 builder
.setEngineKind(EngineKind::Either
)
110 .setErrorStr(&Error
);
111 if (ExecutionEngine
*EE
= builder
.create()){
115 *OutError
= strdup(Error
.c_str());
119 LLVMBool
LLVMCreateInterpreterForModule(LLVMExecutionEngineRef
*OutInterp
,
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
);
130 *OutError
= strdup(Error
.c_str());
134 LLVMBool
LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef
*OutJIT
,
139 EngineBuilder
builder(std::unique_ptr
<Module
>(unwrap(M
)));
140 builder
.setEngineKind(EngineKind::JIT
)
142 .setOptLevel((CodeGenOptLevel
)OptLevel
);
143 if (ExecutionEngine
*JIT
= builder
.create()) {
147 *OutError
= strdup(Error
.c_str());
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
;
157 memcpy(PassedOptions
, &options
,
158 std::min(sizeof(options
), SizeOfPassedOptions
));
161 LLVMBool
LLVMCreateMCJITCompilerForModule(
162 LLVMExecutionEngineRef
*OutJIT
, LLVMModuleRef M
,
163 LLVMMCJITCompilerOptions
*PassedOptions
, size_t SizeOfPassedOptions
,
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
)) {
170 "Refusing to use options struct that is larger than my own; assuming "
171 "LLVM library mismatch.");
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
);
182 TargetOptions targetOptions
;
183 targetOptions
.EnableFastISel
= options
.EnableFastISel
;
184 std::unique_ptr
<Module
> Mod(unwrap(M
));
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
);
197 EngineBuilder
builder(std::move(Mod
));
198 builder
.setEngineKind(EngineKind::JIT
)
200 .setOptLevel((CodeGenOptLevel
)options
.OptLevel
)
201 .setTargetOptions(targetOptions
);
203 if (std::optional
<CodeModel::Model
> CM
= unwrap(options
.CodeModel
, JIT
))
204 builder
.setCodeModel(*CM
);
206 builder
.setMCJITMemoryManager(
207 std::unique_ptr
<RTDyldMemoryManager
>(unwrap(options
.MCJMM
)));
208 if (ExecutionEngine
*JIT
= builder
.create()) {
212 *OutError
= strdup(Error
.c_str());
216 void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE
) {
220 void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE
) {
221 unwrap(EE
)->finalizeObject();
222 unwrap(EE
)->runStaticConstructorsDestructors(false);
225 void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE
) {
226 unwrap(EE
)->finalizeObject();
227 unwrap(EE
)->runStaticConstructorsDestructors(true);
230 int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE
, LLVMValueRef F
,
231 unsigned ArgC
, const char * const *ArgV
,
232 const char * const *EnvP
) {
233 unwrap(EE
)->finalizeObject();
235 std::vector
<std::string
> ArgVec(ArgV
, ArgV
+ ArgC
);
236 return unwrap(EE
)->runFunctionAsMain(unwrap
<Function
>(F
), ArgVec
, EnvP
);
239 LLVMGenericValueRef
LLVMRunFunction(LLVMExecutionEngineRef EE
, LLVMValueRef F
,
241 LLVMGenericValueRef
*Args
) {
242 unwrap(EE
)->finalizeObject();
244 std::vector
<GenericValue
> ArgVec
;
245 ArgVec
.reserve(NumArgs
);
246 for (unsigned I
= 0; I
!= NumArgs
; ++I
)
247 ArgVec
.push_back(*unwrap(Args
[I
]));
249 GenericValue
*Result
= new GenericValue();
250 *Result
= unwrap(EE
)->runFunction(unwrap
<Function
>(F
), ArgVec
);
254 void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE
, LLVMValueRef F
) {
257 void LLVMAddModule(LLVMExecutionEngineRef EE
, LLVMModuleRef M
){
258 unwrap(EE
)->addModule(std::unique_ptr
<Module
>(unwrap(M
)));
261 LLVMBool
LLVMRemoveModule(LLVMExecutionEngineRef EE
, LLVMModuleRef M
,
262 LLVMModuleRef
*OutMod
, char **OutError
) {
263 Module
*Mod
= unwrap(M
);
264 unwrap(EE
)->removeModule(Mod
);
269 LLVMBool
LLVMFindFunction(LLVMExecutionEngineRef EE
, const char *Name
,
270 LLVMValueRef
*OutFn
) {
271 if (Function
*F
= unwrap(EE
)->FindFunctionNamed(Name
)) {
278 void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE
,
283 LLVMTargetDataRef
LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE
) {
284 return wrap(&unwrap(EE
)->getDataLayout());
288 LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE
) {
289 return wrap(unwrap(EE
)->getTargetMachine());
292 void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE
, LLVMValueRef Global
,
294 unwrap(EE
)->addGlobalMapping(unwrap
<GlobalValue
>(Global
), Addr
);
297 void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE
, LLVMValueRef Global
) {
298 unwrap(EE
)->finalizeObject();
300 return unwrap(EE
)->getPointerToGlobal(unwrap
<GlobalValue
>(Global
));
303 uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE
, const char *Name
) {
304 return unwrap(EE
)->getGlobalValueAddress(Name
);
307 uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE
, const char *Name
) {
308 return unwrap(EE
)->getFunctionAddress(Name
);
311 LLVMBool
LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE
,
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();
323 /*===-- Operations on memory managers -------------------------------------===*/
327 struct SimpleBindingMMFunctions
{
328 LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection
;
329 LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection
;
330 LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory
;
331 LLVMMemoryManagerDestroyCallback Destroy
;
334 class SimpleBindingMemoryManager
: public RTDyldMemoryManager
{
336 SimpleBindingMemoryManager(const SimpleBindingMMFunctions
& Functions
,
338 ~SimpleBindingMemoryManager() override
;
340 uint8_t *allocateCodeSection(uintptr_t Size
, unsigned Alignment
,
342 StringRef SectionName
) override
;
344 uint8_t *allocateDataSection(uintptr_t Size
, unsigned Alignment
,
345 unsigned SectionID
, StringRef SectionName
,
346 bool isReadOnly
) override
;
348 bool finalizeMemory(std::string
*ErrMsg
) override
;
351 SimpleBindingMMFunctions Functions
;
355 SimpleBindingMemoryManager::SimpleBindingMemoryManager(
356 const SimpleBindingMMFunctions
& Functions
,
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!");
369 SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
370 Functions
.Destroy(Opaque
);
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());
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(),
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");
395 *ErrMsg
= errMsgCString
;
401 } // anonymous namespace
403 LLVMMCJITMemoryManagerRef
LLVMCreateSimpleMCJITMemoryManager(
405 LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection
,
406 LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection
,
407 LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory
,
408 LLVMMemoryManagerDestroyCallback Destroy
) {
410 if (!AllocateCodeSection
|| !AllocateDataSection
|| !FinalizeMemory
||
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
));
422 void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM
) {
426 /*===-- JIT Event Listener functions -------------------------------------===*/
429 #if !LLVM_USE_INTEL_JITEVENTS
430 LLVMJITEventListenerRef
LLVMCreateIntelJITEventListener(void)
436 #if !LLVM_USE_OPROFILE
437 LLVMJITEventListenerRef
LLVMCreateOProfileJITEventListener(void)
444 LLVMJITEventListenerRef
LLVMCreatePerfJITEventListener(void)