1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[Orc] Add experimental C bindings for Orc.

llvm-svn: 251472
This commit is contained in:
Lang Hames 2015-10-28 00:28:26 +00:00
parent a635879725
commit ec967600c9
10 changed files with 658 additions and 3 deletions

View 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 */

View File

@ -2,6 +2,8 @@ add_llvm_library(LLVMOrcJIT
ExecutionUtils.cpp ExecutionUtils.cpp
IndirectionUtils.cpp IndirectionUtils.cpp
NullResolver.cpp NullResolver.cpp
OrcCBindings.cpp
OrcCBindingsStack.cpp
OrcMCJITReplacement.cpp OrcMCJITReplacement.cpp
OrcTargetSupport.cpp OrcTargetSupport.cpp

View 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);
}

View 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>>();
};
}
}

View File

@ -0,0 +1,268 @@
//===--- 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:
typedef enum { Invalid, CODLayerHandle, ObjectLayerHandle } HandleType;
union RawHandleUnion {
RawHandleUnion() { memset(this, 0, sizeof(RawHandleUnion)); }
ObjLayerT::ObjSetHandleT Obj;
CODLayerT::ModuleSetHandleT COD;
};
struct ModuleHandleData {
ModuleHandleData() : Type(Invalid) {}
ModuleHandleData(ObjLayerT::ObjSetHandleT H)
: Type(ObjectLayerHandle) {
RawHandle.Obj = std::move(H);
}
ModuleHandleData(CODLayerT::ModuleSetHandleT H)
: Type(CODLayerHandle) {
RawHandle.COD = std::move(H);
}
HandleType Type;
RawHandleUnion RawHandle;
};
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(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) {
auto &HD = HandleData[H];
switch (HD.Type) {
case ObjectLayerHandle:
ObjectLayer.removeObjectSet(HD.RawHandle.Obj);
break;
case CODLayerHandle:
CODLayer.removeModuleSet(HD.RawHandle.COD);
break;
default:
llvm_unreachable("removeModule called on invalid handle type");
}
}
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) {
auto &HD = HandleData[H];
switch (HD.Type) {
case ObjectLayerHandle:
return ObjectLayer.findSymbolIn(HD.RawHandle.Obj, mangle(Name),
ExportedSymbolsOnly);
case CODLayerHandle:
return CODLayer.findSymbolIn(HD.RawHandle.COD, mangle(Name),
ExportedSymbolsOnly);
default:
llvm_unreachable("removeModule called on invalid handle type");
}
}
private:
template <typename LayerHandleT>
unsigned createHandle(LayerHandleT LH) {
unsigned NewHandle;
if (!FreeHandles.empty()) {
NewHandle = FreeHandles.back();
FreeHandles.pop_back();
HandleData[NewHandle] = ModuleHandleData(std::move(LH));
return NewHandle;
} else {
NewHandle = HandleData.size();
HandleData.push_back(ModuleHandleData(std::move(LH)));
}
return NewHandle;
}
DataLayout DL;
SectionMemoryManager CCMgrMemMgr;
ObjLayerT ObjectLayer;
CompileLayerT CompileLayer;
std::unique_ptr<CompileCallbackMgr> CCMgr;
CODLayerT CODLayer;
std::vector<ModuleHandleData> HandleData;
std::vector<unsigned> FreeHandles;
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
std::vector<orc::CtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
};
} // end namespace llvm
#endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H

View File

@ -1,7 +1,11 @@
set(LLVM_LINK_COMPONENTS set(LLVM_LINK_COMPONENTS
Core Core
OrcJIT OrcJIT
MC
Support Support
Target
native
) )
add_llvm_unittest(OrcJITTests add_llvm_unittest(OrcJITTests
@ -10,5 +14,6 @@ add_llvm_unittest(OrcJITTests
GlobalMappingLayerTest.cpp GlobalMappingLayerTest.cpp
LazyEmittingLayerTest.cpp LazyEmittingLayerTest.cpp
ObjectTransformLayerTest.cpp ObjectTransformLayerTest.cpp
OrcCAPITest.cpp
OrcTestCommon.cpp OrcTestCommon.cpp
) )

View File

@ -18,7 +18,7 @@ namespace {
TEST(IndirectionUtilsTest, MakeStub) { TEST(IndirectionUtilsTest, MakeStub) {
ModuleBuilder MB(getGlobalContext(), "x86_64-apple-macosx10.10", ""); 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; SmallVector<AttributeSet, 4> Attrs;
Attrs.push_back( Attrs.push_back(
AttributeSet::get(MB.getModule()->getContext(), 1U, AttributeSet::get(MB.getModule()->getContext(), 1U,

View 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);
}
}

View File

@ -15,6 +15,8 @@
using namespace llvm; using namespace llvm;
bool OrcExecutionTest::NativeTargetInitialized = false;
ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple, ModuleBuilder::ModuleBuilder(LLVMContext &Context, StringRef Triple,
StringRef Name) StringRef Name)
: M(new Module(Name, Context)), : M(new Module(Name, Context)),

View File

@ -20,21 +20,52 @@
#include "llvm/IR/LLVMContext.h" #include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/IR/TypeBuilder.h" #include "llvm/IR/TypeBuilder.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/Orc/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/JITSymbol.h"
#include "llvm/Support/TargetSelect.h"
#include <memory> #include <memory>
namespace llvm { 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 { class ModuleBuilder {
public: public:
ModuleBuilder(LLVMContext &Context, StringRef Triple, ModuleBuilder(LLVMContext &Context, StringRef Triple,
StringRef Name); StringRef Name);
template <typename FuncType> template <typename FuncType>
Function* createFunctionDecl(Module *M, StringRef Name) { Function* createFunctionDecl(StringRef Name) {
return Function::Create( return Function::Create(
TypeBuilder<FuncType, false>::get(M->getContext()), TypeBuilder<FuncType, false>::get(M->getContext()),
GlobalValue::ExternalLinkage, Name, M); GlobalValue::ExternalLinkage, Name, M.get());
} }
Module* getModule() { return M.get(); } Module* getModule() { return M.get(); }