brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.7 KiB · 7e4d238 Raw
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