150 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#include "llvm-c/Transforms/PassBuilder.h"24 25#include <stdio.h>26 27int handleError(LLVMErrorRef Err) {28 char *ErrMsg = LLVMGetErrorMessage(Err);29 fprintf(stderr, "Error: %s\n", ErrMsg);30 LLVMDisposeErrorMessage(ErrMsg);31 return 1;32}33 34LLVMOrcThreadSafeModuleRef createDemoModule(void) {35 LLVMContextRef Ctx = LLVMContextCreate();36 LLVMModuleRef M = LLVMModuleCreateWithNameInContext("demo", Ctx);37 LLVMTypeRef ParamTypes[] = {LLVMInt32Type(), LLVMInt32Type()};38 LLVMTypeRef SumFunctionType =39 LLVMFunctionType(LLVMInt32Type(), ParamTypes, 2, 0);40 LLVMValueRef SumFunction = LLVMAddFunction(M, "sum", SumFunctionType);41 LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock(SumFunction, "entry");42 LLVMBuilderRef Builder = LLVMCreateBuilder();43 LLVMPositionBuilderAtEnd(Builder, EntryBB);44 LLVMValueRef SumArg0 = LLVMGetParam(SumFunction, 0);45 LLVMValueRef SumArg1 = LLVMGetParam(SumFunction, 1);46 LLVMValueRef Result = LLVMBuildAdd(Builder, SumArg0, SumArg1, "result");47 LLVMBuildRet(Builder, Result);48 LLVMDisposeBuilder(Builder);49 LLVMOrcThreadSafeContextRef TSCtx =50 LLVMOrcCreateNewThreadSafeContextFromLLVMContext(Ctx);51 LLVMOrcThreadSafeModuleRef TSM = LLVMOrcCreateNewThreadSafeModule(M, TSCtx);52 LLVMOrcDisposeThreadSafeContext(TSCtx);53 return TSM;54}55 56LLVMErrorRef myModuleTransform(void *Ctx, LLVMModuleRef Mod) {57 LLVMPassBuilderOptionsRef Options = LLVMCreatePassBuilderOptions();58 LLVMErrorRef E = LLVMRunPasses(Mod, "instcombine", NULL, Options);59 LLVMDisposePassBuilderOptions(Options);60 return E;61}62 63LLVMErrorRef transform(void *Ctx, LLVMOrcThreadSafeModuleRef *ModInOut,64 LLVMOrcMaterializationResponsibilityRef MR) {65 return LLVMOrcThreadSafeModuleWithModuleDo(*ModInOut, myModuleTransform, Ctx);66}67 68int main(int argc, const char *argv[]) {69 70 int MainResult = 0;71 72 LLVMParseCommandLineOptions(argc, argv, "");73 74 LLVMInitializeNativeTarget();75 LLVMInitializeNativeAsmPrinter();76 77 // Create a DumpObjects instance to use when dumping objects to disk.78 LLVMOrcDumpObjectsRef DumpObjects = LLVMOrcCreateDumpObjects("", "");79 80 // Create the JIT instance.81 LLVMOrcLLJITRef J;82 {83 LLVMErrorRef Err;84 if ((Err = LLVMOrcCreateLLJIT(&J, 0))) {85 MainResult = handleError(Err);86 goto llvm_shutdown;87 }88 }89 90 // Use TransformLayer to set IR transform.91 {92 LLVMOrcIRTransformLayerRef TL = LLVMOrcLLJITGetIRTransformLayer(J);93 LLVMOrcIRTransformLayerSetTransform(TL, *transform, NULL);94 }95 96 // Create our demo module.97 LLVMOrcThreadSafeModuleRef TSM = createDemoModule();98 99 // Add our demo module to the JIT.100 {101 LLVMOrcJITDylibRef MainJD = LLVMOrcLLJITGetMainJITDylib(J);102 LLVMErrorRef Err;103 if ((Err = LLVMOrcLLJITAddLLVMIRModule(J, MainJD, TSM))) {104 // If adding the ThreadSafeModule fails then we need to clean it up105 // ourselves. If adding it succeeds the JIT will manage the memory.106 LLVMOrcDisposeThreadSafeModule(TSM);107 MainResult = handleError(Err);108 goto jit_cleanup;109 }110 }111 112 // Look up the address of our demo entry point.113 LLVMOrcJITTargetAddress SumAddr;114 {115 LLVMErrorRef Err;116 if ((Err = LLVMOrcLLJITLookup(J, &SumAddr, "sum"))) {117 MainResult = handleError(Err);118 goto jit_cleanup;119 }120 }121 122 // If we made it here then everything succeeded. Execute our JIT'd code.123 int32_t (*Sum)(int32_t, int32_t) = (int32_t(*)(int32_t, int32_t))SumAddr;124 int32_t Result = Sum(1, 2);125 126 // Print the result.127 printf("1 + 2 = %i\n", Result);128 129jit_cleanup:130 131 // Destroy our JIT instance.132 {133 LLVMErrorRef Err;134 if ((Err = LLVMOrcDisposeLLJIT(J))) {135 int NewFailureResult = handleError(Err);136 if (MainResult == 0)137 MainResult = NewFailureResult;138 }139 }140 141llvm_shutdown:142 // Destroy our DumpObjects instance.143 LLVMOrcDisposeDumpObjects(DumpObjects);144 145 // Shut down LLVM.146 LLVMShutdown();147 148 return MainResult;149}150