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"
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((CodeGenOpt::Level
)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 "no-frame-pointer-elim" based on
187 // NoFramePointerElim.
188 for (auto &F
: *Mod
) {
189 auto Attrs
= F
.getAttributes();
190 StringRef
Value(options
.NoFramePointerElim
? "true" : "false");
191 Attrs
= Attrs
.addAttribute(F
.getContext(), AttributeList::FunctionIndex
,
192 "no-frame-pointer-elim", Value
);
193 F
.setAttributes(Attrs
);
197 EngineBuilder
builder(std::move(Mod
));
198 builder
.setEngineKind(EngineKind::JIT
)
200 .setOptLevel((CodeGenOpt::Level
)options
.OptLevel
)
201 .setTargetOptions(targetOptions
);
203 if (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 /*===-- Operations on memory managers -------------------------------------===*/
315 struct SimpleBindingMMFunctions
{
316 LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection
;
317 LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection
;
318 LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory
;
319 LLVMMemoryManagerDestroyCallback Destroy
;
322 class SimpleBindingMemoryManager
: public RTDyldMemoryManager
{
324 SimpleBindingMemoryManager(const SimpleBindingMMFunctions
& Functions
,
326 ~SimpleBindingMemoryManager() override
;
328 uint8_t *allocateCodeSection(uintptr_t Size
, unsigned Alignment
,
330 StringRef SectionName
) override
;
332 uint8_t *allocateDataSection(uintptr_t Size
, unsigned Alignment
,
333 unsigned SectionID
, StringRef SectionName
,
334 bool isReadOnly
) override
;
336 bool finalizeMemory(std::string
*ErrMsg
) override
;
339 SimpleBindingMMFunctions Functions
;
343 SimpleBindingMemoryManager::SimpleBindingMemoryManager(
344 const SimpleBindingMMFunctions
& Functions
,
346 : Functions(Functions
), Opaque(Opaque
) {
347 assert(Functions
.AllocateCodeSection
&&
348 "No AllocateCodeSection function provided!");
349 assert(Functions
.AllocateDataSection
&&
350 "No AllocateDataSection function provided!");
351 assert(Functions
.FinalizeMemory
&&
352 "No FinalizeMemory function provided!");
353 assert(Functions
.Destroy
&&
354 "No Destroy function provided!");
357 SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
358 Functions
.Destroy(Opaque
);
361 uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
362 uintptr_t Size
, unsigned Alignment
, unsigned SectionID
,
363 StringRef SectionName
) {
364 return Functions
.AllocateCodeSection(Opaque
, Size
, Alignment
, SectionID
,
365 SectionName
.str().c_str());
368 uint8_t *SimpleBindingMemoryManager::allocateDataSection(
369 uintptr_t Size
, unsigned Alignment
, unsigned SectionID
,
370 StringRef SectionName
, bool isReadOnly
) {
371 return Functions
.AllocateDataSection(Opaque
, Size
, Alignment
, SectionID
,
372 SectionName
.str().c_str(),
376 bool SimpleBindingMemoryManager::finalizeMemory(std::string
*ErrMsg
) {
377 char *errMsgCString
= nullptr;
378 bool result
= Functions
.FinalizeMemory(Opaque
, &errMsgCString
);
379 assert((result
|| !errMsgCString
) &&
380 "Did not expect an error message if FinalizeMemory succeeded");
383 *ErrMsg
= errMsgCString
;
389 } // anonymous namespace
391 LLVMMCJITMemoryManagerRef
LLVMCreateSimpleMCJITMemoryManager(
393 LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection
,
394 LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection
,
395 LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory
,
396 LLVMMemoryManagerDestroyCallback Destroy
) {
398 if (!AllocateCodeSection
|| !AllocateDataSection
|| !FinalizeMemory
||
402 SimpleBindingMMFunctions functions
;
403 functions
.AllocateCodeSection
= AllocateCodeSection
;
404 functions
.AllocateDataSection
= AllocateDataSection
;
405 functions
.FinalizeMemory
= FinalizeMemory
;
406 functions
.Destroy
= Destroy
;
407 return wrap(new SimpleBindingMemoryManager(functions
, Opaque
));
410 void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM
) {
414 /*===-- JIT Event Listener functions -------------------------------------===*/
417 #if !LLVM_USE_INTEL_JITEVENTS
418 LLVMJITEventListenerRef
LLVMCreateIntelJITEventListener(void)
424 #if !LLVM_USE_OPROFILE
425 LLVMJITEventListenerRef
LLVMCreateOProfileJITEventListener(void)
432 LLVMJITEventListenerRef
LLVMCreatePerfJITEventListener(void)