Add code to LLVM from its C-API.
authorVivek Pandya <vivekvpandya@gmail.com>
Sat, 19 Sep 2020 11:08:47 +0000 (16:38 +0530)
committerVivek Pandya <vivekvpandya@gmail.com>
Sat, 19 Sep 2020 11:08:47 +0000 (16:38 +0530)
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
src/libre-soc/vulkan/libresoc_llvm.c [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_llvm.h [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_private.h
src/libre-soc/vulkan/libresoc_shader.c
src/libre-soc/vulkan/libresoc_shader.h
src/libre-soc/vulkan/meson.build

index 546f175c7d8bc922fb199c847ee8cfdcd7822c84..898b3712654dc17896621e8dcb6eeff543bf1a74 100644 (file)
@@ -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 (file)
index 0000000..77248c8
--- /dev/null
@@ -0,0 +1,70 @@
+#include "libresoc_llvm.h"
+#include <llvm-c/OrcBindings.h>
+#include <llvm-c/Core.h>
+#include <llvm-c/Analysis.h>
+#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 (file)
index 0000000..ac57729
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef LIBRESOC_LLVM_H
+#define LIBRESOC_LLVM_H
+
+#include <llvm-c/OrcBindings.h>
+
+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
+
index 55a9cbb609076d8543b67c7240ace0600c93622f..a997dd70a3596c43811b52b6ff473d84c5709bfd 100644 (file)
@@ -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;
index 3d6d52f650994f36a49d966f5b4b9a7c07580b5d..d74b6b13d07f7c84f40c741a60ed47e961488c76 100644 (file)
@@ -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;
index f266106f491dc351d82d8c970edd839c5ae4ef56..14164ad3d1a5437bb73d58d3819725c20a03a08d 100644 (file)
@@ -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"
index e6f64a80d253e0f23f3b13d133b3c0b3c6ddf199..b8ba6d29c7cc4fe91f3261c1d11f384969ecfb07 100644 (file)
@@ -77,6 +77,7 @@ liblibresoc_files = files(
   'libresoc_wsi.c',
   'libresoc_private.h',
   'vk_format.h',
+  'libresoc_llvm.c',
 )
 
 libresoc_deps = []