mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[Orc] Re-add C bindings for the Orc APIs, with a fix to remove the union that
was causing builder failures. The bindings were originally added in r251472, and reverted in r251473 due to the builder failures. llvm-svn: 251482
This commit is contained in:
parent
0ae2b702f7
commit
17ab368657
111
include/llvm-c/OrcBindings.h
Normal file
111
include/llvm-c/OrcBindings.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*===----------- llvm-c/OrcBindings.h - Orc Lib C Iface ---------*- C++ -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header declares the C interface to libLLVMOrcJIT.a, which implements *|
|
||||
|* JIT compilation of LLVM IR. *|
|
||||
|* *|
|
||||
|* Many exotic languages can interoperate with C code but have a harder time *|
|
||||
|* with C++ due to name mangling. So in addition to C, this interface enables *|
|
||||
|* tools written in such languages. *|
|
||||
|* *|
|
||||
|* Note: This interface is experimental. It is *NOT* stable, and may be *|
|
||||
|* changed without warning. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_C_ORCBINDINGS_H
|
||||
#define LLVM_C_ORCBINDINGS_H
|
||||
|
||||
#include "llvm-c/Object.h"
|
||||
#include "llvm-c/Support.h"
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
|
||||
typedef uint32_t LLVMOrcModuleHandle;
|
||||
typedef uint64_t LLVMOrcTargetAddress;
|
||||
typedef uint64_t (*LLVMOrcSymbolResolverFn)(const char *Name,
|
||||
void *LookupCtx);
|
||||
|
||||
/**
|
||||
* Create an ORC JIT stack.
|
||||
*
|
||||
* The client owns the resulting stack, and must call OrcDisposeInstance(...)
|
||||
* to destroy it and free its memory. The JIT stack will take ownership of the
|
||||
* TargetMachine, which will be destroyed when the stack is destroyed. The
|
||||
* client should not attempt to dispose of the Target Machine, or it will result
|
||||
* in a double-free.
|
||||
*/
|
||||
LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM,
|
||||
LLVMContextRef Context);
|
||||
|
||||
/**
|
||||
* Mangle the given symbol.
|
||||
* Memory will be allocated for MangledSymbol to hold the result. The client
|
||||
*/
|
||||
void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledSymbol,
|
||||
const char *Symbol);
|
||||
|
||||
/**
|
||||
* Dispose of a mangled symbol.
|
||||
*/
|
||||
|
||||
void LLVMOrcDisposeMangledSymbol(char *MangledSymbol);
|
||||
|
||||
/**
|
||||
* Add module to be eagerly compiled.
|
||||
*/
|
||||
LLVMOrcModuleHandle
|
||||
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
void *SymbolResolverCtx);
|
||||
|
||||
/**
|
||||
* Add module to be lazily compiled one function at a time.
|
||||
*/
|
||||
LLVMOrcModuleHandle
|
||||
LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
void *SymbolResolverCtx);
|
||||
|
||||
/**
|
||||
* Add an object file.
|
||||
*/
|
||||
LLVMOrcModuleHandle
|
||||
LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack, LLVMObjectFileRef Obj,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
void *SymbolResolverCtx);
|
||||
|
||||
/**
|
||||
* Remove a module set from the JIT.
|
||||
*
|
||||
* This works for all modules that can be added via OrcAdd*, including object
|
||||
* files.
|
||||
*/
|
||||
void LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, LLVMOrcModuleHandle H);
|
||||
|
||||
/**
|
||||
* Get symbol address from JIT instance.
|
||||
*/
|
||||
LLVMOrcTargetAddress LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
|
||||
const char *SymbolName);
|
||||
|
||||
/**
|
||||
* Dispose of an ORC JIT stack.
|
||||
*/
|
||||
void LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* extern "C" */
|
||||
|
||||
#endif /* LLVM_C_ORCBINDINGS_H */
|
@ -2,6 +2,8 @@ add_llvm_library(LLVMOrcJIT
|
||||
ExecutionUtils.cpp
|
||||
IndirectionUtils.cpp
|
||||
NullResolver.cpp
|
||||
OrcCBindings.cpp
|
||||
OrcCBindingsStack.cpp
|
||||
OrcMCJITReplacement.cpp
|
||||
OrcTargetSupport.cpp
|
||||
|
||||
|
80
lib/ExecutionEngine/Orc/OrcCBindings.cpp
Normal file
80
lib/ExecutionEngine/Orc/OrcCBindings.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
//===----------- OrcCBindings.cpp - C bindings for the Orc APIs -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "OrcCBindingsStack.h"
|
||||
#include "llvm-c/OrcBindings.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef);
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef);
|
||||
|
||||
LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM,
|
||||
LLVMContextRef Context) {
|
||||
TargetMachine *TM2(unwrap(TM));
|
||||
LLVMContext &Ctx = *unwrap(Context);
|
||||
|
||||
Triple T(TM2->getTargetTriple());
|
||||
|
||||
auto CallbackMgrBuilder = OrcCBindingsStack::createCallbackManagerBuilder(T);
|
||||
auto IndirectStubsMgrBuilder =
|
||||
OrcCBindingsStack::createIndirectStubsMgrBuilder(T);
|
||||
|
||||
OrcCBindingsStack *JITStack =
|
||||
new OrcCBindingsStack(*TM2, Ctx, CallbackMgrBuilder,
|
||||
IndirectStubsMgrBuilder);
|
||||
|
||||
return wrap(JITStack);
|
||||
}
|
||||
|
||||
void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledName,
|
||||
const char *SymbolName) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
std::string Mangled = J.mangle(SymbolName);
|
||||
*MangledName = new char[Mangled.size() + 1];
|
||||
strcpy(*MangledName, Mangled.c_str());
|
||||
}
|
||||
|
||||
void LLVMOrcDisposeMangledSymbol(char *MangledName) {
|
||||
delete[] MangledName;
|
||||
}
|
||||
|
||||
LLVMOrcModuleHandle
|
||||
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
void *SymbolResolverCtx) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
Module *M(unwrap(Mod));
|
||||
return J.addIRModuleEager(M, SymbolResolver, SymbolResolverCtx);
|
||||
}
|
||||
|
||||
LLVMOrcModuleHandle
|
||||
LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
void *SymbolResolverCtx) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
Module *M(unwrap(Mod));
|
||||
return J.addIRModuleLazy(M, SymbolResolver, SymbolResolverCtx);
|
||||
}
|
||||
|
||||
void LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack, LLVMOrcModuleHandle H) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
J.removeModule(H);
|
||||
}
|
||||
|
||||
LLVMOrcTargetAddress LLVMOrcGetSymbolAddress(LLVMOrcJITStackRef JITStack,
|
||||
const char *SymbolName) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
auto Sym = J.findSymbol(SymbolName, true);
|
||||
return Sym.getAddress();
|
||||
}
|
||||
|
||||
void LLVMOrcDisposeInstance(LLVMOrcJITStackRef JITStack) {
|
||||
delete unwrap(JITStack);
|
||||
}
|
47
lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp
Normal file
47
lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
//===-------- OrcCBindingsStack.cpp - Orc JIT stack for C bindings --------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "OrcCBindingsStack.h"
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include <cstdio>
|
||||
#include <system_error>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
OrcCBindingsStack::CallbackManagerBuilder
|
||||
OrcCBindingsStack::createCallbackManagerBuilder(Triple T) {
|
||||
switch (T.getArch()) {
|
||||
default: return nullptr;
|
||||
|
||||
case Triple::x86_64: {
|
||||
typedef orc::JITCompileCallbackManager<CompileLayerT,
|
||||
orc::OrcX86_64> CCMgrT;
|
||||
return [](CompileLayerT &CompileLayer, RuntimeDyld::MemoryManager &MemMgr,
|
||||
LLVMContext &Context) {
|
||||
return llvm::make_unique<CCMgrT>(CompileLayer, MemMgr, Context, 0,
|
||||
64);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OrcCBindingsStack::IndirectStubsManagerBuilder
|
||||
OrcCBindingsStack::createIndirectStubsMgrBuilder(Triple T) {
|
||||
switch (T.getArch()) {
|
||||
default: return nullptr;
|
||||
|
||||
case Triple::x86_64:
|
||||
return [](){
|
||||
return llvm::make_unique<orc::IndirectStubsManager<orc::OrcX86_64>>();
|
||||
};
|
||||
}
|
||||
}
|
261
lib/ExecutionEngine/Orc/OrcCBindingsStack.h
Normal file
261
lib/ExecutionEngine/Orc/OrcCBindingsStack.h
Normal file
@ -0,0 +1,261 @@
|
||||
//===--- OrcCBindingsStack.h - Orc JIT stack for C bindings ---*- C++ -*---===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
||||
#define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class OrcCBindingsStack {
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
typedef orc::TargetAddress (*CExternalSymbolResolverFn)(const char *Name,
|
||||
void *Ctx);
|
||||
|
||||
typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr;
|
||||
typedef orc::ObjectLinkingLayer<> ObjLayerT;
|
||||
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
|
||||
typedef orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr> CODLayerT;
|
||||
|
||||
typedef std::function<
|
||||
std::unique_ptr<CompileCallbackMgr>(CompileLayerT&,
|
||||
RuntimeDyld::MemoryManager&,
|
||||
LLVMContext&)>
|
||||
CallbackManagerBuilder;
|
||||
|
||||
typedef CODLayerT::IndirectStubsManagerBuilderT IndirectStubsManagerBuilder;
|
||||
|
||||
private:
|
||||
|
||||
class GenericHandle {
|
||||
public:
|
||||
virtual ~GenericHandle() {}
|
||||
virtual orc::JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) = 0;
|
||||
virtual void removeModule() = 0;
|
||||
};
|
||||
|
||||
template <typename LayerT>
|
||||
class GenericHandleImpl : public GenericHandle {
|
||||
public:
|
||||
GenericHandleImpl(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle)
|
||||
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||
|
||||
orc::JITSymbol findSymbolIn(const std::string &Name,
|
||||
bool ExportedSymbolsOnly) override {
|
||||
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
void removeModule() override {
|
||||
return Layer.removeModuleSet(Handle);
|
||||
}
|
||||
|
||||
private:
|
||||
LayerT &Layer;
|
||||
typename LayerT::ModuleSetHandleT Handle;
|
||||
};
|
||||
|
||||
template <typename LayerT>
|
||||
std::unique_ptr<GenericHandleImpl<LayerT>>
|
||||
createGenericHandle(LayerT &Layer, typename LayerT::ModuleSetHandleT Handle) {
|
||||
return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
|
||||
std::move(Handle));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// We need a 'ModuleSetHandleT' to conform to the layer concept.
|
||||
typedef unsigned ModuleSetHandleT;
|
||||
|
||||
typedef unsigned ModuleHandleT;
|
||||
|
||||
static CallbackManagerBuilder createCallbackManagerBuilder(Triple T);
|
||||
static IndirectStubsManagerBuilder createIndirectStubsMgrBuilder(Triple T);
|
||||
|
||||
OrcCBindingsStack(TargetMachine &TM, LLVMContext &Context,
|
||||
CallbackManagerBuilder &BuildCallbackMgr,
|
||||
IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
|
||||
: DL(TM.createDataLayout()),
|
||||
ObjectLayer(),
|
||||
CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
|
||||
CCMgr(BuildCallbackMgr(CompileLayer, CCMgrMemMgr, Context)),
|
||||
CODLayer(CompileLayer,
|
||||
[](Function &F) { std::set<Function*> S; S.insert(&F); return S; },
|
||||
*CCMgr, std::move(IndirectStubsMgrBuilder), false),
|
||||
CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
|
||||
|
||||
~OrcCBindingsStack() {
|
||||
// Run any destructors registered with __cxa_atexit.
|
||||
CXXRuntimeOverrides.runDestructors();
|
||||
// Run any IR destructors.
|
||||
for (auto &DtorRunner : IRStaticDestructorRunners)
|
||||
DtorRunner.runViaLayer(*this);
|
||||
}
|
||||
|
||||
std::string mangle(StringRef Name) {
|
||||
std::string MangledName;
|
||||
{
|
||||
raw_string_ostream MangledNameStream(MangledName);
|
||||
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
|
||||
}
|
||||
return MangledName;
|
||||
}
|
||||
|
||||
template <typename PtrTy>
|
||||
static PtrTy fromTargetAddress(orc::TargetAddress Addr) {
|
||||
return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
|
||||
}
|
||||
|
||||
std::shared_ptr<RuntimeDyld::SymbolResolver>
|
||||
createResolver(CExternalSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
auto Resolver = orc::createLambdaResolver(
|
||||
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
|
||||
// Search order:
|
||||
// 1. JIT'd symbols.
|
||||
// 2. Runtime overrides.
|
||||
// 3. External resolver (if present).
|
||||
|
||||
if (auto Sym = CODLayer.findSymbol(Name, true))
|
||||
return RuntimeDyld::SymbolInfo(Sym.getAddress(),
|
||||
Sym.getFlags());
|
||||
if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
|
||||
return Sym;
|
||||
|
||||
if (ExternalResolver)
|
||||
return RuntimeDyld::SymbolInfo(ExternalResolver(Name.c_str(),
|
||||
ExternalResolverCtx),
|
||||
llvm::JITSymbolFlags::Exported);
|
||||
|
||||
return RuntimeDyld::SymbolInfo(nullptr);
|
||||
},
|
||||
[](const std::string &Name) {
|
||||
return RuntimeDyld::SymbolInfo(nullptr);
|
||||
}
|
||||
);
|
||||
|
||||
return std::shared_ptr<RuntimeDyld::SymbolResolver>(std::move(Resolver));
|
||||
}
|
||||
|
||||
template <typename LayerT>
|
||||
ModuleHandleT addIRModule(LayerT &Layer,
|
||||
Module *M,
|
||||
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
|
||||
CExternalSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
|
||||
// Attach a data-layout if one isn't already present.
|
||||
if (M->getDataLayout().isDefault())
|
||||
M->setDataLayout(DL);
|
||||
|
||||
// Record the static constructors and destructors. We have to do this before
|
||||
// we hand over ownership of the module to the JIT.
|
||||
std::vector<std::string> CtorNames, DtorNames;
|
||||
for (auto Ctor : orc::getConstructors(*M))
|
||||
CtorNames.push_back(mangle(Ctor.Func->getName()));
|
||||
for (auto Dtor : orc::getDestructors(*M))
|
||||
DtorNames.push_back(mangle(Dtor.Func->getName()));
|
||||
|
||||
// Create the resolver.
|
||||
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||
|
||||
// Add the module to the JIT.
|
||||
std::vector<Module*> S;
|
||||
S.push_back(std::move(M));
|
||||
|
||||
auto LH = Layer.addModuleSet(std::move(S), std::move(MemMgr),
|
||||
std::move(Resolver));
|
||||
ModuleHandleT H = createHandle(Layer, LH);
|
||||
|
||||
// Run the static constructors, and save the static destructor runner for
|
||||
// execution when the JIT is torn down.
|
||||
orc::CtorDtorRunner<OrcCBindingsStack> CtorRunner(std::move(CtorNames), H);
|
||||
CtorRunner.runViaLayer(*this);
|
||||
|
||||
IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
|
||||
|
||||
return H;
|
||||
}
|
||||
|
||||
ModuleHandleT addIRModuleEager(Module* M,
|
||||
CExternalSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return addIRModule(CompileLayer, std::move(M),
|
||||
llvm::make_unique<SectionMemoryManager>(),
|
||||
std::move(ExternalResolver), ExternalResolverCtx);
|
||||
}
|
||||
|
||||
ModuleHandleT addIRModuleLazy(Module* M,
|
||||
CExternalSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return addIRModule(CODLayer, std::move(M), nullptr,
|
||||
std::move(ExternalResolver), ExternalResolverCtx);
|
||||
}
|
||||
|
||||
void removeModule(ModuleHandleT H) {
|
||||
GenericHandles[H]->removeModule();
|
||||
GenericHandles[H] = nullptr;
|
||||
FreeHandleIndexes.push_back(H);
|
||||
}
|
||||
|
||||
orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
|
||||
return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name,
|
||||
bool ExportedSymbolsOnly) {
|
||||
return GenericHandles[H]->findSymbolIn(Name, ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template <typename LayerT>
|
||||
unsigned createHandle(LayerT &Layer,
|
||||
typename LayerT::ModuleSetHandleT Handle) {
|
||||
unsigned NewHandle;
|
||||
if (!FreeHandleIndexes.empty()) {
|
||||
NewHandle = FreeHandleIndexes.back();
|
||||
FreeHandleIndexes.pop_back();
|
||||
GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
|
||||
return NewHandle;
|
||||
} else {
|
||||
NewHandle = GenericHandles.size();
|
||||
GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
|
||||
}
|
||||
return NewHandle;
|
||||
}
|
||||
|
||||
DataLayout DL;
|
||||
SectionMemoryManager CCMgrMemMgr;
|
||||
|
||||
ObjLayerT ObjectLayer;
|
||||
CompileLayerT CompileLayer;
|
||||
std::unique_ptr<CompileCallbackMgr> CCMgr;
|
||||
CODLayerT CODLayer;
|
||||
|
||||
std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
|
||||
std::vector<unsigned> FreeHandleIndexes;
|
||||
|
||||
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
|
||||
std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
|
@ -1,7 +1,11 @@
|
||||
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
Core
|
||||
OrcJIT
|
||||
MC
|
||||
Support
|
||||
Target
|
||||
native
|
||||
)
|
||||
|
||||
add_llvm_unittest(OrcJITTests
|
||||
@ -10,5 +14,6 @@ add_llvm_unittest(OrcJITTests
|
||||
GlobalMappingLayerTest.cpp
|
||||
LazyEmittingLayerTest.cpp
|
||||
ObjectTransformLayerTest.cpp
|
||||
OrcCAPITest.cpp
|
||||
OrcTestCommon.cpp
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ namespace {
|
||||
|
||||
TEST(IndirectionUtilsTest, MakeStub) {
|
||||
ModuleBuilder MB(getGlobalContext(), "x86_64-apple-macosx10.10", "");
|
||||
Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>(MB.getModule(), "");
|
||||
Function *F = MB.createFunctionDecl<void(DummyStruct, DummyStruct)>("");
|
||||
SmallVector<AttributeSet, 4> Attrs;
|
||||
Attrs.push_back(
|
||||
AttributeSet::get(MB.getModule()->getContext(), 1U,
|
||||
|
109
unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
Normal file
109
unittests/ExecutionEngine/Orc/OrcCAPITest.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
//===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "OrcTestCommon.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "llvm-c/OrcBindings.h"
|
||||
#include "llvm-c/Target.h"
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef);
|
||||
|
||||
class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
|
||||
protected:
|
||||
|
||||
std::unique_ptr<Module> createTestModule(const Triple &TT) {
|
||||
ModuleBuilder MB(getGlobalContext(), TT.str(), "");
|
||||
Function *TestFunc = MB.createFunctionDecl<int()>("testFunc");
|
||||
Function *Main = MB.createFunctionDecl<int(int, char*[])>("main");
|
||||
|
||||
Main->getBasicBlockList().push_back(BasicBlock::Create(getGlobalContext()));
|
||||
IRBuilder<> B(&Main->back());
|
||||
Value* Result = B.CreateCall(TestFunc);
|
||||
B.CreateRet(Result);
|
||||
|
||||
return MB.takeModule();
|
||||
}
|
||||
|
||||
typedef int (*MainFnTy)(void);
|
||||
|
||||
static int myTestFuncImpl(void) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
static char *testFuncName;
|
||||
|
||||
static uint64_t myResolver(const char *Name, void *Ctx) {
|
||||
if (!strncmp(Name, testFuncName, 8))
|
||||
return (uint64_t)&myTestFuncImpl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
char *OrcCAPIExecutionTest::testFuncName = 0;
|
||||
|
||||
TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
|
||||
auto TM = getHostTargetMachineIfSupported();
|
||||
|
||||
if (!TM)
|
||||
return;
|
||||
|
||||
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
||||
|
||||
LLVMOrcJITStackRef JIT =
|
||||
LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
|
||||
|
||||
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
||||
|
||||
LLVMOrcModuleHandle H =
|
||||
LLVMOrcAddEagerlyCompiledIR(JIT, wrap(M.get()), myResolver, 0);
|
||||
MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
|
||||
int Result = MainFn();
|
||||
EXPECT_EQ(Result, 42)
|
||||
<< "Eagerly JIT'd code did not return expected result";
|
||||
|
||||
LLVMOrcRemoveModule(JIT, H);
|
||||
|
||||
LLVMOrcDisposeMangledSymbol(testFuncName);
|
||||
LLVMOrcDisposeInstance(JIT);
|
||||
}
|
||||
|
||||
TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
|
||||
auto TM = getHostTargetMachineIfSupported();
|
||||
|
||||
if (!TM)
|
||||
return;
|
||||
|
||||
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
||||
|
||||
LLVMOrcJITStackRef JIT =
|
||||
LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
|
||||
|
||||
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
||||
LLVMOrcModuleHandle H =
|
||||
LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, 0);
|
||||
MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
|
||||
int Result = MainFn();
|
||||
EXPECT_EQ(Result, 42)
|
||||
<< "Lazily JIT'd code did not return expected result";
|
||||
|
||||
LLVMOrcRemoveModule(JIT, H);
|
||||
|
||||
LLVMOrcDisposeMangledSymbol(testFuncName);
|
||||
LLVMOrcDisposeInstance(JIT);
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,8 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
bool OrcExecutionTest::NativeTargetInitialized = false;
|
||||
|
||||
ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple,
|
||||
StringRef Name)
|
||||
: M(new Module(Name, Context)),
|
||||
|
@ -20,21 +20,52 @@
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/TypeBuilder.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/Orc/JITSymbol.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// Base class for Orc tests that will execute code.
|
||||
class OrcExecutionTest {
|
||||
public:
|
||||
|
||||
OrcExecutionTest() {
|
||||
if (!NativeTargetInitialized) {
|
||||
InitializeNativeTarget();
|
||||
InitializeNativeTargetAsmParser();
|
||||
InitializeNativeTargetAsmPrinter();
|
||||
NativeTargetInitialized = true;
|
||||
}
|
||||
};
|
||||
|
||||
// Get a target machine for the host if it supports JIT execution.
|
||||
std::unique_ptr<TargetMachine> getHostTargetMachineIfSupported() {
|
||||
std::unique_ptr<TargetMachine> TM(EngineBuilder().selectTarget());
|
||||
|
||||
const Triple& TT = TM->getTargetTriple();
|
||||
|
||||
if (TT.getArch() == Triple::x86_64)
|
||||
return std::move(TM);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool NativeTargetInitialized;
|
||||
};
|
||||
|
||||
class ModuleBuilder {
|
||||
public:
|
||||
ModuleBuilder(LLVMContext &Context, StringRef Triple,
|
||||
StringRef Name);
|
||||
|
||||
template <typename FuncType>
|
||||
Function* createFunctionDecl(Module *M, StringRef Name) {
|
||||
Function* createFunctionDecl(StringRef Name) {
|
||||
return Function::Create(
|
||||
TypeBuilder<FuncType, false>::get(M->getContext()),
|
||||
GlobalValue::ExternalLinkage, Name, M);
|
||||
GlobalValue::ExternalLinkage, Name, M.get());
|
||||
}
|
||||
|
||||
Module* getModule() { return M.get(); }
|
||||
|
Loading…
Reference in New Issue
Block a user