140 lines · c
1//===- OrcV2CBindingsDumpObjects.c - Dump JIT'd objects to disk via C API -===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// To run the demo build 'OrcV2CBindingsDumpObjects', then run the built10// program. It will execute as for OrcV2CBindingsBasicUsage, but will write11// a single JIT'd object out to the working directory.12//13// Try experimenting with the DumpDir and IdentifierOverride arguments to14// LLVMOrcCreateDumpObjects.15//16//===----------------------------------------------------------------------===//17 18#include "llvm-c/Core.h"19#include "llvm-c/Error.h"20#include "llvm-c/LLJIT.h"21#include "llvm-c/Support.h"22#include "llvm-c/Target.h"23 24#include <stdio.h>25 26int handleError(LLVMErrorRef Err) {27 char *ErrMsg = LLVMGetErrorMessage(Err);28 fprintf(stderr, "Error: %s\n", ErrMsg);29 LLVMDisposeErrorMessage(ErrMsg);30 return 1;31}32 33LLVMOrcThreadSafeModuleRef createDemoModule(void) {34 LLVMContextRef Ctx = LLVMContextCreate();35 LLVMModuleRef M = LLVMModuleCreateWithNameInContext("demo", Ctx);36 LLVMTypeRef ParamTypes[] = {LLVMInt32Type(), LLVMInt32Type()};37 LLVMTypeRef SumFunctionType =38 LLVMFunctionType(LLVMInt32Type(), ParamTypes, 2, 0);39 LLVMValueRef SumFunction = LLVMAddFunction(M, "sum", SumFunctionType);40 LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock(SumFunction, "entry");41 LLVMBuilderRef Builder = LLVMCreateBuilder();42 LLVMPositionBuilderAtEnd(Builder, EntryBB);43 LLVMValueRef SumArg0 = LLVMGetParam(SumFunction, 0);44 LLVMValueRef SumArg1 = LLVMGetParam(SumFunction, 1);45 LLVMValueRef Result = LLVMBuildAdd(Builder, SumArg0, SumArg1, "result");46 LLVMBuildRet(Builder, Result);47 LLVMOrcThreadSafeContextRef TSCtx =48 LLVMOrcCreateNewThreadSafeContextFromLLVMContext(Ctx);49 LLVMOrcThreadSafeModuleRef TSM = LLVMOrcCreateNewThreadSafeModule(M, TSCtx);50 LLVMOrcDisposeThreadSafeContext(TSCtx);51 return TSM;52}53 54LLVMErrorRef dumpObjectsTransform(void *Ctx, LLVMMemoryBufferRef *ObjInOut) {55 LLVMOrcDumpObjectsRef DumpObjects = *(LLVMOrcDumpObjectsRef *)Ctx;56 return LLVMOrcDumpObjects_CallOperator(DumpObjects, ObjInOut);57}58 59int main(int argc, const char *argv[]) {60 61 int MainResult = 0;62 63 LLVMParseCommandLineOptions(argc, argv, "");64 65 LLVMInitializeNativeTarget();66 LLVMInitializeNativeAsmPrinter();67 68 // Create a DumpObjects instance to use when dumping objects to disk.69 LLVMOrcDumpObjectsRef DumpObjects = LLVMOrcCreateDumpObjects("", "");70 71 // Create the JIT instance.72 LLVMOrcLLJITRef J;73 {74 LLVMErrorRef Err;75 if ((Err = LLVMOrcCreateLLJIT(&J, 0))) {76 MainResult = handleError(Err);77 goto llvm_shutdown;78 }79 }80 81 // Set an object transform to call our DumpObjects instance for every82 // JIT'd object.83 LLVMOrcObjectTransformLayerSetTransform(LLVMOrcLLJITGetObjTransformLayer(J),84 dumpObjectsTransform, &DumpObjects);85 86 // Create our demo module.87 LLVMOrcThreadSafeModuleRef TSM = createDemoModule();88 89 // Add our demo module to the JIT.90 {91 LLVMOrcJITDylibRef MainJD = LLVMOrcLLJITGetMainJITDylib(J);92 LLVMErrorRef Err;93 if ((Err = LLVMOrcLLJITAddLLVMIRModule(J, MainJD, TSM))) {94 // If adding the ThreadSafeModule fails then we need to clean it up95 // ourselves. If adding it succeeds the JIT will manage the memory.96 LLVMOrcDisposeThreadSafeModule(TSM);97 MainResult = handleError(Err);98 goto jit_cleanup;99 }100 }101 102 // Look up the address of our demo entry point.103 LLVMOrcJITTargetAddress SumAddr;104 {105 LLVMErrorRef Err;106 if ((Err = LLVMOrcLLJITLookup(J, &SumAddr, "sum"))) {107 MainResult = handleError(Err);108 goto jit_cleanup;109 }110 }111 112 // If we made it here then everything succeeded. Execute our JIT'd code.113 int32_t (*Sum)(int32_t, int32_t) = (int32_t(*)(int32_t, int32_t))SumAddr;114 int32_t Result = Sum(1, 2);115 116 // Print the result.117 printf("1 + 2 = %i\n", Result);118 119jit_cleanup:120 121 // Destroy our JIT instance.122 {123 LLVMErrorRef Err;124 if ((Err = LLVMOrcDisposeLLJIT(J))) {125 int NewFailureResult = handleError(Err);126 if (MainResult == 0)127 MainResult = NewFailureResult;128 }129 }130 131llvm_shutdown:132 // Destroy our DumpObjects instance.133 LLVMOrcDisposeDumpObjects(DumpObjects);134 135 // Shut down LLVM.136 LLVMShutdown();137 138 return MainResult;139}140