123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- //===-- ExecutionEngineBindings.cpp - C bindings for EEs ------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the C bindings for the ExecutionEngine library.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm-c/ExecutionEngine.h"
- #include "llvm/ExecutionEngine/ExecutionEngine.h"
- #include "llvm/ExecutionEngine/GenericValue.h"
- #include "llvm/ExecutionEngine/JITEventListener.h"
- #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
- #include "llvm/IR/DerivedTypes.h"
- #include "llvm/IR/Module.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Target/CodeGenCWrappers.h"
- #include "llvm/Target/TargetOptions.h"
- #include <cstring>
- #include <optional>
- using namespace llvm;
- #define DEBUG_TYPE "jit"
- // Wrapping the C bindings types.
- DEFINE_SIMPLE_CONVERSION_FUNCTIONS(GenericValue, LLVMGenericValueRef)
- static LLVMTargetMachineRef wrap(const TargetMachine *P) {
- return
- reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
- }
- /*===-- Operations on generic values --------------------------------------===*/
- LLVMGenericValueRef LLVMCreateGenericValueOfInt(LLVMTypeRef Ty,
- unsigned long long N,
- LLVMBool IsSigned) {
- GenericValue *GenVal = new GenericValue();
- GenVal->IntVal = APInt(unwrap<IntegerType>(Ty)->getBitWidth(), N, IsSigned);
- return wrap(GenVal);
- }
- LLVMGenericValueRef LLVMCreateGenericValueOfPointer(void *P) {
- GenericValue *GenVal = new GenericValue();
- GenVal->PointerVal = P;
- return wrap(GenVal);
- }
- LLVMGenericValueRef LLVMCreateGenericValueOfFloat(LLVMTypeRef TyRef, double N) {
- GenericValue *GenVal = new GenericValue();
- switch (unwrap(TyRef)->getTypeID()) {
- case Type::FloatTyID:
- GenVal->FloatVal = N;
- break;
- case Type::DoubleTyID:
- GenVal->DoubleVal = N;
- break;
- default:
- llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
- }
- return wrap(GenVal);
- }
- unsigned LLVMGenericValueIntWidth(LLVMGenericValueRef GenValRef) {
- return unwrap(GenValRef)->IntVal.getBitWidth();
- }
- unsigned long long LLVMGenericValueToInt(LLVMGenericValueRef GenValRef,
- LLVMBool IsSigned) {
- GenericValue *GenVal = unwrap(GenValRef);
- if (IsSigned)
- return GenVal->IntVal.getSExtValue();
- else
- return GenVal->IntVal.getZExtValue();
- }
- void *LLVMGenericValueToPointer(LLVMGenericValueRef GenVal) {
- return unwrap(GenVal)->PointerVal;
- }
- double LLVMGenericValueToFloat(LLVMTypeRef TyRef, LLVMGenericValueRef GenVal) {
- switch (unwrap(TyRef)->getTypeID()) {
- case Type::FloatTyID:
- return unwrap(GenVal)->FloatVal;
- case Type::DoubleTyID:
- return unwrap(GenVal)->DoubleVal;
- default:
- llvm_unreachable("LLVMGenericValueToFloat supports only float and double.");
- }
- }
- void LLVMDisposeGenericValue(LLVMGenericValueRef GenVal) {
- delete unwrap(GenVal);
- }
- /*===-- Operations on execution engines -----------------------------------===*/
- LLVMBool LLVMCreateExecutionEngineForModule(LLVMExecutionEngineRef *OutEE,
- LLVMModuleRef M,
- char **OutError) {
- std::string Error;
- EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
- builder.setEngineKind(EngineKind::Either)
- .setErrorStr(&Error);
- if (ExecutionEngine *EE = builder.create()){
- *OutEE = wrap(EE);
- return 0;
- }
- *OutError = strdup(Error.c_str());
- return 1;
- }
- LLVMBool LLVMCreateInterpreterForModule(LLVMExecutionEngineRef *OutInterp,
- LLVMModuleRef M,
- char **OutError) {
- std::string Error;
- EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
- builder.setEngineKind(EngineKind::Interpreter)
- .setErrorStr(&Error);
- if (ExecutionEngine *Interp = builder.create()) {
- *OutInterp = wrap(Interp);
- return 0;
- }
- *OutError = strdup(Error.c_str());
- return 1;
- }
- LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
- LLVMModuleRef M,
- unsigned OptLevel,
- char **OutError) {
- std::string Error;
- EngineBuilder builder(std::unique_ptr<Module>(unwrap(M)));
- builder.setEngineKind(EngineKind::JIT)
- .setErrorStr(&Error)
- .setOptLevel((CodeGenOpt::Level)OptLevel);
- if (ExecutionEngine *JIT = builder.create()) {
- *OutJIT = wrap(JIT);
- return 0;
- }
- *OutError = strdup(Error.c_str());
- return 1;
- }
- void LLVMInitializeMCJITCompilerOptions(LLVMMCJITCompilerOptions *PassedOptions,
- size_t SizeOfPassedOptions) {
- LLVMMCJITCompilerOptions options;
- memset(&options, 0, sizeof(options)); // Most fields are zero by default.
- options.CodeModel = LLVMCodeModelJITDefault;
- memcpy(PassedOptions, &options,
- std::min(sizeof(options), SizeOfPassedOptions));
- }
- LLVMBool LLVMCreateMCJITCompilerForModule(
- LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M,
- LLVMMCJITCompilerOptions *PassedOptions, size_t SizeOfPassedOptions,
- char **OutError) {
- LLVMMCJITCompilerOptions options;
- // If the user passed a larger sized options struct, then they were compiled
- // against a newer LLVM. Tell them that something is wrong.
- if (SizeOfPassedOptions > sizeof(options)) {
- *OutError = strdup(
- "Refusing to use options struct that is larger than my own; assuming "
- "LLVM library mismatch.");
- return 1;
- }
- // Defend against the user having an old version of the API by ensuring that
- // any fields they didn't see are cleared. We must defend against fields being
- // set to the bitwise equivalent of zero, and assume that this means "do the
- // default" as if that option hadn't been available.
- LLVMInitializeMCJITCompilerOptions(&options, sizeof(options));
- memcpy(&options, PassedOptions, SizeOfPassedOptions);
- TargetOptions targetOptions;
- targetOptions.EnableFastISel = options.EnableFastISel;
- std::unique_ptr<Module> Mod(unwrap(M));
- if (Mod)
- // Set function attribute "frame-pointer" based on
- // NoFramePointerElim.
- for (auto &F : *Mod) {
- auto Attrs = F.getAttributes();
- StringRef Value = options.NoFramePointerElim ? "all" : "none";
- Attrs = Attrs.addFnAttribute(F.getContext(), "frame-pointer", Value);
- F.setAttributes(Attrs);
- }
- std::string Error;
- EngineBuilder builder(std::move(Mod));
- builder.setEngineKind(EngineKind::JIT)
- .setErrorStr(&Error)
- .setOptLevel((CodeGenOpt::Level)options.OptLevel)
- .setTargetOptions(targetOptions);
- bool JIT;
- if (std::optional<CodeModel::Model> CM = unwrap(options.CodeModel, JIT))
- builder.setCodeModel(*CM);
- if (options.MCJMM)
- builder.setMCJITMemoryManager(
- std::unique_ptr<RTDyldMemoryManager>(unwrap(options.MCJMM)));
- if (ExecutionEngine *JIT = builder.create()) {
- *OutJIT = wrap(JIT);
- return 0;
- }
- *OutError = strdup(Error.c_str());
- return 1;
- }
- void LLVMDisposeExecutionEngine(LLVMExecutionEngineRef EE) {
- delete unwrap(EE);
- }
- void LLVMRunStaticConstructors(LLVMExecutionEngineRef EE) {
- unwrap(EE)->finalizeObject();
- unwrap(EE)->runStaticConstructorsDestructors(false);
- }
- void LLVMRunStaticDestructors(LLVMExecutionEngineRef EE) {
- unwrap(EE)->finalizeObject();
- unwrap(EE)->runStaticConstructorsDestructors(true);
- }
- int LLVMRunFunctionAsMain(LLVMExecutionEngineRef EE, LLVMValueRef F,
- unsigned ArgC, const char * const *ArgV,
- const char * const *EnvP) {
- unwrap(EE)->finalizeObject();
- std::vector<std::string> ArgVec(ArgV, ArgV + ArgC);
- return unwrap(EE)->runFunctionAsMain(unwrap<Function>(F), ArgVec, EnvP);
- }
- LLVMGenericValueRef LLVMRunFunction(LLVMExecutionEngineRef EE, LLVMValueRef F,
- unsigned NumArgs,
- LLVMGenericValueRef *Args) {
- unwrap(EE)->finalizeObject();
- std::vector<GenericValue> ArgVec;
- ArgVec.reserve(NumArgs);
- for (unsigned I = 0; I != NumArgs; ++I)
- ArgVec.push_back(*unwrap(Args[I]));
- GenericValue *Result = new GenericValue();
- *Result = unwrap(EE)->runFunction(unwrap<Function>(F), ArgVec);
- return wrap(Result);
- }
- void LLVMFreeMachineCodeForFunction(LLVMExecutionEngineRef EE, LLVMValueRef F) {
- }
- void LLVMAddModule(LLVMExecutionEngineRef EE, LLVMModuleRef M){
- unwrap(EE)->addModule(std::unique_ptr<Module>(unwrap(M)));
- }
- LLVMBool LLVMRemoveModule(LLVMExecutionEngineRef EE, LLVMModuleRef M,
- LLVMModuleRef *OutMod, char **OutError) {
- Module *Mod = unwrap(M);
- unwrap(EE)->removeModule(Mod);
- *OutMod = wrap(Mod);
- return 0;
- }
- LLVMBool LLVMFindFunction(LLVMExecutionEngineRef EE, const char *Name,
- LLVMValueRef *OutFn) {
- if (Function *F = unwrap(EE)->FindFunctionNamed(Name)) {
- *OutFn = wrap(F);
- return 0;
- }
- return 1;
- }
- void *LLVMRecompileAndRelinkFunction(LLVMExecutionEngineRef EE,
- LLVMValueRef Fn) {
- return nullptr;
- }
- LLVMTargetDataRef LLVMGetExecutionEngineTargetData(LLVMExecutionEngineRef EE) {
- return wrap(&unwrap(EE)->getDataLayout());
- }
- LLVMTargetMachineRef
- LLVMGetExecutionEngineTargetMachine(LLVMExecutionEngineRef EE) {
- return wrap(unwrap(EE)->getTargetMachine());
- }
- void LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
- void* Addr) {
- unwrap(EE)->addGlobalMapping(unwrap<GlobalValue>(Global), Addr);
- }
- void *LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global) {
- unwrap(EE)->finalizeObject();
- return unwrap(EE)->getPointerToGlobal(unwrap<GlobalValue>(Global));
- }
- uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name) {
- return unwrap(EE)->getGlobalValueAddress(Name);
- }
- uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name) {
- return unwrap(EE)->getFunctionAddress(Name);
- }
- LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE,
- char **OutError) {
- assert(OutError && "OutError must be non-null");
- auto *ExecEngine = unwrap(EE);
- if (ExecEngine->hasError()) {
- *OutError = strdup(ExecEngine->getErrorMessage().c_str());
- ExecEngine->clearErrorMessage();
- return true;
- }
- return false;
- }
- /*===-- Operations on memory managers -------------------------------------===*/
- namespace {
- struct SimpleBindingMMFunctions {
- LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection;
- LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection;
- LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory;
- LLVMMemoryManagerDestroyCallback Destroy;
- };
- class SimpleBindingMemoryManager : public RTDyldMemoryManager {
- public:
- SimpleBindingMemoryManager(const SimpleBindingMMFunctions& Functions,
- void *Opaque);
- ~SimpleBindingMemoryManager() override;
- uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID,
- StringRef SectionName) override;
- uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID, StringRef SectionName,
- bool isReadOnly) override;
- bool finalizeMemory(std::string *ErrMsg) override;
- private:
- SimpleBindingMMFunctions Functions;
- void *Opaque;
- };
- SimpleBindingMemoryManager::SimpleBindingMemoryManager(
- const SimpleBindingMMFunctions& Functions,
- void *Opaque)
- : Functions(Functions), Opaque(Opaque) {
- assert(Functions.AllocateCodeSection &&
- "No AllocateCodeSection function provided!");
- assert(Functions.AllocateDataSection &&
- "No AllocateDataSection function provided!");
- assert(Functions.FinalizeMemory &&
- "No FinalizeMemory function provided!");
- assert(Functions.Destroy &&
- "No Destroy function provided!");
- }
- SimpleBindingMemoryManager::~SimpleBindingMemoryManager() {
- Functions.Destroy(Opaque);
- }
- uint8_t *SimpleBindingMemoryManager::allocateCodeSection(
- uintptr_t Size, unsigned Alignment, unsigned SectionID,
- StringRef SectionName) {
- return Functions.AllocateCodeSection(Opaque, Size, Alignment, SectionID,
- SectionName.str().c_str());
- }
- uint8_t *SimpleBindingMemoryManager::allocateDataSection(
- uintptr_t Size, unsigned Alignment, unsigned SectionID,
- StringRef SectionName, bool isReadOnly) {
- return Functions.AllocateDataSection(Opaque, Size, Alignment, SectionID,
- SectionName.str().c_str(),
- isReadOnly);
- }
- bool SimpleBindingMemoryManager::finalizeMemory(std::string *ErrMsg) {
- char *errMsgCString = nullptr;
- bool result = Functions.FinalizeMemory(Opaque, &errMsgCString);
- assert((result || !errMsgCString) &&
- "Did not expect an error message if FinalizeMemory succeeded");
- if (errMsgCString) {
- if (ErrMsg)
- *ErrMsg = errMsgCString;
- free(errMsgCString);
- }
- return result;
- }
- } // anonymous namespace
- LLVMMCJITMemoryManagerRef LLVMCreateSimpleMCJITMemoryManager(
- void *Opaque,
- LLVMMemoryManagerAllocateCodeSectionCallback AllocateCodeSection,
- LLVMMemoryManagerAllocateDataSectionCallback AllocateDataSection,
- LLVMMemoryManagerFinalizeMemoryCallback FinalizeMemory,
- LLVMMemoryManagerDestroyCallback Destroy) {
- if (!AllocateCodeSection || !AllocateDataSection || !FinalizeMemory ||
- !Destroy)
- return nullptr;
- SimpleBindingMMFunctions functions;
- functions.AllocateCodeSection = AllocateCodeSection;
- functions.AllocateDataSection = AllocateDataSection;
- functions.FinalizeMemory = FinalizeMemory;
- functions.Destroy = Destroy;
- return wrap(new SimpleBindingMemoryManager(functions, Opaque));
- }
- void LLVMDisposeMCJITMemoryManager(LLVMMCJITMemoryManagerRef MM) {
- delete unwrap(MM);
- }
- /*===-- JIT Event Listener functions -------------------------------------===*/
- #if !LLVM_USE_INTEL_JITEVENTS
- LLVMJITEventListenerRef LLVMCreateIntelJITEventListener(void)
- {
- return nullptr;
- }
- #endif
- #if !LLVM_USE_OPROFILE
- LLVMJITEventListenerRef LLVMCreateOProfileJITEventListener(void)
- {
- return nullptr;
- }
- #endif
- #if !LLVM_USE_PERF
- LLVMJITEventListenerRef LLVMCreatePerfJITEventListener(void)
- {
- return nullptr;
- }
- #endif
|