From 20d458dc1ca837556446e389058afbe4f7adf5cd Mon Sep 17 00:00:00 2001 From: Vivek Pandya Date: Sat, 19 Sep 2020 16:38:47 +0530 Subject: [PATCH] Add code to LLVM from its C-API. To test if LLVM is created properly it just creates a dummy add function and dumps it on stderr. --- src/libre-soc/vulkan/libresoc_device.c | 11 ++-- src/libre-soc/vulkan/libresoc_llvm.c | 70 +++++++++++++++++++++++++ src/libre-soc/vulkan/libresoc_llvm.h | 19 +++++++ src/libre-soc/vulkan/libresoc_private.h | 2 + src/libre-soc/vulkan/libresoc_shader.c | 1 + src/libre-soc/vulkan/libresoc_shader.h | 1 + src/libre-soc/vulkan/meson.build | 1 + 7 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 src/libre-soc/vulkan/libresoc_llvm.c create mode 100644 src/libre-soc/vulkan/libresoc_llvm.h diff --git a/src/libre-soc/vulkan/libresoc_device.c b/src/libre-soc/vulkan/libresoc_device.c index 546f175c7d8..898b3712654 100644 --- a/src/libre-soc/vulkan/libresoc_device.c +++ b/src/libre-soc/vulkan/libresoc_device.c @@ -504,11 +504,12 @@ libresoc_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, libresoc_device_dispatch_table.entrypoints[i]; } } - instance->physical_devices_enumerated = false; - list_inithead(&instance->physical_devices); - glsl_type_singleton_init_or_ref(); - libresoc_init_dri_options(instance); - *pInstance = libresoc_instance_to_handle(instance); + instance->physical_devices_enumerated = false; + list_inithead(&instance->physical_devices); + glsl_type_singleton_init_or_ref(); + libresoc_init_dri_options(instance); + InitLLVM(&instance->llvm_ref); + *pInstance = libresoc_instance_to_handle(instance); return VK_SUCCESS; } diff --git a/src/libre-soc/vulkan/libresoc_llvm.c b/src/libre-soc/vulkan/libresoc_llvm.c new file mode 100644 index 00000000000..77248c8d530 --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_llvm.c @@ -0,0 +1,70 @@ +#include "libresoc_llvm.h" +#include +#include +#include +#include "nir/nir.h" +#include "nir/nir_deref.h" + +void InitLLVM(struct libresoc_llvm *llvm_ref) +{ + LLVMInitializeNativeTarget(); + LLVMInitializeNativeAsmPrinter(); + //LLVMLinkInMCJIT(); + char *def_triple = LLVMGetDefaultTargetTriple(); // E.g. "x86_64-linux-gnu" + char *error; + LLVMTargetRef target_ref; + if (LLVMGetTargetFromTriple(def_triple, &target_ref, &error)) { + // Fatal error + } + + if (!LLVMTargetHasJIT(target_ref)) { + // Fatal error, cannot do JIT on this platform + } + + LLVMTargetMachineRef tm_ref = + LLVMCreateTargetMachine(target_ref, def_triple, "", "", + LLVMCodeGenLevelDefault, + LLVMRelocDefault, + LLVMCodeModelJITDefault); + //assert(tm_ref); + LLVMDisposeErrorMessage(def_triple); + llvm_ref->orc_ref = LLVMOrcCreateInstance(tm_ref); + llvm_ref->context = LLVMContextCreate(); + llvm_ref->builder = LLVMCreateBuilderInContext(llvm_ref->context); +} + +void DestroyLLVM(struct libresoc_llvm *llvm_ref) +{ + LLVMErrorRef error_ref = LLVMOrcDisposeInstance(llvm_ref->orc_ref); +} + +static uint64_t orc_sym_resolver(const char *name, void *ctx) +{ + LLVMOrcJITStackRef orc_ref = (LLVMOrcJITStackRef) (ctx); + LLVMOrcTargetAddress address; + LLVMOrcGetSymbolAddress(orc_ref, &address, name); + return (uint64_t)address; +} + +void libresoc_nir_translate(struct libresoc_llvm *llvm_ref, struct nir_shader *nir) +{ + LLVMModuleRef mod = LLVMModuleCreateWithName("libresoc_mod"); + LLVMTypeRef param_types[] = { LLVMInt32Type(), LLVMInt32Type() }; + LLVMTypeRef ret_type = LLVMFunctionType(LLVMInt32Type(), param_types, 2, 0); + LLVMValueRef sum = LLVMAddFunction(mod, "sum", ret_type); + LLVMBasicBlockRef entry = LLVMAppendBasicBlock(sum, "entry"); + LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMPositionBuilderAtEnd(builder, entry); + LLVMValueRef tmp = LLVMBuildAdd(builder, LLVMGetParam(sum, 0), LLVMGetParam(sum, 1), "tmp"); + LLVMBuildRet(builder, tmp); + char *error = NULL; + LLVMVerifyModule(mod, LLVMAbortProcessAction, &error); + LLVMDumpModule(mod); + LLVMDisposeMessage(error); + LLVMOrcModuleHandle mod_handle; + LLVMErrorRef error_ref = LLVMOrcAddEagerlyCompiledIR(llvm_ref->orc_ref, + &mod_handle, + mod, + orc_sym_resolver, + (void *)(llvm_ref->orc_ref)); +} diff --git a/src/libre-soc/vulkan/libresoc_llvm.h b/src/libre-soc/vulkan/libresoc_llvm.h new file mode 100644 index 00000000000..ac577295911 --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_llvm.h @@ -0,0 +1,19 @@ +#ifndef LIBRESOC_LLVM_H +#define LIBRESOC_LLVM_H + +#include + +struct nir_shader; + +struct libresoc_llvm { + LLVMOrcJITStackRef orc_ref; + LLVMContextRef context; + LLVMBuilderRef builder; +}; + +void InitLLVM(struct libresoc_llvm *llvm_ref); +void DestroyLLVM(struct libresoc_llvm *llvm_ref); + +void libresoc_nir_translate(struct libresoc_llvm *llvm_ref, struct nir_shader *nir); +#endif + diff --git a/src/libre-soc/vulkan/libresoc_private.h b/src/libre-soc/vulkan/libresoc_private.h index 55a9cbb6090..a997dd70a35 100644 --- a/src/libre-soc/vulkan/libresoc_private.h +++ b/src/libre-soc/vulkan/libresoc_private.h @@ -45,6 +45,7 @@ #include "libresoc_extensions.h" #include "libresoc_constants.h" #include "libresoc_debug.h" +#include "libresoc_llvm.h" #include "wsi_common.h" #define LIBRESOC_MAX_QUEUE_FAMILIES 1 @@ -324,6 +325,7 @@ struct libresoc_instance { struct driOptionCache dri_options; struct driOptionCache available_dri_options; struct vk_debug_report_instance debug_report_callbacks; + struct libresoc_llvm llvm_ref; }; struct libresoc_deferred_queue_submission; diff --git a/src/libre-soc/vulkan/libresoc_shader.c b/src/libre-soc/vulkan/libresoc_shader.c index 3d6d52f6509..d74b6b13d07 100644 --- a/src/libre-soc/vulkan/libresoc_shader.c +++ b/src/libre-soc/vulkan/libresoc_shader.c @@ -164,6 +164,7 @@ libresoc_shader_compile_to_nir(struct libresoc_device *device, if (device->instance->debug_flags & LIBRESOC_DEBUG_DUMP_NIR) nir_print_shader(nir, stderr); + libresoc_nir_translate(&device->instance->llvm_ref, nir); free(spec_entries); } return nir; diff --git a/src/libre-soc/vulkan/libresoc_shader.h b/src/libre-soc/vulkan/libresoc_shader.h index f266106f491..14164ad3d1a 100644 --- a/src/libre-soc/vulkan/libresoc_shader.h +++ b/src/libre-soc/vulkan/libresoc_shader.h @@ -29,6 +29,7 @@ #define LIBRESOC_SHADER_H #include "libresoc_constants.h" +#include "libresoc_llvm.h" #include "util/mesa-sha1.h" #include "nir/nir.h" diff --git a/src/libre-soc/vulkan/meson.build b/src/libre-soc/vulkan/meson.build index e6f64a80d25..b8ba6d29c7c 100644 --- a/src/libre-soc/vulkan/meson.build +++ b/src/libre-soc/vulkan/meson.build @@ -77,6 +77,7 @@ liblibresoc_files = files( 'libresoc_wsi.c', 'libresoc_private.h', 'vk_format.h', + 'libresoc_llvm.c', ) libresoc_deps = [] -- 2.30.2