#include "llvm-c/Core.h"
#include "llvm-c/Error.h"
#include "llvm-c/Initialization.h"
#include "llvm-c/LLJIT.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) {
LLVMModuleRef M = LLVMModuleCreateWithNameInContext("demo", Ctx);
LLVMTypeRef ParamTypes[] = {LLVMInt32Type(), LLVMInt32Type()};
LLVMTypeRef SumFunctionType =
LLVMFunctionType(LLVMInt32Type(), ParamTypes, 2, 0);
LLVMValueRef SumFunction = LLVMAddFunction(M, "sum", SumFunctionType);
LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock(SumFunction, "entry");
LLVMBuilderRef Builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(Builder, EntryBB);
LLVMValueRef SumArg0 = LLVMGetParam(SumFunction, 0);
LLVMValueRef SumArg1 = LLVMGetParam(SumFunction, 1);
LLVMValueRef Result = LLVMBuildAdd(Builder, SumArg0, SumArg1, "result");
LLVMBuildRet(Builder, Result);
return M;
}
int main(int argc, char *argv[]) {
int MainResult = 0;
LLVMParseCommandLineOptions(argc, (const char **)argv, "");
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();
LLVMOrcLLJITRef J;
{
LLVMErrorRef Err;
if ((Err = LLVMOrcCreateLLJIT(&J, 0))) {
MainResult = handleError(Err);
goto llvm_shutdown;
}
}
LLVMMemoryBufferRef ObjectFileBuffer;
{
LLVMContextRef Ctx = LLVMContextCreate();
LLVMModuleRef M = createDemoModule(Ctx);
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;
}
LLVMTargetMachineRef TM =
LLVMCreateTargetMachine(Target, Triple, "", "", LLVMCodeGenLevelNone,
LLVMRelocDefault, LLVMCodeModelDefault);
if (LLVMTargetMachineEmitToMemoryBuffer(TM, M, LLVMObjectFile, &ErrorMsg,
&ObjectFileBuffer)) {
fprintf(stderr, "Error emitting object: %s\n", ErrorMsg);
LLVMDisposeTargetMachine(TM);
LLVMDisposeModule(M);
LLVMContextDispose(Ctx);
goto jit_cleanup;
}
}
{
LLVMOrcJITDylibRef MainJD = LLVMOrcLLJITGetMainJITDylib(J);
LLVMErrorRef Err;
if ((Err = LLVMOrcLLJITAddObjectFile(J, MainJD, ObjectFileBuffer))) {
MainResult = handleError(Err);
goto jit_cleanup;
}
}
LLVMOrcJITTargetAddress SumAddr;
{
LLVMErrorRef Err;
if ((Err = LLVMOrcLLJITLookup(J, &SumAddr, "sum"))) {
MainResult = handleError(Err);
goto jit_cleanup;
}
}
int32_t (*Sum)(int32_t, int32_t) = (int32_t(*)(int32_t, int32_t))SumAddr;
int32_t Result = Sum(1, 2);
printf("1 + 2 = %i\n", Result);
jit_cleanup:
{
LLVMErrorRef Err;
if ((Err = LLVMOrcDisposeLLJIT(J))) {
int NewFailureResult = handleError(Err);
if (MainResult == 0)
MainResult = NewFailureResult;
}
}
llvm_shutdown:
LLVMShutdown();
return MainResult;
}