1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[ORC] Add C API support for adding object files to an LLJIT instance.

This commit is contained in:
Lang Hames 2020-04-09 16:17:04 -07:00
parent e2925289c9
commit a737d1b399
5 changed files with 200 additions and 2 deletions

View File

@ -4,5 +4,6 @@ add_subdirectory(LLJITWithGDBRegistrationListener)
add_subdirectory(LLJITWithLazyReexports)
add_subdirectory(LLJITWithObjectCache)
add_subdirectory(LLJITWithObjectLinkingLayerPlugin)
add_subdirectory(OrcV2CBindingsAddObjectFile)
add_subdirectory(OrcV2CBindingsBasicUsage)
add_subdirectory(OrcV2CBindingsReflectProcessSymbols)

View File

@ -0,0 +1,15 @@
set(LLVM_LINK_COMPONENTS
Core
ExecutionEngine
IRReader
JITLink
MC
OrcJIT
Support
Target
nativecodegen
)
add_llvm_example(OrcV2CBindingsAddObjectFile
OrcV2CBindingsAddObjectFile.c
)

View File

@ -0,0 +1,157 @@
//===-------- BasicOrcV2CBindings.c - Basic OrcV2 C Bindings Demo ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "llvm-c/Core.h"
#include "llvm-c/Error.h"
#include "llvm-c/Initialization.h"
#include "llvm-c/Orc.h"
#include "llvm-c/Support.h"
#include "llvm-c/Target.h"
#include "llvm-c/TargetMachine.h"
#include <stdio.h>
int handleError(LLVMErrorRef Err) {
char *ErrMsg = LLVMGetErrorMessage(Err);
fprintf(stderr, "Error: %s\n", ErrMsg);
LLVMDisposeErrorMessage(ErrMsg);
return 1;
}
LLVMModuleRef createDemoModule(LLVMContextRef Ctx) {
// Create a new LLVM module.
LLVMModuleRef M = LLVMModuleCreateWithNameInContext("demo", Ctx);
// Add a "sum" function":
// - Create the function type and function instance.
LLVMTypeRef ParamTypes[] = {LLVMInt32Type(), LLVMInt32Type()};
LLVMTypeRef SumFunctionType =
LLVMFunctionType(LLVMInt32Type(), ParamTypes, 2, 0);
LLVMValueRef SumFunction = LLVMAddFunction(M, "sum", SumFunctionType);
// - Add a basic block to the function.
LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock(SumFunction, "entry");
// - Add an IR builder and point it at the end of the basic block.
LLVMBuilderRef Builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(Builder, EntryBB);
// - Get the two function arguments and use them co construct an "add"
// instruction.
LLVMValueRef SumArg0 = LLVMGetParam(SumFunction, 0);
LLVMValueRef SumArg1 = LLVMGetParam(SumFunction, 1);
LLVMValueRef Result = LLVMBuildAdd(Builder, SumArg0, SumArg1, "result");
// - Build the return instruction.
LLVMBuildRet(Builder, Result);
return M;
}
int main(int argc, char *argv[]) {
int MainResult = 0;
// Parse command line arguments and initialize LLVM Core.
LLVMParseCommandLineOptions(argc, (const char **)argv, "");
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
// Initialize native target codegen and asm printer.
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
// Create the JIT instance.
LLVMOrcLLJITRef J;
{
LLVMErrorRef Err;
if ((Err = LLVMOrcCreateLLJIT(&J, 0))) {
MainResult = handleError(Err);
goto llvm_shutdown;
}
}
// Create our demo object file.
LLVMMemoryBufferRef ObjectFileBuffer;
{
// Create a module.
LLVMContextRef Ctx = LLVMContextCreate();
LLVMModuleRef M = createDemoModule(Ctx);
// Get the Target.
const char *Triple = LLVMOrcLLJITGetTripleString(J);
LLVMTargetRef Target = 0;
char *ErrorMsg = 0;
if (LLVMGetTargetFromTriple(Triple, &Target, &ErrorMsg)) {
fprintf(stderr, "Error getting target for %s: %s\n", Triple, ErrorMsg);
LLVMDisposeModule(M);
LLVMContextDispose(Ctx);
goto jit_cleanup;
}
// Construct a TargetMachine.
LLVMTargetMachineRef TM =
LLVMCreateTargetMachine(Target, Triple, "", "", LLVMCodeGenLevelNone,
LLVMRelocDefault, LLVMCodeModelDefault);
// Run CodeGen to produce the buffer.
if (LLVMTargetMachineEmitToMemoryBuffer(TM, M, LLVMObjectFile, &ErrorMsg,
&ObjectFileBuffer)) {
fprintf(stderr, "Error emitting object: %s\n", ErrorMsg);
LLVMDisposeTargetMachine(TM);
LLVMDisposeModule(M);
LLVMContextDispose(Ctx);
goto jit_cleanup;
}
}
// Add our object file buffer to the JIT.
{
LLVMErrorRef Err;
if ((Err = LLVMOrcLLJITAddObjectFile(J, ObjectFileBuffer))) {
MainResult = handleError(Err);
goto jit_cleanup;
}
}
// Look up the address of our demo entry point.
LLVMOrcJITTargetAddress SumAddr;
{
LLVMErrorRef Err;
if ((Err = LLVMOrcLLJITLookup(J, &SumAddr, "sum"))) {
MainResult = handleError(Err);
goto jit_cleanup;
}
}
// If we made it here then everything succeeded. Execute our JIT'd code.
int32_t (*Sum)(int32_t, int32_t) = (int32_t(*)(int32_t, int32_t))SumAddr;
int32_t Result = Sum(1, 2);
// Print the result.
printf("1 + 2 = %i\n", Result);
jit_cleanup:
// Destroy our JIT instance. This will clean up any memory that the JIT has
// taken ownership of. This operation is non-trivial (e.g. it may need to
// JIT static destructors) and may also fail. In that case we want to render
// the error to stderr, but not overwrite any existing return value.
{
LLVMErrorRef Err;
if ((Err = LLVMOrcDisposeLLJIT(J))) {
int NewFailureResult = handleError(Err);
if (MainResult == 0)
MainResult = NewFailureResult;
}
}
llvm_shutdown:
// Shut down LLVM.
LLVMShutdown();
return MainResult;
}

