Skip to content

Commit

Permalink
[Orc] Add experimental C bindings for Orc.
Browse files Browse the repository at this point in the history
llvm-svn: 251472
  • Loading branch information
lhames committed Oct 28, 2015
1 parent a3eda37 commit ec61510
Show file tree
Hide file tree
Showing 10 changed files with 658 additions and 3 deletions.
111 changes: 111 additions & 0 deletions llvm/include/llvm-c/OrcBindings.h
Original file line number Diff line number Diff line change
@@ -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 changes: 2 additions & 0 deletions llvm/lib/ExecutionEngine/Orc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ add_llvm_library(LLVMOrcJIT
ExecutionUtils.cpp
IndirectionUtils.cpp
NullResolver.cpp
OrcCBindings.cpp
OrcCBindingsStack.cpp
OrcMCJITReplacement.cpp
OrcTargetSupport.cpp

Expand Down
80 changes: 80 additions & 0 deletions llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp
Original file line number Diff line number Diff line change
@@ -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 changes: 47 additions & 0 deletions llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp
Original file line number Diff line number Diff line change
@@ -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>>();
};
}
}
Loading

0 comments on commit ec61510

Please sign in to comment.