View File

@ -270,6 +270,12 @@ LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J);
*/
LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J);
/**
* Return the target triple for this LLJIT instance. This string is owned by
* the LLJIT instance and should not be freed by the client.
*/
const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J);
/**
* Returns the global prefix character according to the LLJIT's DataLayout.
*/
@ -285,10 +291,19 @@ char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
LLVMOrcSymbolStringPoolEntryRef
LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName);
/**
* Add a buffer representing an object file to the given LLJIT instance. This
* operation transfers ownership of the buffer to the LLJIT instance. The
* buffer should not be disposed of or referenced once this function returns.
*/
LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J,
LLVMMemoryBufferRef ObjBuffer);
/**
* Add an IR module to the main JITDylib of the given LLJIT instance. This
* operation takes ownership of the TSM argument which should not be disposed
* of or referenced once this function returns.
* operation transfers ownership of the TSM argument to the LLJIT instance.
* The TSM argument should not be 3disposed of or referenced once this
* function returns.
*/
LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
LLVMOrcThreadSafeModuleRef TSM);

View File

@ -190,6 +190,10 @@ LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J) {
return wrap(&unwrap(J)->getMainJITDylib());
}
const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J) {
return unwrap(J)->getTargetTriple().str().c_str();
}
char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J) {
return unwrap(J)->getDataLayout().getGlobalPrefix();
}
@ -200,6 +204,12 @@ LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName) {
unwrap(J)->mangleAndIntern(UnmangledName)));
}
LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J,
LLVMMemoryBufferRef ObjBuffer) {
return wrap(unwrap(J)->addObjectFile(
std::unique_ptr<MemoryBuffer>(unwrap(ObjBuffer))));
}
LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
LLVMOrcThreadSafeModuleRef TSM) {
return wrap(unwrap(J)->addIRModule(std::move(*unwrap(TSM))));