diff --git a/0001-26018_upstream_orcjit.patch b/0001-26018_upstream_orcjit.patch new file mode 100644 index 0000000000000000000000000000000000000000..5ed51cdf5ea6e9b6e3c4d4274a590fcc2b0c655a --- /dev/null +++ b/0001-26018_upstream_orcjit.patch @@ -0,0 +1,2670 @@ +From dec908554f1ae682843d2c20b7cdd5821c1fec85 Mon Sep 17 00:00:00 2001 +From: Yukari Chiba +Date: Fri, 3 Nov 2023 23:18:47 +0800 +Subject: [PATCH 1/2] llvmpipe: add an implementation with llvm orcjit + +--- + meson.build | 6 +- + meson_options.txt | 7 + + src/gallium/auxiliary/draw/draw_context.c | 4 + + src/gallium/auxiliary/draw/draw_llvm.c | 93 +- + src/gallium/auxiliary/draw/draw_llvm.h | 17 +- + src/gallium/auxiliary/gallivm/lp_bld_coro.c | 6 +- + src/gallium/auxiliary/gallivm/lp_bld_coro.h | 8 + + src/gallium/auxiliary/gallivm/lp_bld_init.c | 7 +- + src/gallium/auxiliary/gallivm/lp_bld_init.h | 41 +- + .../auxiliary/gallivm/lp_bld_init_orc.cpp | 943 ++++++++++++++++++ + src/gallium/auxiliary/meson.build | 6 +- + src/gallium/drivers/llvmpipe/lp_context.c | 20 +- + src/gallium/drivers/llvmpipe/lp_context.h | 4 + + src/gallium/drivers/llvmpipe/lp_screen.c | 4 + + src/gallium/drivers/llvmpipe/lp_state_cs.c | 18 + + src/gallium/drivers/llvmpipe/lp_state_cs.h | 3 + + src/gallium/drivers/llvmpipe/lp_state_fs.c | 33 + + src/gallium/drivers/llvmpipe/lp_state_fs.h | 6 + + .../llvmpipe/lp_state_fs_linear_llvm.c | 4 + + src/gallium/drivers/llvmpipe/lp_state_setup.c | 9 + + src/gallium/drivers/llvmpipe/lp_state_setup.h | 3 + + src/gallium/drivers/llvmpipe/lp_test_arit.c | 19 + + src/gallium/drivers/llvmpipe/lp_test_blend.c | 33 +- + src/gallium/drivers/llvmpipe/lp_test_conv.c | 33 +- + src/gallium/drivers/llvmpipe/lp_test_format.c | 50 +- + .../llvmpipe/lp_test_lookup_multiple.c | 172 ++++ + src/gallium/drivers/llvmpipe/lp_test_printf.c | 31 +- + .../drivers/llvmpipe/lp_texture_handle.c | 23 + + src/gallium/drivers/llvmpipe/meson.build | 2 +- + src/util/detect_arch.h | 23 + + 30 files changed, 1606 insertions(+), 22 deletions(-) + create mode 100644 src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp + create mode 100644 src/gallium/drivers/llvmpipe/lp_test_lookup_multiple.c + +diff --git a/meson.build b/meson.build +index 61d76eeab1f16..897778c8744f4 100644 +--- a/meson.build ++++ b/meson.build +@@ -1680,6 +1680,7 @@ if with_clc + llvm_optional_modules += ['all-targets', 'windowsdriver', 'frontendhlsl'] + endif + draw_with_llvm = get_option('draw-use-llvm') ++llvm_with_orcjit = get_option('llvm-orcjit') + if draw_with_llvm + llvm_modules += 'native' + # lto is needded with LLVM>=15, but we don't know what LLVM verrsion we are using yet +@@ -1688,7 +1689,7 @@ endif + + if with_amd_vk or with_gallium_radeonsi + _llvm_version = '>= 15.0.0' +-elif with_intel_clc ++elif with_intel_clc or llvm_with_orcjit + _llvm_version = '>= 13.0.0' + elif with_gallium_opencl + _llvm_version = '>= 11.0.0' +@@ -1729,6 +1730,9 @@ if with_llvm + + if draw_with_llvm + pre_args += '-DDRAW_LLVM_AVAILABLE' ++ if llvm_with_orcjit ++ pre_args += '-DGALLIVM_USE_ORCJIT=1' ++ endif + elif with_swrast_vk + error('Lavapipe requires LLVM draw support.') + endif +diff --git a/meson_options.txt b/meson_options.txt +index e885ba61a8af0..bd6518d1f0c36 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -681,3 +681,10 @@ option ( + value : 'disabled', + description: 'Enable Intel Xe KMD support.' + ) ++ ++option ( ++ 'llvm-orcjit', ++ type : 'boolean', ++ value : false, ++ description: 'Build llvmpipe with LLVM ORCJIT support.' ++) +diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c +index d2a37e5ad5b88..4d6cb707e163c 100644 +--- a/src/gallium/auxiliary/draw/draw_context.c ++++ b/src/gallium/auxiliary/draw/draw_context.c +@@ -77,7 +77,11 @@ draw_create_context(struct pipe_context *pipe, void *context, + + #ifdef DRAW_LLVM_AVAILABLE + if (try_llvm && draw_get_option_use_llvm()) { ++#if GALLIVM_USE_ORCJIT ++ draw->llvm = draw_llvm_create(draw, (LLVMOrcThreadSafeContextRef)context); ++#else + draw->llvm = draw_llvm_create(draw, (LLVMContextRef)context); ++#endif + } + #endif + +diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c +index f4e0d70cd32c1..2b2576d43d3d3 100644 +--- a/src/gallium/auxiliary/draw/draw_llvm.c ++++ b/src/gallium/auxiliary/draw/draw_llvm.c +@@ -381,8 +381,13 @@ get_vertex_header_ptr_type(struct draw_llvm_variant *variant) + /** + * Create per-context LLVM info. + */ ++#if GALLIVM_USE_ORCJIT ++struct draw_llvm * ++draw_llvm_create(struct draw_context *draw, LLVMOrcThreadSafeContextRef context) ++#else + struct draw_llvm * + draw_llvm_create(struct draw_context *draw, LLVMContextRef context) ++#endif + { + struct draw_llvm *llvm; + +@@ -395,6 +400,16 @@ draw_llvm_create(struct draw_context *draw, LLVMContextRef context) + + llvm->draw = draw; + ++#if GALLIVM_USE_ORCJIT ++ llvm->_ts_context = context; ++ if (!llvm->_ts_context) { ++ llvm->_ts_context = LLVMOrcCreateNewThreadSafeContext(); ++ llvm->context_owned = true; ++ } ++ if (!llvm->_ts_context) ++ goto fail; ++ llvm->context = LLVMOrcThreadSafeContextGetContext(llvm->_ts_context); ++#else + llvm->context = context; + if (!llvm->context) { + llvm->context = LLVMContextCreate(); +@@ -407,6 +422,7 @@ draw_llvm_create(struct draw_context *draw, LLVMContextRef context) + } + if (!llvm->context) + goto fail; ++#endif + + llvm->nr_variants = 0; + list_inithead(&llvm->vs_variants_list.list); +@@ -434,9 +450,16 @@ fail: + void + draw_llvm_destroy(struct draw_llvm *llvm) + { ++#if GALLIVM_USE_ORCJIT ++ if (llvm->context_owned) ++ LLVMOrcDisposeThreadSafeContext(llvm->_ts_context); ++ llvm->_ts_context = NULL; ++ llvm->context = NULL; ++#else + if (llvm->context_owned) + LLVMContextDispose(llvm->context); + llvm->context = NULL; ++#endif + + /* XXX free other draw_llvm data? */ + FREE(llvm); +@@ -510,7 +533,11 @@ draw_llvm_create_variant(struct draw_llvm *llvm, + if (!cached.data_size) + needs_caching = true; + } ++#if GALLIVM_USE_ORCJIT ++ variant->gallivm = gallivm_create(module_name, llvm->_ts_context, &cached); ++#else + variant->gallivm = gallivm_create(module_name, llvm->context, &cached); ++#endif + + create_vs_jit_types(variant); + +@@ -529,8 +556,13 @@ draw_llvm_create_variant(struct draw_llvm *llvm, + + gallivm_compile_module(variant->gallivm); + ++#if GALLIVM_USE_ORCJIT ++ variant->jit_func = (draw_jit_vert_func) ++ gallivm_jit_function(variant->gallivm, variant->function_name); ++#else + variant->jit_func = (draw_jit_vert_func) + gallivm_jit_function(variant->gallivm, variant->function); ++#endif + + if (needs_caching) + llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, +@@ -1631,6 +1663,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) + + variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); + variant->function = variant_func; ++#if GALLIVM_USE_ORCJIT ++ variant->function_name = MALLOC(strlen(func_name)+1); ++ strcpy(variant->function_name, func_name); ++#endif + + LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); + for (i = 0; i < num_arg_types; ++i) +@@ -2242,6 +2278,11 @@ draw_llvm_destroy_variant(struct draw_llvm_variant *variant) + variant->shader->variants_cached--; + list_del(&variant->list_item_global.list); + llvm->nr_variants--; ++ ++#if GALLIVM_USE_ORCJIT ++ if(variant->function_name) ++ FREE(variant->function_name); ++#endif + FREE(variant); + } + +@@ -2351,6 +2392,10 @@ draw_gs_llvm_generate(struct draw_llvm *llvm, + variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); + + variant->function = variant_func; ++#if GALLIVM_USE_ORCJIT ++ variant->function_name = MALLOC(strlen(func_name)+1); ++ strcpy(variant->function_name, func_name); ++#endif + + LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); + +@@ -2516,7 +2561,11 @@ draw_gs_llvm_create_variant(struct draw_llvm *llvm, + if (!cached.data_size) + needs_caching = true; + } ++#if GALLIVM_USE_ORCJIT ++ variant->gallivm = gallivm_create(module_name, llvm->_ts_context, &cached); ++#else + variant->gallivm = gallivm_create(module_name, llvm->context, &cached); ++#endif + + create_gs_jit_types(variant); + +@@ -2527,8 +2576,13 @@ draw_gs_llvm_create_variant(struct draw_llvm *llvm, + + gallivm_compile_module(variant->gallivm); + ++#if GALLIVM_USE_ORCJIT ++ variant->jit_func = (draw_gs_jit_func) ++ gallivm_jit_function(variant->gallivm, variant->function_name); ++#else + variant->jit_func = (draw_gs_jit_func) + gallivm_jit_function(variant->gallivm, variant->function); ++#endif + + if (needs_caching) + llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, +@@ -2561,6 +2615,10 @@ draw_gs_llvm_destroy_variant(struct draw_gs_llvm_variant *variant) + variant->shader->variants_cached--; + list_del(&variant->list_item_global.list); + llvm->nr_gs_variants--; ++#if GALLIVM_USE_ORCJIT ++ if(variant->function_name) ++ FREE(variant->function_name); ++#endif + FREE(variant); + } + +@@ -2934,6 +2992,10 @@ draw_tcs_llvm_generate(struct draw_llvm *llvm, + variant_coro = LLVMAddFunction(gallivm->module, func_name_coro, coro_func_type); + + variant->function = variant_func; ++#if GALLIVM_USE_ORCJIT ++ variant->function_name = MALLOC(strlen(func_name)+1); ++ strcpy(variant->function_name, func_name); ++#endif + LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); + + LLVMSetFunctionCallConv(variant_coro, LLVMCCallConv); +@@ -3169,8 +3231,11 @@ draw_tcs_llvm_create_variant(struct draw_llvm *llvm, + if (!cached.data_size) + needs_caching = true; + } +- ++#if GALLIVM_USE_ORCJIT ++ variant->gallivm = gallivm_create(module_name, llvm->_ts_context, &cached); ++#else + variant->gallivm = gallivm_create(module_name, llvm->context, &cached); ++#endif + + create_tcs_jit_types(variant); + +@@ -3183,8 +3248,13 @@ draw_tcs_llvm_create_variant(struct draw_llvm *llvm, + + gallivm_compile_module(variant->gallivm); + ++#if GALLIVM_USE_ORCJIT ++ variant->jit_func = (draw_tcs_jit_func) ++ gallivm_jit_function(variant->gallivm, variant->function_name); ++#else + variant->jit_func = (draw_tcs_jit_func) + gallivm_jit_function(variant->gallivm, variant->function); ++#endif + + if (needs_caching) + llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, +@@ -3217,6 +3287,10 @@ draw_tcs_llvm_destroy_variant(struct draw_tcs_llvm_variant *variant) + variant->shader->variants_cached--; + list_del(&variant->list_item_global.list); + llvm->nr_tcs_variants--; ++#if GALLIVM_USE_ORCJIT ++ if(variant->function_name) ++ FREE(variant->function_name); ++#endif + FREE(variant); + } + +@@ -3499,6 +3573,10 @@ draw_tes_llvm_generate(struct draw_llvm *llvm, + variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); + + variant->function = variant_func; ++#if GALLIVM_USE_ORCJIT ++ variant->function_name = MALLOC(strlen(func_name)+1); ++ strcpy(variant->function_name, func_name); ++#endif + LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); + + for (i = 0; i < ARRAY_SIZE(arg_types); ++i) +@@ -3689,7 +3767,11 @@ draw_tes_llvm_create_variant(struct draw_llvm *llvm, + if (!cached.data_size) + needs_caching = true; + } ++#if GALLIVM_USE_ORCJIT ++ variant->gallivm = gallivm_create(module_name, llvm->_ts_context, &cached); ++#else + variant->gallivm = gallivm_create(module_name, llvm->context, &cached); ++#endif + + create_tes_jit_types(variant); + +@@ -3705,8 +3787,13 @@ draw_tes_llvm_create_variant(struct draw_llvm *llvm, + + gallivm_compile_module(variant->gallivm); + ++#if GALLIVM_USE_ORCJIT ++ variant->jit_func = (draw_tes_jit_func) ++ gallivm_jit_function(variant->gallivm, variant->function_name); ++#else + variant->jit_func = (draw_tes_jit_func) + gallivm_jit_function(variant->gallivm, variant->function); ++#endif + + if (needs_caching) + llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, +@@ -3739,6 +3826,10 @@ draw_tes_llvm_destroy_variant(struct draw_tes_llvm_variant *variant) + variant->shader->variants_cached--; + list_del(&variant->list_item_global.list); + llvm->nr_tes_variants--; ++#if GALLIVM_USE_ORCJIT ++ if(variant->function_name) ++ FREE(variant->function_name); ++#endif + FREE(variant); + } + +diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h +index 65199feab1b7d..fec2c6add2aa2 100644 +--- a/src/gallium/auxiliary/draw/draw_llvm.h ++++ b/src/gallium/auxiliary/draw/draw_llvm.h +@@ -42,6 +42,9 @@ + #include "pipe/p_context.h" + #include "util/list.h" + ++#if GALLIVM_USE_ORCJIT ++#include ++#endif + + struct draw_llvm; + struct llvm_vertex_shader; +@@ -398,6 +401,7 @@ struct draw_llvm_variant + LLVMTypeRef vertex_header_ptr_type; + + LLVMValueRef function; ++ char *function_name; + draw_jit_vert_func jit_func; + + struct llvm_vertex_shader *shader; +@@ -431,6 +435,7 @@ struct draw_gs_llvm_variant + LLVMValueRef io_ptr; + LLVMValueRef num_prims; + LLVMValueRef function; ++ char *function_name; + draw_gs_jit_func jit_func; + + struct llvm_geometry_shader *shader; +@@ -457,6 +462,7 @@ struct draw_tcs_llvm_variant + /* LLVMValueRef io_ptr; */ + LLVMValueRef num_prims; + LLVMValueRef function; ++ char *function_name; + draw_tcs_jit_func jit_func; + + struct llvm_tess_ctrl_shader *shader; +@@ -487,6 +493,7 @@ struct draw_tes_llvm_variant + LLVMValueRef io_ptr; + LLVMValueRef num_prims; + LLVMValueRef function; ++ char *function_name; + draw_tes_jit_func jit_func; + + struct llvm_tess_eval_shader *shader; +@@ -539,6 +546,9 @@ struct draw_llvm { + struct draw_context *draw; + + LLVMContextRef context; ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef _ts_context; ++#endif + bool context_owned; + + struct draw_vs_jit_context vs_jit_context; +@@ -584,8 +594,13 @@ llvm_tess_eval_shader(struct draw_tess_eval_shader *tes) + return (struct llvm_tess_eval_shader *)tes; + } + ++#if GALLIVM_USE_ORCJIT + struct draw_llvm * +-draw_llvm_create(struct draw_context *draw, LLVMContextRef llvm_context); ++draw_llvm_create(struct draw_context *draw, LLVMOrcThreadSafeContextRef context); ++#else ++struct draw_llvm * ++draw_llvm_create(struct draw_context *draw, LLVMContextRef context); ++#endif + + void + draw_llvm_destroy(struct draw_llvm *llvm); +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_coro.c b/src/gallium/auxiliary/gallivm/lp_bld_coro.c +index 0214dcf674203..e5b4890d7ec00 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_coro.c ++++ b/src/gallium/auxiliary/gallivm/lp_bld_coro.c +@@ -156,12 +156,14 @@ coro_free(char *ptr) + + void lp_build_coro_add_malloc_hooks(struct gallivm_state *gallivm) + { ++#if !GALLIVM_USE_ORCJIT + assert(gallivm->engine); ++#endif + + assert(gallivm->coro_malloc_hook); + assert(gallivm->coro_free_hook); +- LLVMAddGlobalMapping(gallivm->engine, gallivm->coro_malloc_hook, coro_malloc); +- LLVMAddGlobalMapping(gallivm->engine, gallivm->coro_free_hook, coro_free); ++ gallivm_add_global_mapping(gallivm, gallivm->coro_malloc_hook, coro_malloc); ++ gallivm_add_global_mapping(gallivm, gallivm->coro_free_hook, coro_free); + } + + void lp_build_coro_declare_malloc_hooks(struct gallivm_state *gallivm) +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_coro.h b/src/gallium/auxiliary/gallivm/lp_bld_coro.h +index 2fbaecc31521a..5421d0926caf9 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_coro.h ++++ b/src/gallium/auxiliary/gallivm/lp_bld_coro.h +@@ -31,6 +31,10 @@ + #include "gallivm/lp_bld.h" + #include "gallivm/lp_bld_intr.h" + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + struct gallivm_state; + LLVMValueRef lp_build_coro_id(struct gallivm_state *gallivm); + +@@ -84,4 +88,8 @@ static inline void lp_build_coro_add_presplit(LLVMValueRef coro) + #endif + } + ++#ifdef __cplusplus ++} ++#endif ++ + #endif +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c +index cd2108f3a088d..41a62578375eb 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c ++++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c +@@ -515,6 +515,11 @@ gallivm_destroy(struct gallivm_state *gallivm) + FREE(gallivm); + } + ++void ++gallivm_add_global_mapping(struct gallivm_state *gallivm, LLVMValueRef sym, void* addr) ++{ ++ LLVMAddGlobalMapping(gallivm->engine, sym, addr); ++} + + /** + * Validate a function. +@@ -670,7 +675,7 @@ gallivm_compile_module(struct gallivm_state *gallivm) + ++gallivm->compiled; + + lp_init_printf_hook(gallivm); +- LLVMAddGlobalMapping(gallivm->engine, gallivm->debug_printf_hook, debug_printf); ++ gallivm_add_global_mapping(gallivm, gallivm->debug_printf_hook, debug_printf); + + lp_init_clock_hook(gallivm); + LLVMAddGlobalMapping(gallivm->engine, gallivm->get_time_hook, os_time_get_nano); +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h +index 418921cb7add4..0fe8466592cdc 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_init.h ++++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h +@@ -29,11 +29,14 @@ + #ifndef LP_BLD_INIT_H + #define LP_BLD_INIT_H + +- + #include "util/compiler.h" + #include "util/u_pointer.h" // for func_pointer + #include "lp_bld.h" ++#if GALLIVM_USE_ORCJIT ++#include ++#else + #include ++#endif + + #ifdef __cplusplus + extern "C" { +@@ -44,18 +47,27 @@ struct gallivm_state + { + char *module_name; + LLVMModuleRef module; +- LLVMExecutionEngineRef engine; + LLVMTargetDataRef target; ++#if GALLIVM_USE_ORCJIT ++ /* own this->module */ ++ LLVMOrcThreadSafeContextRef _ts_context; ++ /* each module is in its own jitdylib */ ++ LLVMOrcJITDylibRef _per_module_jd; ++#else ++ LLVMExecutionEngineRef engine; + #if GALLIVM_USE_NEW_PASS == 0 + LLVMPassManagerRef passmgr; + #if GALLIVM_HAVE_CORO == 1 + LLVMPassManagerRef cgpassmgr; + #endif + #endif +- LLVMContextRef context; +- LLVMBuilderRef builder; + LLVMMCJITMemoryManagerRef memorymgr; + struct lp_generated_code *code; ++#endif ++ ++ LLVMContextRef context; ++ LLVMBuilderRef builder; ++ + struct lp_cached_code *cache; + unsigned compiled; + LLVMValueRef coro_malloc_hook; +@@ -77,10 +89,15 @@ lp_build_init_native_width(void); + bool + lp_build_init(void); + +- ++#if GALLIVM_USE_ORCJIT ++struct gallivm_state * ++gallivm_create(const char *name, LLVMOrcThreadSafeContextRef context, ++ struct lp_cached_code *cache); ++#else + struct gallivm_state * + gallivm_create(const char *name, LLVMContextRef context, + struct lp_cached_code *cache); ++#endif + + void + gallivm_destroy(struct gallivm_state *gallivm); +@@ -93,11 +110,25 @@ gallivm_verify_function(struct gallivm_state *gallivm, + LLVMValueRef func); + + void ++gallivm_add_global_mapping(struct gallivm_state *gallivm, LLVMValueRef sym, void* addr); ++ ++/** ++ * for ORCJIT, after this function gets called, all access and modification to ++ * module and any structure associated to it should be avoided, ++ * as module has been moved into ORCJIT and may be recycled ++ */ ++void + gallivm_compile_module(struct gallivm_state *gallivm); + ++#if GALLIVM_USE_ORCJIT ++func_pointer ++gallivm_jit_function(struct gallivm_state *gallivm, ++ const char *func_name); ++#else + func_pointer + gallivm_jit_function(struct gallivm_state *gallivm, + LLVMValueRef func); ++#endif + + unsigned gallivm_get_perf_flags(void); + +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp +new file mode 100644 +index 0000000000000..6a74cc9b20f8f +--- /dev/null ++++ b/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp +@@ -0,0 +1,943 @@ ++#include "util/detect.h" ++#include "util/u_cpu_detect.h" ++#include "util/u_debug.h" ++#include "util/os_time.h" ++#include "lp_bld.h" ++#include "lp_bld_debug.h" ++#include "lp_bld_init.h" ++#include "lp_bld_coro.h" ++#include "lp_bld_printf.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#if LLVM_VERSION_MAJOR >= 7 ++#include ++#endif ++#include ++#if GALLIVM_USE_NEW_PASS == 1 ++#include ++#elif GALLIVM_HAVE_CORO == 1 ++#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 == 1 || DETECT_ARCH_ARM == 1 || DETECT_ARCH_S390 == 1 || DETECT_ARCH_MIPS64 == 1) ++#include ++#endif ++#include ++#endif ++ ++#include ++#include ++#include ++#include "llvm/ExecutionEngine/JITLink/JITLink.h" ++#include ++#include ++#include ++#include ++#include ++#if LLVM_USE_INTEL_JITEVENTS ++#include ++#endif ++ ++/* conflict with ObjectLinkingLayer.h */ ++#include "util/u_memory.h" ++ ++#if DETECT_ARCH_RISCV64 == 1 || DETECT_ARCH_RISCV32 == 1 || (defined(_WIN32) && LLVM_VERSION_MAJOR >= 15) ++/* use ObjectLinkingLayer (JITLINK backend) */ ++#define USE_JITLINK ++#endif ++/* else use old RTDyldObjectLinkingLayer (RuntimeDyld backend) */ ++ ++unsigned lp_native_vector_width; ++ ++unsigned gallivm_perf = 0; ++ ++static const struct debug_named_value lp_bld_perf_flags[] = { ++ { "brilinear", GALLIVM_PERF_BRILINEAR, "enable brilinear optimization" }, ++ { "rho_approx", GALLIVM_PERF_RHO_APPROX, "enable rho_approx optimization" }, ++ { "no_quad_lod", GALLIVM_PERF_NO_QUAD_LOD, "disable quad_lod optimization" }, ++ { "no_aos_sampling", GALLIVM_PERF_NO_AOS_SAMPLING, "disable aos sampling optimization" }, ++ { "nopt", GALLIVM_PERF_NO_OPT, "disable optimization passes to speed up shader compilation" }, ++ DEBUG_NAMED_VALUE_END ++}; ++ ++unsigned gallivm_debug = 0; ++ ++static const struct debug_named_value lp_bld_debug_flags[] = { ++ { "tgsi", GALLIVM_DEBUG_TGSI, NULL }, ++ { "ir", GALLIVM_DEBUG_IR, NULL }, ++ { "asm", GALLIVM_DEBUG_ASM, NULL }, ++ { "perf", GALLIVM_DEBUG_PERF, NULL }, ++ { "gc", GALLIVM_DEBUG_GC, NULL }, ++/* Don't allow setting DUMP_BC for release builds, since writing the files may be an issue with setuid. */ ++#ifdef DEBUG ++ { "dumpbc", GALLIVM_DEBUG_DUMP_BC, NULL }, ++#endif ++ DEBUG_NAMED_VALUE_END ++}; ++ ++DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags, 0) ++ ++struct lp_cached_code { ++ void *data; ++ size_t data_size; ++ bool dont_cache; ++ void *jit_obj_cache; ++}; ++ ++namespace { ++ ++class LPJit; ++ ++class LLVMEnsureMultithreaded { ++public: ++ LLVMEnsureMultithreaded() ++ { ++ if (!LLVMIsMultithreaded()) { ++ LLVMStartMultithreaded(); ++ } ++ } ++}; ++ ++LLVMEnsureMultithreaded lLVMEnsureMultithreaded; ++ ++DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::orc::ThreadSafeContext, ++ LLVMOrcThreadSafeContextRef) ++DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::orc::IRTransformLayer, ++ LLVMOrcIRTransformLayerRef) ++DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::orc::JITDylib, LLVMOrcJITDylibRef) ++DEFINE_SIMPLE_CONVERSION_FUNCTIONS(llvm::orc::JITTargetMachineBuilder, ++ LLVMOrcJITTargetMachineBuilderRef) ++LLVMTargetMachineRef wrap(const llvm::TargetMachine *P) { ++ return reinterpret_cast(const_cast(P)); ++} ++ ++llvm::ExitOnError ExitOnErr; ++ ++inline const char* get_module_name(LLVMModuleRef mod) { ++ using llvm::Module; ++ return llvm::unwrap(mod)->getModuleIdentifier().c_str(); ++} ++ ++once_flag init_lpjit_once_flag = ONCE_FLAG_INIT; ++ ++/* A JIT singleton built upon LLJIT */ ++class LPJit ++{ ++public: ++ static LPJit* get_instance() { ++ call_once(&init_lpjit_once_flag, init_lpjit); ++ return jit; ++ } ++ ++ gallivm_state *find_gallivm_state(LLVMModuleRef mod) { ++#if DEBUG ++ using llvm::Module; ++ auto I = gallivm_modules.find(llvm::unwrap(mod)->getModuleIdentifier()); ++ if (I == gallivm_modules.end()) { ++ debug_printf("No gallivm state found for module: %s", get_module_name(mod)); ++ return NULL; ++ } ++ return I->second; ++#endif ++ return NULL; ++ } ++ ++ static char *get_unique_name(const char* name) { ++ LPJit* jit = get_instance(); ++ size_t size = name == NULL? 16: strlen(name) + 16; ++ char *name_uniq = (char *)MALLOC(size); ++ if (!name_uniq) { ++ return NULL; ++ } ++ do { ++ snprintf(name_uniq, size, "%s_%u", name, jit->jit_dylib_count++); ++ } while(jit->lljit->getExecutionSession().getJITDylibByName(name_uniq)); ++ return name_uniq; ++ } ++ ++ static LLVMOrcJITDylibRef create_jit_dylib(const char * name) { ++ using llvm::orc::JITDylib; ++ LPJit* jit = get_instance(); ++ JITDylib& tmp = ExitOnErr(jit->lljit->createJITDylib(name)); ++ return wrap(&tmp); ++ } ++ ++ static void register_gallivm_state(gallivm_state *gallivm) { ++#if DEBUG ++ LPJit* jit = get_instance(); ++ jit->gallivm_modules[gallivm->module_name] = gallivm; ++#endif ++ } ++ ++ static void deregister_gallivm_state(gallivm_state *gallivm) { ++#if DEBUG ++ LPJit* jit = get_instance(); ++ (void)jit->gallivm_modules.erase(gallivm->module_name); ++#endif ++ } ++ ++ static void add_ir_module_to_jd( ++ LLVMOrcThreadSafeContextRef ts_context, ++ LLVMModuleRef mod, ++ LLVMOrcJITDylibRef jd) { ++ using llvm::Module; ++ using llvm::orc::ThreadSafeModule; ++ using llvm::orc::JITDylib; ++ ThreadSafeModule tsm( ++ std::unique_ptr(llvm::unwrap(mod)), *::unwrap(ts_context)); ++ ExitOnErr(get_instance()->lljit->addIRModule( ++ *::unwrap(jd), std::move(tsm) ++ )); ++ } ++ ++ static void add_mapping_to_jd( ++ LLVMValueRef sym, ++ void *addr, ++ LLVMOrcJITDylibRef jd) { ++ using llvm::JITEvaluatedSymbol; ++ using llvm::orc::ExecutionSession; ++ using llvm::orc::JITDylib; ++ using llvm::orc::SymbolMap; ++ JITDylib* JD = ::unwrap(jd); ++ auto& es = LPJit::get_instance()->lljit->getExecutionSession(); ++ auto name = es.intern(llvm::unwrap(sym)->getName()); ++ SymbolMap map(1); ++ map[name] = JITEvaluatedSymbol::fromPointer(addr); ++ auto munit = llvm::orc::absoluteSymbols(map); ++ llvm::cantFail(JD->define(std::move(munit))); ++ } ++ ++ static void *lookup_in_jd( ++ const char *func_name, ++ LLVMOrcJITDylibRef jd) { ++ using llvm::orc::JITDylib; ++ using llvm::JITEvaluatedSymbol; ++ using llvm::orc::ExecutorAddr; ++ JITDylib* JD = ::unwrap(jd); ++ auto func = ExitOnErr(LPJit::get_instance()->lljit->lookup(*JD, func_name)); ++#if LLVM_VERSION_MAJOR >= 16 ++ return func.toPtr(); ++#else ++ return (void *)(func.getAddress()); ++#endif ++ } ++ ++ static void remove_jd(LLVMOrcJITDylibRef jd) { ++ using llvm::orc::ExecutionSession; ++ using llvm::orc::JITDylib; ++ auto& es = LPJit::get_instance()->lljit->getExecutionSession(); ++ ExitOnErr(es.removeJITDylib(* ::unwrap(jd))); ++ } ++ ++ LLVMTargetMachineRef tm; ++ ++private: ++ LPJit(); ++ ~LPJit() = default; ++ LPJit(const LPJit&) = delete; ++ LPJit& operator=(const LPJit&) = delete; ++ ++ static void init_native_targets(); ++ llvm::orc::JITTargetMachineBuilder create_jtdb(); ++ ++ static void init_lpjit() { ++ jit = new LPJit; ++ } ++ static LPJit* jit; ++ ++ std::unique_ptr lljit; ++ /* avoid name conflict */ ++ unsigned jit_dylib_count; ++ ++#if DEBUG ++ /* map from module name to gallivm_state */ ++ llvm::StringMap gallivm_modules; ++#endif ++}; ++ ++LPJit* LPJit::jit = NULL; ++ ++LLVMErrorRef module_transform(void *Ctx, LLVMModuleRef mod) { ++ int64_t time_begin = 0; ++ if (::gallivm_debug & GALLIVM_DEBUG_PERF) ++ time_begin = os_time_get(); ++#if GALLIVM_USE_NEW_PASS == 1 ++ char passes[1024]; ++ passes[0] = 0; ++ ++ /* ++ * there should be some way to combine these two pass runs but I'm not seeing it, ++ * at the time of writing. ++ */ ++ strcpy(passes, "default"); ++ ++ LLVMPassBuilderOptionsRef opts = LLVMCreatePassBuilderOptions(); ++ LLVMRunPasses(mod, passes, LPJit::get_instance()->tm, opts); ++ ++ if (!(gallivm_perf & GALLIVM_PERF_NO_OPT)) ++ strcpy(passes, "sroa,early-cse,simplifycfg,reassociate,mem2reg,instsimplify,instcombine,"); ++ else ++ strcpy(passes, "mem2reg"); ++ ++ LLVMRunPasses(mod, passes, LPJit::get_instance()->tm, opts); ++ LLVMDisposePassBuilderOptions(opts); ++ ++ return LLVMErrorSuccess; ++ ++#else /* GALLIVM_USE_NEW_PASS */ ++ LLVMPassManagerRef passmgr = LLVMCreateFunctionPassManagerForModule(mod); ++ ++#if GALLIVM_HAVE_CORO == 1 ++ LLVMPassManagerRef cgpassmgr = LLVMCreatePassManager(); ++#endif ++ ++#if GALLIVM_HAVE_CORO == 1 ++#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 == 1 || DETECT_ARCH_ARM == 1 || DETECT_ARCH_S390 == 1 || DETECT_ARCH_MIPS64 == 1) ++ LLVMAddArgumentPromotionPass(cgpassmgr); ++ LLVMAddFunctionAttrsPass(cgpassmgr); ++#endif ++ LLVMAddCoroEarlyPass(cgpassmgr); ++ LLVMAddCoroSplitPass(cgpassmgr); ++ LLVMAddCoroElidePass(cgpassmgr); ++#endif ++ ++ if ((gallivm_perf & GALLIVM_PERF_NO_OPT) == 0) { ++ /* ++ * TODO: Evaluate passes some more - keeping in mind ++ * both quality of generated code and compile times. ++ */ ++ /* ++ * NOTE: if you change this, don't forget to change the output ++ * with GALLIVM_DEBUG_DUMP_BC in gallivm_compile_module. ++ */ ++ LLVMAddScalarReplAggregatesPass(passmgr); ++ LLVMAddEarlyCSEPass(passmgr); ++ LLVMAddCFGSimplificationPass(passmgr); ++ /* ++ * FIXME: LICM is potentially quite useful. However, for some ++ * rather crazy shaders the compile time can reach _hours_ per shader, ++ * due to licm implying lcssa (since llvm 3.5), which can take forever. ++ * Even for sane shaders, the cost of licm is rather high (and not just ++ * due to lcssa, licm itself too), though mostly only in cases when it ++ * can actually move things, so having to disable it is a pity. ++ * LLVMAddLICMPass(passmgr); ++ */ ++ LLVMAddReassociatePass(passmgr); ++ LLVMAddPromoteMemoryToRegisterPass(passmgr); ++#if LLVM_VERSION_MAJOR <= 11 ++ LLVMAddConstantPropagationPass(passmgr); ++#else ++ LLVMAddInstructionSimplifyPass(passmgr); ++#endif ++ LLVMAddInstructionCombiningPass(passmgr); ++ LLVMAddGVNPass(passmgr); ++ } ++ else { ++ /* We need at least this pass to prevent the backends to fail in ++ * unexpected ways. ++ */ ++ LLVMAddPromoteMemoryToRegisterPass(passmgr); ++ } ++#if GALLIVM_HAVE_CORO == 1 ++ LLVMAddCoroCleanupPass(passmgr); ++ ++ LLVMRunPassManager(cgpassmgr, mod); ++#endif ++ /* Run optimization passes */ ++ LLVMInitializeFunctionPassManager(passmgr); ++ LLVMValueRef func; ++ func = LLVMGetFirstFunction(mod); ++ while (func) { ++ if (0) { ++ debug_printf("optimizing func %s...\n", LLVMGetValueName(func)); ++ } ++ ++ /* Disable frame pointer omission on debug/profile builds */ ++ /* XXX: And workaround http://llvm.org/PR21435 */ ++#if defined(DEBUG) || defined(PROFILE) || (DETECT_ARCH_X86 == 1 || DETECT_ARCH_X86_64 == 1) ++ LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim", "true"); ++ LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim-non-leaf", "true"); ++#endif ++ ++ LLVMRunFunctionPassManager(passmgr, func); ++ func = LLVMGetNextFunction(func); ++ } ++ LLVMFinalizeFunctionPassManager(passmgr); ++ if (gallivm_debug & GALLIVM_DEBUG_PERF) { ++ int64_t time_end = os_time_get(); ++ int time_msec = (int)((time_end - time_begin) / 1000); ++ ++ const char *module_name = get_module_name(mod); ++ debug_printf("optimizing module %s took %d msec\n", ++ module_name, time_msec); ++ } ++ ++#if GALLIVM_HAVE_CORO == 1 ++ LLVMDisposePassManager(cgpassmgr); ++#endif ++ LLVMDisposePassManager(passmgr); ++ return LLVMErrorSuccess; ++#endif /* GALLIVM_USE_NEW_PASS */ ++} ++ ++LLVMErrorRef module_transform_wrapper( ++ void *Ctx, LLVMOrcThreadSafeModuleRef *ModInOut, ++ LLVMOrcMaterializationResponsibilityRef MR) { ++ return LLVMOrcThreadSafeModuleWithModuleDo(*ModInOut, *module_transform, Ctx); ++} ++ ++LPJit::LPJit() :jit_dylib_count(0) { ++ using namespace llvm::orc; ++ ++ ::gallivm_debug = debug_get_option_gallivm_debug(); ++ ++ ++ gallivm_perf = debug_get_flags_option("GALLIVM_PERF", lp_bld_perf_flags, 0 ); ++ ++ init_native_targets(); ++ JITTargetMachineBuilder JTMB = create_jtdb(); ++ tm = wrap(ExitOnErr(JTMB.createTargetMachine()).release()); ++ ++ /* Create an LLJIT instance with an ObjectLinkingLayer (JITLINK) ++ * or RuntimeDyld as the base layer. ++ * intel & perf listeners are not supported by ObjectLinkingLayer yet ++ */ ++ lljit = ExitOnErr( ++ LLJITBuilder() ++ .setJITTargetMachineBuilder(std::move(JTMB)) ++#ifdef USE_JITLINK ++ .setObjectLinkingLayerCreator( ++ [&](ExecutionSession &ES, const llvm::Triple &TT) { ++ return std::make_unique( ++ ES, ExitOnErr(llvm::jitlink::InProcessMemoryManager::Create())); ++ }) ++#else ++#if LLVM_USE_INTEL_JITEVENTS ++ .RegisterJITEventListener( ++ llvm::JITEventListener::createIntelJITEventListener()) ++#endif ++#endif ++ .create()); ++ ++ LLVMOrcIRTransformLayerRef TL = wrap(&lljit->getIRTransformLayer()); ++ LLVMOrcIRTransformLayerSetTransform(TL, *module_transform_wrapper, NULL); ++} ++ ++void LPJit::init_native_targets() { ++ // If we have a native target, initialize it to ensure it is linked in and ++ // usable by the JIT. ++ llvm::InitializeNativeTarget(); ++ ++ llvm::InitializeNativeTargetAsmPrinter(); ++ ++ llvm::InitializeNativeTargetDisassembler(); ++#if DEBUG ++ { ++ char *env_llc_options = getenv("GALLIVM_LLC_OPTIONS"); ++ if (env_llc_options) { ++ char *option; ++ char *options[64] = {(char *) "llc"}; // Warning without cast ++ int n; ++ for (n = 0, option = strtok(env_llc_options, " "); option; n++, option = strtok(NULL, " ")) { ++ options[n + 1] = option; ++ } ++ if (::gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) { ++ debug_printf("llc additional options (%d):\n", n); ++ for (int i = 1; i <= n; i++) ++ debug_printf("\t%s\n", options[i]); ++ debug_printf("\n"); ++ } ++ LLVMParseCommandLineOptions(n + 1, options, NULL); ++ } ++ } ++#endif ++ ++ if (util_get_cpu_caps()->has_avx2 || util_get_cpu_caps()->has_avx) { ++ ::lp_native_vector_width = 256; ++ } else { ++ /* Leave it at 128, even when no SIMD extensions are available. ++ * Really needs to be a multiple of 128 so can fit 4 floats. ++ */ ++ ::lp_native_vector_width = 128; ++ } ++ ++ ::lp_native_vector_width = debug_get_num_option("LP_NATIVE_VECTOR_WIDTH", ++ lp_native_vector_width); ++ ++#if DETECT_ARCH_PPC_64 == 1 ++ /* Set the NJ bit in VSCR to 0 so denormalized values are handled as ++ * specified by IEEE standard (PowerISA 2.06 - Section 6.3). This guarantees ++ * that some rounding and half-float to float handling does not round ++ * incorrectly to 0. ++ * XXX: should eventually follow same logic on all platforms. ++ * Right now denorms get explicitly disabled (but elsewhere) for x86, ++ * whereas ppc64 explicitly enables them... ++ */ ++ if (util_get_cpu_caps()->has_altivec) { ++ unsigned short mask[] = { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, ++ 0xFFFF, 0xFFFF, 0xFFFE, 0xFFFF }; ++ __asm ( ++ "mfvscr %%v1\n" ++ "vand %0,%%v1,%0\n" ++ "mtvscr %0" ++ : ++ : "r" (*mask) ++ ); ++ } ++#endif ++} ++ ++llvm::orc::JITTargetMachineBuilder LPJit::create_jtdb() { ++ using namespace llvm; ++ using orc::JITTargetMachineBuilder; ++ ++#if defined(_WIN32) && LLVM_VERSION_MAJOR < 15 ++ /* ++ * JITLink works on Windows, but only through ELF object format. ++ * ++ * XXX: We could use `LLVM_HOST_TRIPLE "-elf"` but LLVM_HOST_TRIPLE has ++ * different strings for MinGW/MSVC, so better play it safe and be ++ * explicit. ++ */ ++# ifdef _WIN64 ++ JITTargetMachineBuilder JTMB((Triple("x86_64-pc-win32-elf"))); ++# else ++ JITTargetMachineBuilder JTMB((Triple("i686-pc-win32-elf"))); ++# endif ++#else ++ /* ++ * llvm::sys::getProcessTriple() is bogus. It returns the host LLVM was ++ * compiled on. Be careful when doing cross compilation ++ */ ++ JITTargetMachineBuilder JTMB((Triple(sys::getProcessTriple()))); ++#endif ++ ++ TargetOptions options; ++ /** ++ * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and ++ * friends for configuring code generation options, like stack alignment. ++ */ ++#if DETECT_ARCH_X86 == 1 && LLVM_VERSION_MAJOR < 13 ++ options.StackAlignmentOverride = 4; ++#endif ++ ++#if DETECT_ARCH_RISCV64 == 1 ++#if defined(__riscv_float_abi_soft) ++ options.MCOptions.ABIName = "lp64"; ++#elif defined(__riscv_float_abi_single) ++ options.MCOptions.ABIName = "lp64f"; ++#elif defined(__riscv_float_abi_double) ++ options.MCOptions.ABIName = "lp64d"; ++#else ++#error "GALLIVM: unknown target riscv float abi" ++#endif ++#endif ++ ++#if DETECT_ARCH_RISCV32 == 1 ++#if defined(__riscv_float_abi_soft) ++ options.MCOptions.ABIName = "ilp32"; ++#elif defined(__riscv_float_abi_single) ++ options.MCOptions.ABIName = "ilp32f"; ++#elif defined(__riscv_float_abi_double) ++ options.MCOptions.ABIName = "ilp32d"; ++#else ++#error "GALLIVM: unknown target riscv float abi" ++#endif ++#endif ++ ++ JTMB.setOptions(options); ++ ++ std::vector MAttrs; ++ ++#if LLVM_VERSION_MAJOR >= 4 && (DETECT_ARCH_X86 == 1 || DETECT_ARCH_X86_64 == 1 || DETECT_ARCH_ARM == 1) ++ /* llvm-3.3+ implements sys::getHostCPUFeatures for Arm ++ * and llvm-3.7+ for x86, which allows us to enable/disable ++ * code generation based on the results of cpuid on these ++ * architectures. ++ */ ++ StringMap features; ++ sys::getHostCPUFeatures(features); ++ ++ for (StringMapIterator f = features.begin(); ++ f != features.end(); ++ ++f) { ++ MAttrs.push_back(((*f).second ? "+" : "-") + (*f).first().str()); ++ } ++#elif DETECT_ARCH_X86 == 1 || DETECT_ARCH_X86_64 == 1 ++ /* ++ * We need to unset attributes because sometimes LLVM mistakenly assumes ++ * certain features are present given the processor name. ++ * ++ * https://bugs.freedesktop.org/show_bug.cgi?id=92214 ++ * http://llvm.org/PR25021 ++ * http://llvm.org/PR19429 ++ * http://llvm.org/PR16721 ++ */ ++ MAttrs.push_back(util_get_cpu_caps()->has_sse ? "+sse" : "-sse" ); ++ MAttrs.push_back(util_get_cpu_caps()->has_sse2 ? "+sse2" : "-sse2" ); ++ MAttrs.push_back(util_get_cpu_caps()->has_sse3 ? "+sse3" : "-sse3" ); ++ MAttrs.push_back(util_get_cpu_caps()->has_ssse3 ? "+ssse3" : "-ssse3" ); ++ MAttrs.push_back(util_get_cpu_caps()->has_sse4_1 ? "+sse4.1" : "-sse4.1"); ++ MAttrs.push_back(util_get_cpu_caps()->has_sse4_2 ? "+sse4.2" : "-sse4.2"); ++ /* ++ * AVX feature is not automatically detected from CPUID by the X86 target ++ * yet, because the old (yet default) JIT engine is not capable of ++ * emitting the opcodes. On newer llvm versions it is and at least some ++ * versions (tested with 3.3) will emit avx opcodes without this anyway. ++ */ ++ MAttrs.push_back(util_get_cpu_caps()->has_avx ? "+avx" : "-avx"); ++ MAttrs.push_back(util_get_cpu_caps()->has_f16c ? "+f16c" : "-f16c"); ++ MAttrs.push_back(util_get_cpu_caps()->has_fma ? "+fma" : "-fma"); ++ MAttrs.push_back(util_get_cpu_caps()->has_avx2 ? "+avx2" : "-avx2"); ++ /* disable avx512 and all subvariants */ ++ MAttrs.push_back("-avx512cd"); ++ MAttrs.push_back("-avx512er"); ++ MAttrs.push_back("-avx512f"); ++ MAttrs.push_back("-avx512pf"); ++ MAttrs.push_back("-avx512bw"); ++ MAttrs.push_back("-avx512dq"); ++ MAttrs.push_back("-avx512vl"); ++#endif ++#if DETECT_ARCH_ARM == 1 ++ if (!util_get_cpu_caps()->has_neon) { ++ MAttrs.push_back("-neon"); ++ MAttrs.push_back("-crypto"); ++ MAttrs.push_back("-vfp2"); ++ } ++#endif ++ ++#if DETECT_ARCH_PPC == 1 ++ MAttrs.push_back(util_get_cpu_caps()->has_altivec ? "+altivec" : "-altivec"); ++#if (LLVM_VERSION_MAJOR < 4) ++ /* ++ * Make sure VSX instructions are disabled ++ * See LLVM bugs: ++ * https://llvm.org/bugs/show_bug.cgi?id=25503#c7 (fixed in 3.8.1) ++ * https://llvm.org/bugs/show_bug.cgi?id=26775 (fixed in 3.8.1) ++ * https://llvm.org/bugs/show_bug.cgi?id=33531 (fixed in 4.0) ++ * https://llvm.org/bugs/show_bug.cgi?id=34647 (llc performance on certain unusual shader IR; intro'd in 4.0, pending as of 5.0) ++ */ ++ if (util_get_cpu_caps()->has_altivec) { ++ MAttrs.push_back("-vsx"); ++ } ++#else ++ /* ++ * Bug 25503 is fixed, by the same fix that fixed ++ * bug 26775, in versions of LLVM later than 3.8 (starting with 3.8.1). ++ * BZ 33531 actually comprises more than one bug, all of ++ * which are fixed in LLVM 4.0. ++ * ++ * With LLVM 4.0 or higher: ++ * Make sure VSX instructions are ENABLED (if supported), unless ++ * VSX instructions are explicitly enabled/disabled via GALLIVM_VSX=1 or 0. ++ */ ++ if (util_get_cpu_caps()->has_altivec) { ++ MAttrs.push_back(util_get_cpu_caps()->has_vsx ? "+vsx" : "-vsx"); ++ } ++#endif ++#endif ++ ++#if DETECT_ARCH_MIPS64 == 1 ++ MAttrs.push_back(util_get_cpu_caps()->has_msa ? "+msa" : "-msa"); ++ /* MSA requires a 64-bit FPU register file */ ++ MAttrs.push_back("+fp64"); ++#endif ++ ++#if DETECT_ARCH_RISCV64 == 1 ++ /* Before riscv is more matured and util_get_cpu_caps() is implemented, ++ * assume this for now since most of linux capable riscv machine are ++ * riscv64gc ++ */ ++ MAttrs = {"+m","+c","+a","+d","+f"}; ++#endif ++ ++ JTMB.addFeatures(MAttrs); ++ ++ if (::gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) { ++ int n = MAttrs.size(); ++ if (n > 0) { ++ debug_printf("llc -mattr option(s): "); ++ for (int i = 0; i < n; i++) ++ debug_printf("%s%s", MAttrs[i].c_str(), (i < n - 1) ? "," : ""); ++ debug_printf("\n"); ++ } ++ } ++ ++ std::string MCPU = llvm::sys::getHostCPUName().str(); ++ /* ++ * Note that the MAttrs set above will be sort of ignored (since we should ++ * not set any which would not be set by specifying the cpu anyway). ++ * It ought to be safe though since getHostCPUName() should include bits ++ * not only from the cpu but environment as well (for instance if it's safe ++ * to use avx instructions which need OS support). According to ++ * http://llvm.org/bugs/show_bug.cgi?id=19429 however if I understand this ++ * right it may be necessary to specify older cpu (or disable mattrs) though ++ * when not using MCJIT so no instructions are generated which the old JIT ++ * can't handle. Not entirely sure if we really need to do anything yet. ++ * ++ * Not sure if the above is also the case for ORCJIT, but we need set CPU ++ * manually since we don't use JITTargetMachineBuilder::detectHost() ++ */ ++ ++#if DETECT_ARCH_PPC_64 == 1 ++ /* ++ * Large programs, e.g. gnome-shell and firefox, may tax the addressability ++ * of the Medium code model once dynamically generated JIT-compiled shader ++ * programs are linked in and relocated. Yet the default code model as of ++ * LLVM 8 is Medium or even Small. ++ * The cost of changing from Medium to Large is negligible: ++ * - an additional 8-byte pointer stored immediately before the shader entrypoint; ++ * - change an add-immediate (addis) instruction to a load (ld). ++ */ ++ JTMB.setCodeModel(CodeModel::Large); ++ ++#if UTIL_ARCH_LITTLE_ENDIAN ++ /* ++ * Versions of LLVM prior to 4.0 lacked a table entry for "POWER8NVL", ++ * resulting in (big-endian) "generic" being returned on ++ * little-endian Power8NVL systems. The result was that code that ++ * attempted to load the least significant 32 bits of a 64-bit quantity ++ * from memory loaded the wrong half. This resulted in failures in some ++ * Piglit tests, e.g. ++ * .../arb_gpu_shader_fp64/execution/conversion/frag-conversion-explicit-double-uint ++ */ ++ if (MCPU == "generic") ++ MCPU = "pwr8"; ++#endif ++#endif ++ ++#if DETECT_ARCH_MIPS64 == 1 ++ /* ++ * ls3a4000 CPU and ls2k1000 SoC is a mips64r5 compatible with MSA SIMD ++ * instruction set implemented, while ls3a3000 is mips64r2 compatible ++ * only. getHostCPUName() return "generic" on all loongson ++ * mips CPU currently. So we override the MCPU to mips64r5 if MSA is ++ * implemented, feedback to mips64r2 for all other ordinary mips64 cpu. ++ */ ++ if (MCPU == "generic") ++ MCPU = util_get_cpu_caps()->has_msa ? "mips64r5" : "mips64r2"; ++#endif ++ ++#if DETECT_ARCH_RISCV64 == 1 ++ /** ++ * should be fixed with https://reviews.llvm.org/D121149 in llvm 15, ++ * set it anyway for llvm 14 ++ */ ++ if (MCPU == "generic") ++ MCPU = "generic-rv64"; ++ ++ JTMB.setCodeModel(CodeModel::Medium); ++ JTMB.setRelocationModel(Reloc::PIC_); ++#endif ++ ++#if DETECT_ARCH_RISCV32 == 1 ++ /** ++ * should be fixed with https://reviews.llvm.org/D121149 in llvm 15, ++ * set it anyway for llvm 14 ++ */ ++ if (MCPU == "generic") ++ MCPU = "generic-rv32"; ++ ++ JTMB.setCodeModel(CodeModel::Medium); ++ JTMB.setRelocationModel(Reloc::PIC_); ++#endif ++ ++ JTMB.setCPU(MCPU); ++ if (gallivm_debug & (GALLIVM_DEBUG_IR | GALLIVM_DEBUG_ASM | GALLIVM_DEBUG_DUMP_BC)) { ++ debug_printf("llc -mcpu option: %s\n", MCPU.c_str()); ++ } ++ ++ return JTMB; ++} ++ ++ ++} /* Anonymous namespace */ ++ ++unsigned ++lp_build_init_native_width(void) ++{ ++ // Default to 256 until we're confident llvmpipe with 512 is as correct and not slower than 256 ++ lp_native_vector_width = MIN2(util_get_cpu_caps()->max_vector_bits, 256); ++ assert(lp_native_vector_width); ++ ++ lp_native_vector_width = debug_get_num_option("LP_NATIVE_VECTOR_WIDTH", lp_native_vector_width); ++ assert(lp_native_vector_width); ++ ++ return lp_native_vector_width; ++} ++ ++bool ++lp_build_init(void) ++{ ++ (void)LPJit::get_instance(); ++ return true; ++} ++ ++bool ++init_gallivm_state(struct gallivm_state *gallivm, const char *name, ++ LLVMOrcThreadSafeContextRef context, struct lp_cached_code *cache) ++{ ++ assert(!gallivm->context); ++ assert(!gallivm->_ts_context); ++ assert(!gallivm->module); ++ ++ if (!lp_build_init()) ++ return false; ++ ++ // cache is not implemented ++ gallivm->cache = cache; ++ if (gallivm->cache) ++ gallivm->cache->data_size = 0; ++ ++ gallivm->_ts_context = context; ++ gallivm->context = LLVMOrcThreadSafeContextGetContext(context); ++ ++ gallivm->module_name = LPJit::get_unique_name(name); ++ gallivm->module = LLVMModuleCreateWithNameInContext(gallivm->module_name, ++ gallivm->context); ++#if DETECT_ARCH_X86 == 1 ++ lp_set_module_stack_alignment_override(gallivm->module, 4); ++#endif ++ gallivm->builder = LLVMCreateBuilderInContext(gallivm->context); ++ gallivm->_per_module_jd = LPJit::create_jit_dylib(gallivm->module_name); ++ ++ gallivm->target = LLVMCreateTargetDataLayout(LPJit::get_instance()->tm); ++ ++ lp_build_coro_declare_malloc_hooks(gallivm); ++ return true; ++} ++ ++struct gallivm_state * ++gallivm_create(const char *name, LLVMOrcThreadSafeContextRef context, ++ struct lp_cached_code *cache){ ++ struct gallivm_state *gallivm; ++ ++ gallivm = CALLOC_STRUCT(gallivm_state); ++ if (gallivm) { ++ if (!init_gallivm_state(gallivm, name, context, cache)) { ++ FREE(gallivm); ++ gallivm = NULL; ++ } ++ } ++ ++ assert(gallivm != NULL); ++ return gallivm; ++} ++ ++void ++gallivm_destroy(struct gallivm_state *gallivm) ++{ ++ LPJit::remove_jd(gallivm->_per_module_jd); ++ gallivm->_per_module_jd = nullptr; ++} ++ ++void ++gallivm_free_ir(struct gallivm_state *gallivm) ++{ ++ if (gallivm->module) ++ LLVMDisposeModule(gallivm->module); ++ FREE(gallivm->module_name); ++ ++ if (gallivm->target) { ++ LLVMDisposeTargetData(gallivm->target); ++ } ++ ++ if (gallivm->builder) ++ LLVMDisposeBuilder(gallivm->builder); ++ ++ gallivm->target = NULL; ++ gallivm->module=NULL; ++ gallivm->module_name=NULL; ++ gallivm->builder=NULL; ++ gallivm->context=NULL; ++ gallivm->_ts_context=NULL; ++ gallivm->cache=NULL; ++ LPJit::deregister_gallivm_state(gallivm); ++} ++ ++void ++gallivm_verify_function(struct gallivm_state *gallivm, ++ LLVMValueRef func) ++{ ++ /* Verify the LLVM IR. If invalid, dump and abort */ ++#ifdef DEBUG ++ if (LLVMVerifyFunction(func, LLVMPrintMessageAction)) { ++ lp_debug_dump_value(func); ++ assert(0); ++ return; ++ } ++#endif ++ ++ if (gallivm_debug & GALLIVM_DEBUG_IR) { ++ /* Print the LLVM IR to stderr */ ++ lp_debug_dump_value(func); ++ debug_printf("\n"); ++ } ++return; ++} ++ ++void ++gallivm_add_global_mapping(struct gallivm_state *gallivm, LLVMValueRef sym, void* addr) ++{ ++ LPJit::add_mapping_to_jd(sym, addr, gallivm->_per_module_jd); ++} ++ ++void lp_init_clock_hook(struct gallivm_state *gallivm) ++{ ++ if (gallivm->get_time_hook) ++ return; ++ ++ LLVMTypeRef get_time_type = LLVMFunctionType(LLVMInt64TypeInContext(gallivm->context), NULL, 0, 1); ++ gallivm->get_time_hook = LLVMAddFunction(gallivm->module, "get_time_hook", get_time_type); ++} ++ ++void ++gallivm_compile_module(struct gallivm_state *gallivm) ++{ ++ lp_init_printf_hook(gallivm); ++ gallivm_add_global_mapping(gallivm, gallivm->debug_printf_hook, ++ (void *)debug_printf); ++ ++ lp_init_clock_hook(gallivm); ++ gallivm_add_global_mapping(gallivm, gallivm->get_time_hook, ++ (void *)os_time_get_nano); ++ ++ lp_build_coro_add_malloc_hooks(gallivm); ++ ++ LPJit::add_ir_module_to_jd(gallivm->_ts_context, gallivm->module, ++ gallivm->_per_module_jd); ++ /* ownership of module is now transferred into orc jit, ++ * disallow modifying it ++ */ ++ LPJit::register_gallivm_state(gallivm); ++ gallivm->module=nullptr; ++ ++ /* defer compilation till first lookup by gallivm_jit_function */ ++} ++ ++func_pointer ++gallivm_jit_function(struct gallivm_state *gallivm, ++ const char *func_name) ++{ ++ return pointer_to_func( ++ LPJit::lookup_in_jd(func_name, gallivm->_per_module_jd)); ++} ++ ++unsigned ++gallivm_get_perf_flags(void){ ++ return gallivm_perf; ++} ++ ++void ++lp_set_module_stack_alignment_override(LLVMModuleRef MRef, unsigned align) ++{ ++#if LLVM_VERSION_MAJOR >= 13 ++ llvm::Module *M = llvm::unwrap(MRef); ++ M->setOverrideStackAlignment(align); ++#endif ++} +diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build +index e7dde65f6a1f3..a1c60b940738a 100644 +--- a/src/gallium/auxiliary/meson.build ++++ b/src/gallium/auxiliary/meson.build +@@ -347,7 +347,6 @@ if draw_with_llvm + 'gallivm/lp_bld_gather.c', + 'gallivm/lp_bld_gather.h', + 'gallivm/lp_bld.h', +- 'gallivm/lp_bld_init.c', + 'gallivm/lp_bld_init.h', + 'gallivm/lp_bld_intr.c', + 'gallivm/lp_bld_intr.h', +@@ -399,6 +398,11 @@ if draw_with_llvm + 'nir/nir_to_tgsi_info.c', + 'nir/nir_to_tgsi_info.h', + ) ++ if llvm_with_orcjit ++ files_libgallium += files('gallivm/lp_bld_init_orc.cpp',) ++ else ++ files_libgallium += files('gallivm/lp_bld_init.c',) ++ endif + endif + + files_libgalliumvl = files( +diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c +index 8e5e8ced3fe9d..d77da467efd61 100644 +--- a/src/gallium/drivers/llvmpipe/lp_context.c ++++ b/src/gallium/drivers/llvmpipe/lp_context.c +@@ -49,6 +49,10 @@ + #include "lp_screen.h" + #include "lp_fence.h" + ++#if !GALLIVM_USE_ORCJIT ++#define USE_GLOBAL_LLVM_CONTEXT ++#endif ++ + static void + llvmpipe_destroy(struct pipe_context *pipe) + { +@@ -108,7 +112,11 @@ llvmpipe_destroy(struct pipe_context *pipe) + llvmpipe_sampler_matrix_destroy(llvmpipe); + + #ifndef USE_GLOBAL_LLVM_CONTEXT ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcDisposeThreadSafeContext(llvmpipe->context); ++#else + LLVMContextDispose(llvmpipe->context); ++#endif + #endif + llvmpipe->context = NULL; + +@@ -258,15 +266,25 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, + + #ifdef USE_GLOBAL_LLVM_CONTEXT + llvmpipe->context = LLVMGetGlobalContext(); ++#else ++#if GALLIVM_USE_ORCJIT ++ llvmpipe->context = LLVMOrcCreateNewThreadSafeContext(); + #else + llvmpipe->context = LLVMContextCreate(); ++#endif + #endif + + if (!llvmpipe->context) + goto fail; + +-#if LLVM_VERSION_MAJOR == 15 ++#if GALLIVM_USE_ORCJIT ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(llvmpipe->context), false); ++#endif ++#else ++#if LLVM_VERSION_MAJOR >= 15 + LLVMContextSetOpaquePointers(llvmpipe->context, false); ++#endif + #endif + + /* +diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h +index 7dd6a3f8596d9..231479eef0fbc 100644 +--- a/src/gallium/drivers/llvmpipe/lp_context.h ++++ b/src/gallium/drivers/llvmpipe/lp_context.h +@@ -190,7 +190,11 @@ struct llvmpipe_context { + unsigned render_cond_offset; + + /** The LLVMContext to use for LLVM related work */ ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef context; ++#else + LLVMContextRef context; ++#endif + + int max_global_buffers; + struct pipe_resource **global_buffers; +diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c +index b518da49e720c..dba0f7b9fd8e1 100644 +--- a/src/gallium/drivers/llvmpipe/lp_screen.c ++++ b/src/gallium/drivers/llvmpipe/lp_screen.c +@@ -951,7 +951,11 @@ static void + lp_disk_cache_create(struct llvmpipe_screen *screen) + { + struct mesa_sha1 ctx; ++#if GALLIVM_USE_ORCJIT ++ unsigned gallivm_perf = 0; ++#else + unsigned gallivm_perf = gallivm_get_perf_flags(); ++#endif + unsigned char sha1[20]; + char cache_id[20 * 2 + 1]; + _mesa_sha1_init(&ctx); +diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.c b/src/gallium/drivers/llvmpipe/lp_state_cs.c +index c4661ced0250e..afb1be4bbadbc 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_cs.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_cs.c +@@ -397,6 +397,10 @@ generate_compute(struct llvmpipe_context *lp, + lp_build_coro_add_presplit(coro); + + variant->function = function; ++#if GALLIVM_USE_ORCJIT ++ variant->function_name = MALLOC(strlen(func_name)+1); ++ strcpy(variant->function_name, func_name); ++#endif + + for (i = 0; i < CS_ARG_MAX - !is_mesh; ++i) { + if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) { +@@ -1047,6 +1051,10 @@ llvmpipe_remove_cs_shader_variant(struct llvmpipe_context *lp, + lp->nr_cs_variants--; + lp->nr_cs_instrs -= variant->nr_instrs; + ++#if GALLIVM_USE_ORCJIT ++ if(variant->function_name) ++ FREE(variant->function_name); ++#endif + FREE(variant); + } + +@@ -1305,12 +1313,22 @@ generate_variant(struct llvmpipe_context *lp, + + generate_compute(lp, shader, variant); + ++#if GALLIVM_USE_ORCJIT ++/* module has been moved into ORCJIT after gallivm_compile_module */ ++ variant->nr_instrs += lp_build_count_ir_module(variant->gallivm->module); ++ ++ gallivm_compile_module(variant->gallivm); ++ ++ variant->jit_function = (lp_jit_cs_func) ++ gallivm_jit_function(variant->gallivm, variant->function_name); ++#else + gallivm_compile_module(variant->gallivm); + + variant->nr_instrs += lp_build_count_ir_module(variant->gallivm->module); + + variant->jit_function = (lp_jit_cs_func) + gallivm_jit_function(variant->gallivm, variant->function); ++#endif + + if (needs_caching) { + lp_disk_cache_insert_shader(screen, &cached, ir_sha1_cache_key); +diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.h b/src/gallium/drivers/llvmpipe/lp_state_cs.h +index 11d2e2cd8257a..bdf579aebc0b9 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_cs.h ++++ b/src/gallium/drivers/llvmpipe/lp_state_cs.h +@@ -91,6 +91,9 @@ struct lp_compute_shader_variant + LLVMTypeRef jit_vertex_header_ptr_type; + LLVMTypeRef jit_prim_type; + LLVMValueRef function; ++#if GALLIVM_USE_ORCJIT ++ char* function_name; ++#endif + lp_jit_cs_func jit_function; + + /* Total number of LLVM instructions generated */ +diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c +index b380f4cd964ac..26273be7ab314 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c +@@ -3206,6 +3206,10 @@ generate_fragment(struct llvmpipe_context *lp, + LLVMSetFunctionCallConv(function, LLVMCCallConv); + + variant->function[partial_mask] = function; ++#if GALLIVM_USE_ORCJIT ++ variant->function_name[partial_mask] = MALLOC(strlen(func_name)+1); ++ strcpy(variant->function_name[partial_mask], func_name); ++#endif + + /* XXX: need to propagate noalias down into color param now we are + * passing a pointer-to-pointer? +@@ -3912,20 +3916,37 @@ generate_variant(struct llvmpipe_context *lp, + * Compile everything + */ + ++#if GALLIVM_USE_ORCJIT ++/* module has been moved into ORCJIT after gallivm_compile_module */ ++ variant->nr_instrs += lp_build_count_ir_module(variant->gallivm->module); ++ ++ gallivm_compile_module(variant->gallivm); ++#else + gallivm_compile_module(variant->gallivm); + + variant->nr_instrs += lp_build_count_ir_module(variant->gallivm->module); ++#endif + + if (variant->function[RAST_EDGE_TEST]) { + variant->jit_function[RAST_EDGE_TEST] = (lp_jit_frag_func) ++#if GALLIVM_USE_ORCJIT ++ gallivm_jit_function(variant->gallivm, ++ variant->function_name[RAST_EDGE_TEST]); ++#else + gallivm_jit_function(variant->gallivm, + variant->function[RAST_EDGE_TEST]); ++#endif + } + + if (variant->function[RAST_WHOLE]) { + variant->jit_function[RAST_WHOLE] = (lp_jit_frag_func) ++#if GALLIVM_USE_ORCJIT ++ gallivm_jit_function(variant->gallivm, ++ variant->function_name[RAST_WHOLE]); ++#else + gallivm_jit_function(variant->gallivm, + variant->function[RAST_WHOLE]); ++#endif + } else if (!variant->jit_function[RAST_WHOLE]) { + variant->jit_function[RAST_WHOLE] = (lp_jit_frag_func) + variant->jit_function[RAST_EDGE_TEST]; +@@ -3934,7 +3955,11 @@ generate_variant(struct llvmpipe_context *lp, + if (linear_pipeline) { + if (variant->linear_function) { + variant->jit_linear_llvm = (lp_jit_linear_llvm_func) ++#if GALLIVM_USE_ORCJIT ++ gallivm_jit_function(variant->gallivm, variant->linear_function_name); ++#else + gallivm_jit_function(variant->gallivm, variant->linear_function); ++#endif + } + + /* +@@ -4110,6 +4135,14 @@ llvmpipe_destroy_shader_variant(struct llvmpipe_context *lp, + { + gallivm_destroy(variant->gallivm); + lp_fs_reference(lp, &variant->shader, NULL); ++#if GALLIVM_USE_ORCJIT ++ if (variant->function_name[RAST_EDGE_TEST]) ++ FREE(variant->function_name[RAST_EDGE_TEST]); ++ if (variant->function_name[RAST_WHOLE]) ++ FREE(variant->function_name[RAST_WHOLE]); ++ if (variant->linear_function_name) ++ FREE(variant->linear_function_name); ++#endif + FREE(variant); + } + +diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h +index 195cdd5960b10..4b7126a59e98f 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_fs.h ++++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h +@@ -168,6 +168,9 @@ struct lp_fragment_shader_variant + LLVMTypeRef jit_linear_textures_type; + + LLVMValueRef function[2]; // [RAST_WHOLE], [RAST_EDGE_TEST] ++#if GALLIVM_USE_ORCJIT ++ char* function_name[2]; ++#endif + + lp_jit_frag_func jit_function[2]; // [RAST_WHOLE], [RAST_EDGE_TEST] + +@@ -177,6 +180,9 @@ struct lp_fragment_shader_variant + /* Functions within the linear path: + */ + LLVMValueRef linear_function; ++#if GALLIVM_USE_ORCJIT ++ char* linear_function_name; ++#endif + lp_jit_linear_llvm_func jit_linear_llvm; + + /* Bitmask to say what cbufs are unswizzled */ +diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c b/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c +index c64f5cf2c3464..e0669a3e9f869 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c +@@ -289,6 +289,10 @@ llvmpipe_fs_variant_linear_llvm(struct llvmpipe_context *lp, + LLVMSetFunctionCallConv(function, LLVMCCallConv); + + variant->linear_function = function; ++#if GALLIVM_USE_ORCJIT ++ variant->linear_function_name = MALLOC(strlen(func_name)+1); ++ strcpy(variant->linear_function_name, func_name); ++#endif + + /* XXX: need to propagate noalias down into color param now we are + * passing a pointer-to-pointer? +diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c +index 2f4bbdf7a88c4..309aaee6f38d2 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_setup.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c +@@ -688,6 +688,10 @@ generate_setup_variant(struct lp_setup_variant_key *key, + arg_types, ARRAY_SIZE(arg_types), 0); + + variant->function = LLVMAddFunction(gallivm->module, func_name, func_type); ++#if GALLIVM_USE_ORCJIT ++ variant->function_name = MALLOC(strlen(func_name)+1); ++ strcpy(variant->function_name, func_name); ++#endif + if (!variant->function) + goto fail; + +@@ -731,8 +735,13 @@ generate_setup_variant(struct lp_setup_variant_key *key, + + gallivm_compile_module(gallivm); + ++#if GALLIVM_USE_ORCJIT ++ variant->jit_function = (lp_jit_setup_triangle) ++ gallivm_jit_function(gallivm, variant->function_name); ++#else + variant->jit_function = (lp_jit_setup_triangle) + gallivm_jit_function(gallivm, variant->function); ++#endif + if (!variant->jit_function) + goto fail; + +diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.h b/src/gallium/drivers/llvmpipe/lp_state_setup.h +index ef208937396e1..38a624ca6ade4 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_setup.h ++++ b/src/gallium/drivers/llvmpipe/lp_state_setup.h +@@ -66,6 +66,9 @@ struct lp_setup_variant { + * assembly. + */ + LLVMValueRef function; ++#if GALLIVM_USE_ORCJIT ++ char *function_name; ++#endif + + /* The actual generated setup function: + */ +diff --git a/src/gallium/drivers/llvmpipe/lp_test_arit.c b/src/gallium/drivers/llvmpipe/lp_test_arit.c +index fd8489f8358b0..abd93a2754282 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_arit.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_arit.c +@@ -417,7 +417,11 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test, unsigned + { + char test_name[128]; + snprintf(test_name, sizeof test_name, "%s.v%u", test->name, length); ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef context; ++#else + LLVMContextRef context; ++#endif + struct gallivm_state *gallivm; + LLVMValueRef test_func; + unary_func_t test_func_jit; +@@ -433,9 +437,16 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test, unsigned + in[i] = 1.0; + } + ++#if GALLIVM_USE_ORCJIT ++ context = LLVMOrcCreateNewThreadSafeContext(); ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); ++#endif ++#else + context = LLVMContextCreate(); + #if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(context, false); ++#endif + #endif + gallivm = gallivm_create("test_module", context, NULL); + +@@ -443,7 +454,11 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test, unsigned + + gallivm_compile_module(gallivm); + ++#if GALLIVM_USE_ORCJIT ++ test_func_jit = (unary_func_t) gallivm_jit_function(gallivm, test_name); ++#else + test_func_jit = (unary_func_t) gallivm_jit_function(gallivm, test_func); ++#endif + + gallivm_free_ir(gallivm); + +@@ -512,7 +527,11 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test, unsigned + } + + gallivm_destroy(gallivm); ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcDisposeThreadSafeContext(context); ++#else + LLVMContextDispose(context); ++#endif + + align_free(in); + align_free(out); +diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c +index 7851bf29dd63f..8c30a7d33a1c0 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c +@@ -131,16 +131,24 @@ dump_blend_type(FILE *fp, + } + + ++#if GALLIVM_USE_ORCJIT ++static const char * ++add_blend_test(struct gallivm_state *gallivm, ++ const struct pipe_blend_state *blend, ++ struct lp_type type) ++#else + static LLVMValueRef + add_blend_test(struct gallivm_state *gallivm, + const struct pipe_blend_state *blend, + struct lp_type type) ++#endif + { + LLVMModuleRef module = gallivm->module; + LLVMContextRef context = gallivm->context; + LLVMTypeRef vec_type; + LLVMTypeRef args[5]; + LLVMValueRef func; ++ const char *func_name = "test"; + LLVMValueRef src_ptr; + LLVMValueRef src1_ptr; + LLVMValueRef dst_ptr; +@@ -160,7 +168,7 @@ add_blend_test(struct gallivm_state *gallivm, + vec_type = lp_build_vec_type(gallivm, type); + + args[4] = args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0); +- func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 5, 0)); ++ func = LLVMAddFunction(module, func_name, LLVMFunctionType(LLVMVoidTypeInContext(context), args, 5, 0)); + LLVMSetFunctionCallConv(func, LLVMCCallConv); + src_ptr = LLVMGetParam(func, 0); + src1_ptr = LLVMGetParam(func, 1); +@@ -188,7 +196,11 @@ add_blend_test(struct gallivm_state *gallivm, + + gallivm_verify_function(gallivm, func); + ++#if GALLIVM_USE_ORCJIT ++ return func_name; ++#else + return func; ++#endif + } + + +@@ -437,9 +449,17 @@ test_one(unsigned verbose, + const struct pipe_blend_state *blend, + struct lp_type type) + { ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef context; ++#else + LLVMContextRef context; ++#endif + struct gallivm_state *gallivm; ++#if GALLIVM_USE_ORCJIT ++ const char *func; ++#else + LLVMValueRef func = NULL; ++#endif + blend_test_ptr_t blend_test_ptr; + bool success; + const unsigned n = LP_TEST_NUM_SAMPLES; +@@ -451,9 +471,16 @@ test_one(unsigned verbose, + if (verbose >= 1) + dump_blend_type(stdout, blend, type); + ++#if GALLIVM_USE_ORCJIT ++ context = LLVMOrcCreateNewThreadSafeContext(); ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); ++#endif ++#else + context = LLVMContextCreate(); + #if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(context, false); ++#endif + #endif + gallivm = gallivm_create("test_module", context, NULL); + +@@ -584,7 +611,11 @@ test_one(unsigned verbose, + write_tsv_row(fp, blend, type, cycles_avg, success); + + gallivm_destroy(gallivm); ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcDisposeThreadSafeContext(context); ++#else + LLVMContextDispose(context); ++#endif + + return success; + } +diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c +index 9fb64486f1131..b8c58cd9a07b7 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_conv.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c +@@ -96,16 +96,24 @@ dump_conv_types(FILE *fp, + } + + ++#if GALLIVM_USE_ORCJIT ++static const char * ++add_conv_test(struct gallivm_state *gallivm, ++ struct lp_type src_type, unsigned num_srcs, ++ struct lp_type dst_type, unsigned num_dsts) ++#else + static LLVMValueRef + add_conv_test(struct gallivm_state *gallivm, + struct lp_type src_type, unsigned num_srcs, + struct lp_type dst_type, unsigned num_dsts) ++#endif + { + LLVMModuleRef module = gallivm->module; + LLVMContextRef context = gallivm->context; + LLVMBuilderRef builder = gallivm->builder; + LLVMTypeRef args[2]; + LLVMValueRef func; ++ const char *func_name = "test"; + LLVMValueRef src_ptr; + LLVMValueRef dst_ptr; + LLVMBasicBlockRef block; +@@ -118,7 +126,7 @@ add_conv_test(struct gallivm_state *gallivm, + args[0] = LLVMPointerType(src_vec_type, 0); + args[1] = LLVMPointerType(dst_vec_type, 0); + +- func = LLVMAddFunction(module, "test", ++ func = LLVMAddFunction(module, func_name, + LLVMFunctionType(LLVMVoidTypeInContext(context), + args, 2, 0)); + LLVMSetFunctionCallConv(func, LLVMCCallConv); +@@ -146,7 +154,11 @@ add_conv_test(struct gallivm_state *gallivm, + + gallivm_verify_function(gallivm, func); + ++#if GALLIVM_USE_ORCJIT ++ return func_name; ++#else + return func; ++#endif + } + + +@@ -157,9 +169,17 @@ test_one(unsigned verbose, + struct lp_type src_type, + struct lp_type dst_type) + { ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef context; ++#else + LLVMContextRef context; ++#endif + struct gallivm_state *gallivm; ++#if GALLIVM_USE_ORCJIT ++ const char *func; ++#else + LLVMValueRef func = NULL; ++#endif + conv_test_ptr_t conv_test_ptr; + bool success; + const unsigned n = LP_TEST_NUM_SAMPLES; +@@ -222,9 +242,16 @@ test_one(unsigned verbose, + eps *= 2; + } + ++#if GALLIVM_USE_ORCJIT ++ context = LLVMOrcCreateNewThreadSafeContext(); ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); ++#endif ++#else + context = LLVMContextCreate(); + #if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(context, false); ++#endif + #endif + gallivm = gallivm_create("test_module", context, NULL); + +@@ -337,7 +364,11 @@ test_one(unsigned verbose, + write_tsv_row(fp, src_type, dst_type, cycles_avg, success); + + gallivm_destroy(gallivm); ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcDisposeThreadSafeContext(context); ++#else + LLVMContextDispose(context); ++#endif + + return success; + } +diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c +index 6d3a60bd8dba0..23d69c78fec52 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_format.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_format.c +@@ -79,9 +79,9 @@ static LLVMValueRef + add_fetch_rgba_test(struct gallivm_state *gallivm, unsigned verbose, + const struct util_format_description *desc, + struct lp_type type, +- unsigned use_cache) ++ unsigned use_cache, ++ char *name) + { +- char name[256]; + LLVMContextRef context = gallivm->context; + LLVMModuleRef module = gallivm->module; + LLVMBuilderRef builder = gallivm->builder; +@@ -96,7 +96,7 @@ add_fetch_rgba_test(struct gallivm_state *gallivm, unsigned verbose, + LLVMValueRef rgba; + LLVMValueRef cache = NULL; + +- snprintf(name, sizeof name, "fetch_%s_%s", desc->short_name, ++ snprintf(name, 64 * sizeof(char), "fetch_%s_%s", desc->short_name, + type.floating ? "float" : "unorm8"); + + args[0] = LLVMPointerType(lp_build_vec_type(gallivm, type), 0); +@@ -139,9 +139,14 @@ test_format_float(unsigned verbose, FILE *fp, + const struct util_format_description *desc, + unsigned use_cache) + { ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef context; ++#else + LLVMContextRef context; ++#endif + struct gallivm_state *gallivm; + LLVMValueRef fetch = NULL; ++ char fetch_name[64]; + fetch_ptr_t fetch_ptr; + alignas(16) uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; + alignas(16) float unpacked[4]; +@@ -149,18 +154,29 @@ test_format_float(unsigned verbose, FILE *fp, + bool success = true; + unsigned i, j, k, l; + ++#if GALLIVM_USE_ORCJIT ++ context = LLVMOrcCreateNewThreadSafeContext(); ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); ++#endif ++#else + context = LLVMContextCreate(); + #if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(context, false); ++#endif + #endif + gallivm = gallivm_create("test_module_float", context, NULL); + + fetch = add_fetch_rgba_test(gallivm, verbose, desc, +- lp_float32_vec4_type(), use_cache); ++ lp_float32_vec4_type(), use_cache, fetch_name); + + gallivm_compile_module(gallivm); + ++#if GALLIVM_USE_ORCJIT ++ fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch_name); ++#else + fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch); ++#endif + + gallivm_free_ir(gallivm); + +@@ -228,7 +244,11 @@ test_format_float(unsigned verbose, FILE *fp, + } + + gallivm_destroy(gallivm); ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcDisposeThreadSafeContext(context); ++#else + LLVMContextDispose(context); ++#endif + + if (fp) + write_tsv_row(fp, desc, success); +@@ -243,9 +263,14 @@ test_format_unorm8(unsigned verbose, FILE *fp, + const struct util_format_description *desc, + unsigned use_cache) + { ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef context; ++#else + LLVMContextRef context; ++#endif + struct gallivm_state *gallivm; + LLVMValueRef fetch = NULL; ++ char fetch_name[64]; + fetch_ptr_t fetch_ptr; + alignas(16) uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; + uint8_t unpacked[4]; +@@ -253,18 +278,29 @@ test_format_unorm8(unsigned verbose, FILE *fp, + bool success = true; + unsigned i, j, k, l; + ++#if GALLIVM_USE_ORCJIT ++ context = LLVMOrcCreateNewThreadSafeContext(); ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); ++#endif ++#else + context = LLVMContextCreate(); + #if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(context, false); ++#endif + #endif + gallivm = gallivm_create("test_module_unorm8", context, NULL); + + fetch = add_fetch_rgba_test(gallivm, verbose, desc, +- lp_unorm8_vec4_type(), use_cache); ++ lp_unorm8_vec4_type(), use_cache, fetch_name); + + gallivm_compile_module(gallivm); + ++#if GALLIVM_USE_ORCJIT ++ fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch_name); ++#else + fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch); ++#endif + + gallivm_free_ir(gallivm); + +@@ -331,7 +367,11 @@ test_format_unorm8(unsigned verbose, FILE *fp, + } + + gallivm_destroy(gallivm); ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcDisposeThreadSafeContext(context); ++#else + LLVMContextDispose(context); ++#endif + + if (fp) + write_tsv_row(fp, desc, success); +diff --git a/src/gallium/drivers/llvmpipe/lp_test_lookup_multiple.c b/src/gallium/drivers/llvmpipe/lp_test_lookup_multiple.c +new file mode 100644 +index 0000000000000..1f59d555ec59f +--- /dev/null ++++ b/src/gallium/drivers/llvmpipe/lp_test_lookup_multiple.c +@@ -0,0 +1,172 @@ ++/************************************************************************** ++ * ++ * Copyright 2010 VMware, Inc. ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ++ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ++ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR ++ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ++ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ++ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ **************************************************************************/ ++ ++ ++#include ++#include ++ ++#include "util/u_pointer.h" ++#include "gallivm/lp_bld.h" ++#include "gallivm/lp_bld_init.h" ++#include "gallivm/lp_bld_assert.h" ++#include "gallivm/lp_bld_printf.h" ++ ++#include "lp_test.h" ++ ++ ++struct printf_test_case { ++ int foo; ++}; ++ ++void ++write_tsv_header(FILE *fp) ++{ ++ fprintf(fp, ++ "result\t" ++ "format\n"); ++ ++ fflush(fp); ++} ++ ++ ++ ++typedef void (*test_printf_t)(int i); ++ ++ ++static LLVMValueRef ++add_printf_test(struct gallivm_state *gallivm, int n, char *func_name) ++{ ++ LLVMModuleRef module = gallivm->module; ++ LLVMTypeRef args[1] = { LLVMIntTypeInContext(gallivm->context, 32) }; ++ snprintf(func_name, 64 * sizeof(char), "test_lookup_multiple_%d", n); ++ LLVMValueRef func = LLVMAddFunction(module, func_name, LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context), args, 1, 0)); ++ LLVMBuilderRef builder = gallivm->builder; ++ LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, func, "entry"); ++ ++ LLVMSetFunctionCallConv(func, LLVMCCallConv); ++ ++ LLVMPositionBuilderAtEnd(builder, block); ++ lp_build_printf(gallivm, "hello, world from "); ++ lp_build_printf(gallivm, func_name); ++ lp_build_printf(gallivm, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 5, 0), ++ LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 6, 0)); ++ ++ /* Also test lp_build_assert(). This should not fail. */ ++ lp_build_assert(gallivm, LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 1, 0), "assert(1)"); ++ ++ LLVMBuildRetVoid(builder); ++ ++ gallivm_verify_function(gallivm, func); ++ ++ return func; ++} ++ ++ ++static bool ++test_lookup_multiple(unsigned verbose, FILE *fp, ++ const struct printf_test_case *testcase) ++{ ++ struct gallivm_state *gallivm; ++ const int N = 10; ++ LLVMValueRef func[N]; ++ char func_name[N][64]; ++ test_printf_t test_lookup_multiple_func[N]; ++ bool success = true; ++ int i; ++ ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef context = LLVMOrcCreateNewThreadSafeContext(); ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); ++#endif ++#else ++ LLVMContextRef context = LLVMContextCreate(); ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(context, false); ++#endif ++#endif ++ gallivm = gallivm_create("test_module", context, NULL); ++ ++ for(i = 0; i < N; i++){ ++ func[i] = add_printf_test(gallivm, i, func_name[i]); ++ } ++ ++ gallivm_compile_module(gallivm); ++ ++#if GALLIVM_USE_ORCJIT ++ for(i = 0; i < N; i++){ ++ test_lookup_multiple_func[i] = (test_printf_t) gallivm_jit_function(gallivm, func_name[i]); ++ } ++ (void)func; ++#else ++ for(i = 0; i < N; i++){ ++ test_lookup_multiple_func[i] = (test_printf_t) gallivm_jit_function(gallivm, func[i]); ++ } ++#endif ++ ++ gallivm_free_ir(gallivm); ++ ++ for(i = 0; i < N; i++){ ++ test_lookup_multiple_func[i](0); ++ } ++ ++ gallivm_destroy(gallivm); ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcDisposeThreadSafeContext(context); ++#else ++ LLVMContextDispose(context); ++#endif ++ ++ return success; ++} ++ ++ ++bool ++test_all(unsigned verbose, FILE *fp) ++{ ++ bool success = true; ++ ++ test_lookup_multiple(verbose, fp, NULL); ++ ++ return success; ++} ++ ++ ++bool ++test_some(unsigned verbose, FILE *fp, ++ unsigned long n) ++{ ++ return test_all(verbose, fp); ++} ++ ++ ++bool ++test_single(unsigned verbose, FILE *fp) ++{ ++ printf("no test_single()"); ++ return true; ++} +diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c +index 7e53aa519280e..1f9f3b1383044 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_printf.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c +@@ -57,12 +57,18 @@ write_tsv_header(FILE *fp) + typedef void (*test_printf_t)(int i); + + ++#if GALLIVM_USE_ORCJIT ++static const char * ++add_printf_test(struct gallivm_state *gallivm) ++#else + static LLVMValueRef + add_printf_test(struct gallivm_state *gallivm) ++#endif + { + LLVMModuleRef module = gallivm->module; ++ const char *func_name = "test_printf"; + LLVMTypeRef args[1] = { LLVMIntTypeInContext(gallivm->context, 32) }; +- LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context), args, 1, 0)); ++ LLVMValueRef func = LLVMAddFunction(module, func_name, LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context), args, 1, 0)); + LLVMBuilderRef builder = gallivm->builder; + LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, func, "entry"); + +@@ -80,7 +86,11 @@ add_printf_test(struct gallivm_state *gallivm) + + gallivm_verify_function(gallivm, func); + ++#if GALLIVM_USE_ORCJIT ++ return func_name; ++#else + return func; ++#endif + } + + +@@ -89,15 +99,30 @@ static bool + test_printf(unsigned verbose, FILE *fp, + const struct printf_test_case *testcase) + { ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcThreadSafeContextRef context; ++#else + LLVMContextRef context; ++#endif + struct gallivm_state *gallivm; ++#if GALLIVM_USE_ORCJIT ++ const char *test; ++#else + LLVMValueRef test; ++#endif + test_printf_t test_printf_func; + bool success = true; + ++#if GALLIVM_USE_ORCJIT ++ context = LLVMOrcCreateNewThreadSafeContext(); ++#if LLVM_VERSION_MAJOR >= 15 ++ LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); ++#endif ++#else + context = LLVMContextCreate(); + #if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(context, false); ++#endif + #endif + gallivm = gallivm_create("test_module", context, NULL); + +@@ -112,7 +137,11 @@ test_printf(unsigned verbose, FILE *fp, + test_printf_func(0); + + gallivm_destroy(gallivm); ++#if GALLIVM_USE_ORCJIT ++ LLVMOrcDisposeThreadSafeContext(context); ++#else + LLVMContextDispose(context); ++#endif + + return success; + } +diff --git a/src/gallium/drivers/llvmpipe/lp_texture_handle.c b/src/gallium/drivers/llvmpipe/lp_texture_handle.c +index ff69fa024a53a..1f45e4ad40789 100644 +--- a/src/gallium/drivers/llvmpipe/lp_texture_handle.c ++++ b/src/gallium/drivers/llvmpipe/lp_texture_handle.c +@@ -200,14 +200,25 @@ llvmpipe_sampler_matrix_destroy(struct llvmpipe_context *ctx) + util_dynarray_fini(&ctx->sampler_matrix.gallivms); + } + ++#if GALLIVM_USE_ORCJIT ++static void * ++compile_function(struct llvmpipe_context *ctx, struct gallivm_state *gallivm, LLVMValueRef function, const char *func_name, ++ uint8_t cache_key[SHA1_DIGEST_LENGTH]) ++{ ++#else + static void * + compile_function(struct llvmpipe_context *ctx, struct gallivm_state *gallivm, LLVMValueRef function, + uint8_t cache_key[SHA1_DIGEST_LENGTH]) + { ++#endif + gallivm_verify_function(gallivm, function); + gallivm_compile_module(gallivm); + ++#if GALLIVM_USE_ORCJIT ++ void *function_ptr = func_to_pointer(gallivm_jit_function(gallivm, func_name)); ++#else + void *function_ptr = func_to_pointer(gallivm_jit_function(gallivm, function)); ++#endif + + if (!gallivm->cache->data_size) + lp_disk_cache_insert_shader(llvmpipe_screen(ctx->pipe.screen), gallivm->cache, cache_key); +@@ -333,7 +344,11 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st + + free(image_soa); + ++#if GALLIVM_USE_ORCJIT ++ return compile_function(ctx, gallivm, function, "image", cache_key); ++#else + return compile_function(ctx, gallivm, function, cache_key); ++#endif + } + + static void * +@@ -480,7 +495,11 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s + + free(sampler_soa); + ++#if GALLIVM_USE_ORCJIT ++ return compile_function(ctx, gallivm, function, "sample", cache_key); ++#else + return compile_function(ctx, gallivm, function, cache_key); ++#endif + } + + static void * +@@ -560,7 +579,11 @@ compile_size_function(struct llvmpipe_context *ctx, struct lp_static_texture_sta + + free(sampler_soa); + ++#if GALLIVM_USE_ORCJIT ++ return compile_function(ctx, gallivm, function, "size", cache_key); ++#else + return compile_function(ctx, gallivm, function, cache_key); ++#endif + } + + static void +diff --git a/src/gallium/drivers/llvmpipe/meson.build b/src/gallium/drivers/llvmpipe/meson.build +index 38ff88980f9f8..d405c67a2d631 100644 +--- a/src/gallium/drivers/llvmpipe/meson.build ++++ b/src/gallium/drivers/llvmpipe/meson.build +@@ -132,7 +132,7 @@ driver_swrast = declare_dependency( + + if with_tests and with_gallium_softpipe and draw_with_llvm + foreach t : ['lp_test_format', 'lp_test_arit', 'lp_test_blend', +- 'lp_test_conv', 'lp_test_printf'] ++ 'lp_test_conv', 'lp_test_printf', 'lp_test_lookup_multiple'] + test( + t, + executable( +diff --git a/src/util/detect_arch.h b/src/util/detect_arch.h +index 334358fcc260e..34b650734127f 100644 +--- a/src/util/detect_arch.h ++++ b/src/util/detect_arch.h +@@ -97,6 +97,17 @@ + #define DETECT_ARCH_MIPS 1 + #endif + ++#if defined(__riscv) ++#define DETECT_ARCH_RISCV 1 ++#if __riscv_xlen == 64 ++#define DETECT_ARCH_RISCV64 1 ++#elif __riscv_xlen == 32 ++#define DETECT_ARCH_RISCV32 1 ++#else ++#error "detect_arch: unknown target riscv xlen" ++#endif ++#endif ++ + #ifndef DETECT_ARCH_X86 + #define DETECT_ARCH_X86 0 + #endif +@@ -137,4 +148,16 @@ + #define DETECT_ARCH_MIPS 0 + #endif + ++#ifndef DETECT_ARCH_RISCV ++#define DETECT_ARCH_RISCV 0 ++#endif ++ ++#ifndef DETECT_ARCH_RISCV32 ++#define DETECT_ARCH_RISCV32 0 ++#endif ++ ++#ifndef DETECT_ARCH_RISCV64 ++#define DETECT_ARCH_RISCV64 0 ++#endif ++ + #endif /* UTIL_DETECT_ARCH_H_ */ +-- +GitLab + + +From f29e0c865582fd5103e8192bb35800a9299ab75e Mon Sep 17 00:00:00 2001 +From: Yukari Chiba +Date: Fri, 3 Nov 2023 23:19:27 +0800 +Subject: [PATCH 2/2] llvmpipe: make unnamed global have internal linkage + +--- + src/gallium/drivers/llvmpipe/lp_state_fs.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c +index 26273be7ab314..0c356ad32204a 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c +@@ -3309,6 +3309,7 @@ generate_fragment(struct llvmpipe_context *lp, + LLVMValueRef glob_sample_pos = + LLVMAddGlobal(gallivm->module, + LLVMArrayType(flt_type, key->coverage_samples * 2), ""); ++ LLVMSetLinkage(glob_sample_pos, LLVMInternalLinkage); + LLVMValueRef sample_pos_array; + + if (key->multisample && key->coverage_samples == 4) { +-- +GitLab + diff --git a/0001-add_loongarch64_basic_support.patch b/0001-add_loongarch64_basic_support.patch new file mode 100644 index 0000000000000000000000000000000000000000..5d274fe32f0873d185f5aa28bdfb33b09937bd8b --- /dev/null +++ b/0001-add_loongarch64_basic_support.patch @@ -0,0 +1,109 @@ +commit 8cc2495eb5fd80e8f4caf448440933939dd18668 +Author: zhaojiale +Date: Fri May 12 10:17:33 2024 +0800 + + llvmpipe: add loongarch64 basic support + + Signed-off-by: zhaojiale + +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c +index d0264e4..055ab20 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c ++++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c +@@ -2390,6 +2390,10 @@ lp_build_iround(struct lp_build_context *bld, + } + + res = LLVMBuildFPToSI(builder, res, int_vec_type, ""); ++ if (type.sign) ++ res = LLVMBuildFPToSI(builder, res, int_vec_type, ""); ++ else ++ res = LLVMBuildFPToUI(builder, res, int_vec_type, ""); + + return res; + } +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp +index 2918d38..eeed17d 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp ++++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp +@@ -171,6 +171,12 @@ disassemble(const void* func, std::ostream &buffer) + } + #endif + ++#if DETECT_ARCH_LOONGARCH64 ++ if (Size == 4 && (*(uint32_t *)(bytes+pc) >> 26) == 0x13) { ++ break; ++ } ++#endif ++ + /* + * Advance. + */ +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h +index a8db59b..30100aa 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h ++++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h +@@ -49,6 +49,12 @@ + #define GALLIVM_PERF_NO_OPT (1 << 3) + #define GALLIVM_PERF_NO_AOS_SAMPLING (1 << 4) + ++#if DETECT_ARCH_LOONGARCH64 ++#define GALLIVM_PERF_OPT_O1 (1 << 5) ++#define GALLIVM_PERF_OPT_O2 (1 << 6) ++#define GALLIVM_PERF_OPT_O3 (1 << 7) ++#endif ++ + #ifdef __cplusplus + extern "C" { + #endif +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c +index 41a6257..8560846 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c ++++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c +@@ -50,7 +50,7 @@ + #if LLVM_VERSION_MAJOR >= 7 + #include + #endif +-#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64) ++#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64 || DETECT_ARCH_LOONGARCH64) + #include + #endif + #include +@@ -64,6 +64,11 @@ static const struct debug_named_value lp_bld_perf_flags[] = { + { "no_quad_lod", GALLIVM_PERF_NO_QUAD_LOD, "disable quad_lod optimization" }, + { "no_aos_sampling", GALLIVM_PERF_NO_AOS_SAMPLING, "disable aos sampling optimization" }, + { "nopt", GALLIVM_PERF_NO_OPT, "disable optimization passes to speed up shader compilation" }, ++#if DETECT_ARCH_LOONGARCH64 ++ { "o3", GALLIVM_PERF_OPT_O3, "enable aggressive optimization passes" }, ++ { "o2", GALLIVM_PERF_OPT_O2, "enable medium optimization passes" }, ++ { "o1", GALLIVM_PERF_OPT_O1, "enable less optimization passes" }, ++#endif + DEBUG_NAMED_VALUE_END + }; + +@@ -141,7 +146,7 @@ create_pass_manager(struct gallivm_state *gallivm) + } + + #if GALLIVM_HAVE_CORO == 1 +-#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64) ++#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64 || DETECT_ARCH_LOONGARCH64) + LLVMAddArgumentPromotionPass(gallivm->cgpassmgr); + LLVMAddFunctionAttrsPass(gallivm->cgpassmgr); + #endif +@@ -281,6 +286,17 @@ init_gallivm_engine(struct gallivm_state *gallivm) + optlevel = Default; + } + ++#if DETECT_ARCH_LOONGARCH64 ++ if (gallivm_perf & GALLIVM_PERF_OPT_O3) ++ optlevel = Aggressive; ++ else if (gallivm_perf & GALLIVM_PERF_OPT_O2) ++ optlevel = Default; ++ else if (gallivm_perf & GALLIVM_PERF_OPT_O1) ++ optlevel = Less; ++ else ++ optlevel = Default; ++#endif ++ + ret = lp_build_create_jit_compiler_for_module(&gallivm->engine, + &gallivm->code, + gallivm->cache, diff --git a/0002-26018_upstream_orcjit_patch_update.patch b/0002-26018_upstream_orcjit_patch_update.patch new file mode 100644 index 0000000000000000000000000000000000000000..2eea80ac5bd7f9a7305cafd7eebab48c1af93aa3 --- /dev/null +++ b/0002-26018_upstream_orcjit_patch_update.patch @@ -0,0 +1,1316 @@ +commit 7690af15d36d8f6197272e5b3e96d450afaf3179 +Author: zhaojiale +Date: Thu May 12 10:12:00 2024 +0800 + + upstream orcjit patch update + + - update commit from upstream: + e64ed86cf02ccaf0f4231aba17d742781a677336 + + Signed-off-by: Yukari Chiba + zhaojiale + +diff --git a/meson.build b/meson.build +index 07e7869..4c9fdc0 100644 +--- a/meson.build ++++ b/meson.build +@@ -1687,10 +1687,8 @@ if draw_with_llvm + llvm_optional_modules += ['lto'] + endif + +-if with_amd_vk or with_gallium_radeonsi ++if with_amd_vk or with_gallium_radeonsi or llvm_with_orcjit + _llvm_version = '>= 15.0.0' +-elif with_intel_clc or llvm_with_orcjit +- _llvm_version = '>= 13.0.0' + elif with_gallium_opencl + _llvm_version = '>= 11.0.0' + elif with_clc +diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c +index 4d6cb70..5edbcd9 100644 +--- a/src/gallium/auxiliary/draw/draw_context.c ++++ b/src/gallium/auxiliary/draw/draw_context.c +@@ -77,7 +77,7 @@ draw_create_context(struct pipe_context *pipe, void *context, + + #ifdef DRAW_LLVM_AVAILABLE + if (try_llvm && draw_get_option_use_llvm()) { +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + draw->llvm = draw_llvm_create(draw, (LLVMOrcThreadSafeContextRef)context); + #else + draw->llvm = draw_llvm_create(draw, (LLVMContextRef)context); +diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c +index 0ea4fb1..eeb0f93 100644 +--- a/src/gallium/auxiliary/draw/draw_llvm.c ++++ b/src/gallium/auxiliary/draw/draw_llvm.c +@@ -381,7 +381,7 @@ get_vertex_header_ptr_type(struct draw_llvm_variant *variant) + /** + * Create per-context LLVM info. + */ +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + struct draw_llvm * + draw_llvm_create(struct draw_context *draw, LLVMOrcThreadSafeContextRef context) + #else +@@ -400,7 +400,7 @@ draw_llvm_create(struct draw_context *draw, LLVMContextRef context) + + llvm->draw = draw; + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + llvm->_ts_context = context; + if (!llvm->_ts_context) { + llvm->_ts_context = LLVMOrcCreateNewThreadSafeContext(); +@@ -450,7 +450,7 @@ fail: + void + draw_llvm_destroy(struct draw_llvm *llvm) + { +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + if (llvm->context_owned) + LLVMOrcDisposeThreadSafeContext(llvm->_ts_context); + llvm->_ts_context = NULL; +@@ -533,7 +533,7 @@ draw_llvm_create_variant(struct draw_llvm *llvm, + if (!cached.data_size) + needs_caching = true; + } +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + variant->gallivm = gallivm_create(module_name, llvm->_ts_context, &cached); + #else + variant->gallivm = gallivm_create(module_name, llvm->context, &cached); +@@ -556,13 +556,9 @@ draw_llvm_create_variant(struct draw_llvm *llvm, + + gallivm_compile_module(variant->gallivm); + +-#if GALLIVM_USE_ORCJIT + variant->jit_func = (draw_jit_vert_func) +- gallivm_jit_function(variant->gallivm, variant->function_name); +-#else +- variant->jit_func = (draw_jit_vert_func) +- gallivm_jit_function(variant->gallivm, variant->function); +-#endif ++ gallivm_jit_function(variant->gallivm, variant->function, ++ variant->function_name); + + if (needs_caching) + llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, +@@ -1662,10 +1658,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) + + variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); + variant->function = variant_func; +-#if GALLIVM_USE_ORCJIT + variant->function_name = MALLOC(strlen(func_name)+1); + strcpy(variant->function_name, func_name); +-#endif + + LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); + for (i = 0; i < num_arg_types; ++i) +@@ -2278,10 +2272,8 @@ draw_llvm_destroy_variant(struct draw_llvm_variant *variant) + list_del(&variant->list_item_global.list); + llvm->nr_variants--; + +-#if GALLIVM_USE_ORCJIT + if(variant->function_name) + FREE(variant->function_name); +-#endif + FREE(variant); + } + +@@ -2391,10 +2383,8 @@ draw_gs_llvm_generate(struct draw_llvm *llvm, + variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); + + variant->function = variant_func; +-#if GALLIVM_USE_ORCJIT + variant->function_name = MALLOC(strlen(func_name)+1); + strcpy(variant->function_name, func_name); +-#endif + + LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); + +@@ -2560,7 +2550,7 @@ draw_gs_llvm_create_variant(struct draw_llvm *llvm, + if (!cached.data_size) + needs_caching = true; + } +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + variant->gallivm = gallivm_create(module_name, llvm->_ts_context, &cached); + #else + variant->gallivm = gallivm_create(module_name, llvm->context, &cached); +@@ -2575,13 +2565,9 @@ draw_gs_llvm_create_variant(struct draw_llvm *llvm, + + gallivm_compile_module(variant->gallivm); + +-#if GALLIVM_USE_ORCJIT +- variant->jit_func = (draw_gs_jit_func) +- gallivm_jit_function(variant->gallivm, variant->function_name); +-#else + variant->jit_func = (draw_gs_jit_func) +- gallivm_jit_function(variant->gallivm, variant->function); +-#endif ++ gallivm_jit_function(variant->gallivm, variant->function, ++ variant->function_name); + + if (needs_caching) + llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, +@@ -2614,10 +2600,8 @@ draw_gs_llvm_destroy_variant(struct draw_gs_llvm_variant *variant) + variant->shader->variants_cached--; + list_del(&variant->list_item_global.list); + llvm->nr_gs_variants--; +-#if GALLIVM_USE_ORCJIT + if(variant->function_name) + FREE(variant->function_name); +-#endif + FREE(variant); + } + +@@ -2991,10 +2975,8 @@ draw_tcs_llvm_generate(struct draw_llvm *llvm, + variant_coro = LLVMAddFunction(gallivm->module, func_name_coro, coro_func_type); + + variant->function = variant_func; +-#if GALLIVM_USE_ORCJIT + variant->function_name = MALLOC(strlen(func_name)+1); + strcpy(variant->function_name, func_name); +-#endif + LLVMSetFunctionCallConv(variant_func, LLVMCCallConv); + + LLVMSetFunctionCallConv(variant_coro, LLVMCCallConv); +@@ -3230,7 +3212,7 @@ draw_tcs_llvm_create_variant(struct draw_llvm *llvm, + if (!cached.data_size) + needs_caching = true; + } +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + variant->gallivm = gallivm_create(module_name, llvm->_ts_context, &cached); + #else + variant->gallivm = gallivm_create(module_name, llvm->context, &cached); +@@ -3247,13 +3229,9 @@ draw_tcs_llvm_create_variant(struct draw_llvm *llvm, + + gallivm_compile_module(variant->gallivm); + +-#if GALLIVM_USE_ORCJIT +- variant->jit_func = (draw_tcs_jit_func) +- gallivm_jit_function(variant->gallivm, variant->function_name); +-#else + variant->jit_func = (draw_tcs_jit_func) +- gallivm_jit_function(variant->gallivm, variant->function); +-#endif ++ gallivm_jit_function(variant->gallivm, variant->function, ++ variant->function_name); + + if (needs_caching) + llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, +@@ -3286,10 +3264,8 @@ draw_tcs_llvm_destroy_variant(struct draw_tcs_llvm_variant *variant) + variant->shader->variants_cached--; + list_del(&variant->list_item_global.list); + llvm->nr_tcs_variants--; +-#if GALLIVM_USE_ORCJIT + if(variant->function_name) + FREE(variant->function_name); +-#endif + FREE(variant); + } + +@@ -3572,7 +3548,7 @@ draw_tes_llvm_generate(struct draw_llvm *llvm, + variant_func = LLVMAddFunction(gallivm->module, func_name, func_type); + + variant->function = variant_func; +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + variant->function_name = MALLOC(strlen(func_name)+1); + strcpy(variant->function_name, func_name); + #endif +@@ -3766,7 +3742,7 @@ draw_tes_llvm_create_variant(struct draw_llvm *llvm, + if (!cached.data_size) + needs_caching = true; + } +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + variant->gallivm = gallivm_create(module_name, llvm->_ts_context, &cached); + #else + variant->gallivm = gallivm_create(module_name, llvm->context, &cached); +@@ -3786,13 +3762,9 @@ draw_tes_llvm_create_variant(struct draw_llvm *llvm, + + gallivm_compile_module(variant->gallivm); + +-#if GALLIVM_USE_ORCJIT + variant->jit_func = (draw_tes_jit_func) +- gallivm_jit_function(variant->gallivm, variant->function_name); +-#else +- variant->jit_func = (draw_tes_jit_func) +- gallivm_jit_function(variant->gallivm, variant->function); +-#endif ++ gallivm_jit_function(variant->gallivm, variant->function, ++ variant->function_name); + + if (needs_caching) + llvm->draw->disk_cache_insert_shader(llvm->draw->disk_cache_cookie, +@@ -3825,10 +3797,8 @@ draw_tes_llvm_destroy_variant(struct draw_tes_llvm_variant *variant) + variant->shader->variants_cached--; + list_del(&variant->list_item_global.list); + llvm->nr_tes_variants--; +-#if GALLIVM_USE_ORCJIT + if(variant->function_name) + FREE(variant->function_name); +-#endif + FREE(variant); + } + +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_coro.c b/src/gallium/auxiliary/gallivm/lp_bld_coro.c +index e5b4890..f5a2b31 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_coro.c ++++ b/src/gallium/auxiliary/gallivm/lp_bld_coro.c +@@ -156,7 +156,7 @@ coro_free(char *ptr) + + void lp_build_coro_add_malloc_hooks(struct gallivm_state *gallivm) + { +-#if !GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 0 + assert(gallivm->engine); + #endif + +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c +index 41a6257..9750cf7 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c ++++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c +@@ -718,7 +718,7 @@ gallivm_compile_module(struct gallivm_state *gallivm) + + func_pointer + gallivm_jit_function(struct gallivm_state *gallivm, +- LLVMValueRef func) ++ LLVMValueRef func, const char *func_name) + { + void *code; + func_pointer jit_func; +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h +index 0fe8466..f425ebb 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_init.h ++++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h +@@ -32,7 +32,7 @@ + #include "util/compiler.h" + #include "util/u_pointer.h" // for func_pointer + #include "lp_bld.h" +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + #include + #else + #include +@@ -48,7 +48,7 @@ struct gallivm_state + char *module_name; + LLVMModuleRef module; + LLVMTargetDataRef target; +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + /* own this->module */ + LLVMOrcThreadSafeContextRef _ts_context; + /* each module is in its own jitdylib */ +@@ -64,10 +64,8 @@ struct gallivm_state + LLVMMCJITMemoryManagerRef memorymgr; + struct lp_generated_code *code; + #endif +- + LLVMContextRef context; + LLVMBuilderRef builder; +- + struct lp_cached_code *cache; + unsigned compiled; + LLVMValueRef coro_malloc_hook; +@@ -89,7 +87,7 @@ lp_build_init_native_width(void); + bool + lp_build_init(void); + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + struct gallivm_state * + gallivm_create(const char *name, LLVMOrcThreadSafeContextRef context, + struct lp_cached_code *cache); +@@ -120,15 +118,9 @@ gallivm_add_global_mapping(struct gallivm_state *gallivm, LLVMValueRef sym, void + void + gallivm_compile_module(struct gallivm_state *gallivm); + +-#if GALLIVM_USE_ORCJIT +-func_pointer +-gallivm_jit_function(struct gallivm_state *gallivm, +- const char *func_name); +-#else + func_pointer + gallivm_jit_function(struct gallivm_state *gallivm, +- LLVMValueRef func); +-#endif ++ LLVMValueRef func, const char *func_name); + + unsigned gallivm_get_perf_flags(void); + +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp +index 6a74cc9..797c9e1 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp ++++ b/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp +@@ -16,10 +16,12 @@ + #include + + #include ++#if LLVM_VERSION_MAJOR < 17 + #include + #if LLVM_VERSION_MAJOR >= 7 + #include + #endif ++#endif + #include + #if GALLIVM_USE_NEW_PASS == 1 + #include +@@ -37,7 +39,11 @@ + #include + #include + #include ++#if LLVM_VERSION_MAJOR >= 18 ++#include ++#else + #include ++#endif + #include + #if LLVM_USE_INTEL_JITEVENTS + #include +@@ -199,7 +205,13 @@ public: + LLVMValueRef sym, + void *addr, + LLVMOrcJITDylibRef jd) { ++#if LLVM_VERSION_MAJOR >= 17 ++ using llvm::orc::ExecutorAddr; ++ using llvm::orc::ExecutorSymbolDef; ++ using llvm::JITSymbolFlags; ++#else + using llvm::JITEvaluatedSymbol; ++#endif + using llvm::orc::ExecutionSession; + using llvm::orc::JITDylib; + using llvm::orc::SymbolMap; +@@ -207,7 +219,11 @@ public: + auto& es = LPJit::get_instance()->lljit->getExecutionSession(); + auto name = es.intern(llvm::unwrap(sym)->getName()); + SymbolMap map(1); ++#if LLVM_VERSION_MAJOR >= 17 ++ map[name] = ExecutorSymbolDef(ExecutorAddr::fromPtr(addr), JITSymbolFlags::Exported); ++#else + map[name] = JITEvaluatedSymbol::fromPointer(addr); ++#endif + auto munit = llvm::orc::absoluteSymbols(map); + llvm::cantFail(JD->define(std::move(munit))); + } +@@ -922,7 +938,7 @@ gallivm_compile_module(struct gallivm_state *gallivm) + + func_pointer + gallivm_jit_function(struct gallivm_state *gallivm, +- const char *func_name) ++ LLVMValueRef func, const char *func_name) + { + return pointer_to_func( + LPJit::lookup_in_jd(func_name, gallivm->_per_module_jd)); +diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c +index d77da46..479e46a 100644 +--- a/src/gallium/drivers/llvmpipe/lp_context.c ++++ b/src/gallium/drivers/llvmpipe/lp_context.c +@@ -49,7 +49,7 @@ + #include "lp_screen.h" + #include "lp_fence.h" + +-#if !GALLIVM_USE_ORCJIT ++#if !(GALLIVM_USE_ORCJIT == 1) + #define USE_GLOBAL_LLVM_CONTEXT + #endif + +@@ -112,7 +112,7 @@ llvmpipe_destroy(struct pipe_context *pipe) + llvmpipe_sampler_matrix_destroy(llvmpipe); + + #ifndef USE_GLOBAL_LLVM_CONTEXT +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcDisposeThreadSafeContext(llvmpipe->context); + #else + LLVMContextDispose(llvmpipe->context); +@@ -267,7 +267,7 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, + #ifdef USE_GLOBAL_LLVM_CONTEXT + llvmpipe->context = LLVMGetGlobalContext(); + #else +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + llvmpipe->context = LLVMOrcCreateNewThreadSafeContext(); + #else + llvmpipe->context = LLVMContextCreate(); +@@ -277,12 +277,12 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, + if (!llvmpipe->context) + goto fail; + +-#if GALLIVM_USE_ORCJIT +-#if LLVM_VERSION_MAJOR >= 15 ++#if GALLIVM_USE_ORCJIT == 1 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(llvmpipe->context), false); + #endif + #else +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(llvmpipe->context, false); + #endif + #endif +diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h +index 231479e..d30aa89 100644 +--- a/src/gallium/drivers/llvmpipe/lp_context.h ++++ b/src/gallium/drivers/llvmpipe/lp_context.h +@@ -190,7 +190,7 @@ struct llvmpipe_context { + unsigned render_cond_offset; + + /** The LLVMContext to use for LLVM related work */ +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcThreadSafeContextRef context; + #else + LLVMContextRef context; +diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c +index dba0f7b..606cfeb 100644 +--- a/src/gallium/drivers/llvmpipe/lp_screen.c ++++ b/src/gallium/drivers/llvmpipe/lp_screen.c +@@ -951,7 +951,7 @@ static void + lp_disk_cache_create(struct llvmpipe_screen *screen) + { + struct mesa_sha1 ctx; +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + unsigned gallivm_perf = 0; + #else + unsigned gallivm_perf = gallivm_get_perf_flags(); +diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.c b/src/gallium/drivers/llvmpipe/lp_state_cs.c +index 7528f68..1a05866 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_cs.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_cs.c +@@ -398,10 +398,8 @@ generate_compute(struct llvmpipe_context *lp, + lp_build_coro_add_presplit(coro); + + variant->function = function; +-#if GALLIVM_USE_ORCJIT + variant->function_name = MALLOC(strlen(func_name)+1); + strcpy(variant->function_name, func_name); +-#endif + + for (i = 0; i < CS_ARG_MAX - !is_mesh; ++i) { + if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) { +@@ -1052,10 +1050,8 @@ llvmpipe_remove_cs_shader_variant(struct llvmpipe_context *lp, + lp->nr_cs_variants--; + lp->nr_cs_instrs -= variant->nr_instrs; + +-#if GALLIVM_USE_ORCJIT + if(variant->function_name) + FREE(variant->function_name); +-#endif + FREE(variant); + } + +@@ -1314,22 +1310,20 @@ generate_variant(struct llvmpipe_context *lp, + + generate_compute(lp, shader, variant); + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + /* module has been moved into ORCJIT after gallivm_compile_module */ + variant->nr_instrs += lp_build_count_ir_module(variant->gallivm->module); + + gallivm_compile_module(variant->gallivm); +- +- variant->jit_function = (lp_jit_cs_func) +- gallivm_jit_function(variant->gallivm, variant->function_name); + #else + gallivm_compile_module(variant->gallivm); + + variant->nr_instrs += lp_build_count_ir_module(variant->gallivm->module); ++#endif + + variant->jit_function = (lp_jit_cs_func) +- gallivm_jit_function(variant->gallivm, variant->function); +-#endif ++ gallivm_jit_function(variant->gallivm, variant->function, ++ variant->function_name); + + if (needs_caching) { + lp_disk_cache_insert_shader(screen, &cached, ir_sha1_cache_key); +diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.h b/src/gallium/drivers/llvmpipe/lp_state_cs.h +index bdf579a..0f69d05 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_cs.h ++++ b/src/gallium/drivers/llvmpipe/lp_state_cs.h +@@ -91,9 +91,7 @@ struct lp_compute_shader_variant + LLVMTypeRef jit_vertex_header_ptr_type; + LLVMTypeRef jit_prim_type; + LLVMValueRef function; +-#if GALLIVM_USE_ORCJIT + char* function_name; +-#endif + lp_jit_cs_func jit_function; + + /* Total number of LLVM instructions generated */ +diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c +index 0c356ad..32b1b7a 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c +@@ -3206,10 +3206,8 @@ generate_fragment(struct llvmpipe_context *lp, + LLVMSetFunctionCallConv(function, LLVMCCallConv); + + variant->function[partial_mask] = function; +-#if GALLIVM_USE_ORCJIT + variant->function_name[partial_mask] = MALLOC(strlen(func_name)+1); + strcpy(variant->function_name[partial_mask], func_name); +-#endif + + /* XXX: need to propagate noalias down into color param now we are + * passing a pointer-to-pointer? +@@ -3917,7 +3915,7 @@ generate_variant(struct llvmpipe_context *lp, + * Compile everything + */ + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + /* module has been moved into ORCJIT after gallivm_compile_module */ + variant->nr_instrs += lp_build_count_ir_module(variant->gallivm->module); + +@@ -3930,24 +3928,16 @@ generate_variant(struct llvmpipe_context *lp, + + if (variant->function[RAST_EDGE_TEST]) { + variant->jit_function[RAST_EDGE_TEST] = (lp_jit_frag_func) +-#if GALLIVM_USE_ORCJIT + gallivm_jit_function(variant->gallivm, ++ variant->function[RAST_EDGE_TEST], + variant->function_name[RAST_EDGE_TEST]); +-#else +- gallivm_jit_function(variant->gallivm, +- variant->function[RAST_EDGE_TEST]); +-#endif + } + + if (variant->function[RAST_WHOLE]) { + variant->jit_function[RAST_WHOLE] = (lp_jit_frag_func) +-#if GALLIVM_USE_ORCJIT + gallivm_jit_function(variant->gallivm, ++ variant->function[RAST_WHOLE], + variant->function_name[RAST_WHOLE]); +-#else +- gallivm_jit_function(variant->gallivm, +- variant->function[RAST_WHOLE]); +-#endif + } else if (!variant->jit_function[RAST_WHOLE]) { + variant->jit_function[RAST_WHOLE] = (lp_jit_frag_func) + variant->jit_function[RAST_EDGE_TEST]; +@@ -3956,11 +3946,8 @@ generate_variant(struct llvmpipe_context *lp, + if (linear_pipeline) { + if (variant->linear_function) { + variant->jit_linear_llvm = (lp_jit_linear_llvm_func) +-#if GALLIVM_USE_ORCJIT +- gallivm_jit_function(variant->gallivm, variant->linear_function_name); +-#else +- gallivm_jit_function(variant->gallivm, variant->linear_function); +-#endif ++ gallivm_jit_function(variant->gallivm, variant->linear_function, ++ variant->linear_function_name); + } + + /* +@@ -4136,14 +4123,12 @@ llvmpipe_destroy_shader_variant(struct llvmpipe_context *lp, + { + gallivm_destroy(variant->gallivm); + lp_fs_reference(lp, &variant->shader, NULL); +-#if GALLIVM_USE_ORCJIT + if (variant->function_name[RAST_EDGE_TEST]) + FREE(variant->function_name[RAST_EDGE_TEST]); + if (variant->function_name[RAST_WHOLE]) + FREE(variant->function_name[RAST_WHOLE]); + if (variant->linear_function_name) + FREE(variant->linear_function_name); +-#endif + FREE(variant); + } + +diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h +index 4b7126a..c2fa210 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_fs.h ++++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h +@@ -168,9 +168,7 @@ struct lp_fragment_shader_variant + LLVMTypeRef jit_linear_textures_type; + + LLVMValueRef function[2]; // [RAST_WHOLE], [RAST_EDGE_TEST] +-#if GALLIVM_USE_ORCJIT + char* function_name[2]; +-#endif + + lp_jit_frag_func jit_function[2]; // [RAST_WHOLE], [RAST_EDGE_TEST] + +@@ -180,9 +178,7 @@ struct lp_fragment_shader_variant + /* Functions within the linear path: + */ + LLVMValueRef linear_function; +-#if GALLIVM_USE_ORCJIT + char* linear_function_name; +-#endif + lp_jit_linear_llvm_func jit_linear_llvm; + + /* Bitmask to say what cbufs are unswizzled */ +diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c b/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c +index e0669a3..70db126 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c +@@ -289,10 +289,8 @@ llvmpipe_fs_variant_linear_llvm(struct llvmpipe_context *lp, + LLVMSetFunctionCallConv(function, LLVMCCallConv); + + variant->linear_function = function; +-#if GALLIVM_USE_ORCJIT + variant->linear_function_name = MALLOC(strlen(func_name)+1); + strcpy(variant->linear_function_name, func_name); +-#endif + + /* XXX: need to propagate noalias down into color param now we are + * passing a pointer-to-pointer? +diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c +index 309aaee..a68e960 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_setup.c ++++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c +@@ -688,10 +688,8 @@ generate_setup_variant(struct lp_setup_variant_key *key, + arg_types, ARRAY_SIZE(arg_types), 0); + + variant->function = LLVMAddFunction(gallivm->module, func_name, func_type); +-#if GALLIVM_USE_ORCJIT + variant->function_name = MALLOC(strlen(func_name)+1); + strcpy(variant->function_name, func_name); +-#endif + if (!variant->function) + goto fail; + +@@ -735,13 +733,8 @@ generate_setup_variant(struct lp_setup_variant_key *key, + + gallivm_compile_module(gallivm); + +-#if GALLIVM_USE_ORCJIT + variant->jit_function = (lp_jit_setup_triangle) +- gallivm_jit_function(gallivm, variant->function_name); +-#else +- variant->jit_function = (lp_jit_setup_triangle) +- gallivm_jit_function(gallivm, variant->function); +-#endif ++ gallivm_jit_function(gallivm, variant->function, variant->function_name); + if (!variant->jit_function) + goto fail; + +diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.h b/src/gallium/drivers/llvmpipe/lp_state_setup.h +index 38a624c..5882ce1 100644 +--- a/src/gallium/drivers/llvmpipe/lp_state_setup.h ++++ b/src/gallium/drivers/llvmpipe/lp_state_setup.h +@@ -66,9 +66,7 @@ struct lp_setup_variant { + * assembly. + */ + LLVMValueRef function; +-#if GALLIVM_USE_ORCJIT + char *function_name; +-#endif + + /* The actual generated setup function: + */ +diff --git a/src/gallium/drivers/llvmpipe/lp_test_arit.c b/src/gallium/drivers/llvmpipe/lp_test_arit.c +index abd93a2..13a755e 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_arit.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_arit.c +@@ -417,7 +417,7 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test, unsigned + { + char test_name[128]; + snprintf(test_name, sizeof test_name, "%s.v%u", test->name, length); +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcThreadSafeContextRef context; + #else + LLVMContextRef context; +@@ -437,9 +437,9 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test, unsigned + in[i] = 1.0; + } + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + context = LLVMOrcCreateNewThreadSafeContext(); +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); + #endif + #else +@@ -454,11 +454,7 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test, unsigned + + gallivm_compile_module(gallivm); + +-#if GALLIVM_USE_ORCJIT +- test_func_jit = (unary_func_t) gallivm_jit_function(gallivm, test_name); +-#else +- test_func_jit = (unary_func_t) gallivm_jit_function(gallivm, test_func); +-#endif ++ test_func_jit = (unary_func_t) gallivm_jit_function(gallivm, test_func, test_name); + + gallivm_free_ir(gallivm); + +@@ -527,7 +523,7 @@ test_unary(unsigned verbose, FILE *fp, const struct unary_test_t *test, unsigned + } + + gallivm_destroy(gallivm); +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcDisposeThreadSafeContext(context); + #else + LLVMContextDispose(context); +diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c +index 8c30a7d..4182d98 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c +@@ -131,24 +131,16 @@ dump_blend_type(FILE *fp, + } + + +-#if GALLIVM_USE_ORCJIT +-static const char * +-add_blend_test(struct gallivm_state *gallivm, +- const struct pipe_blend_state *blend, +- struct lp_type type) +-#else + static LLVMValueRef + add_blend_test(struct gallivm_state *gallivm, + const struct pipe_blend_state *blend, + struct lp_type type) +-#endif + { + LLVMModuleRef module = gallivm->module; + LLVMContextRef context = gallivm->context; + LLVMTypeRef vec_type; + LLVMTypeRef args[5]; + LLVMValueRef func; +- const char *func_name = "test"; + LLVMValueRef src_ptr; + LLVMValueRef src1_ptr; + LLVMValueRef dst_ptr; +@@ -168,7 +160,7 @@ add_blend_test(struct gallivm_state *gallivm, + vec_type = lp_build_vec_type(gallivm, type); + + args[4] = args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0); +- func = LLVMAddFunction(module, func_name, LLVMFunctionType(LLVMVoidTypeInContext(context), args, 5, 0)); ++ func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 5, 0)); + LLVMSetFunctionCallConv(func, LLVMCCallConv); + src_ptr = LLVMGetParam(func, 0); + src1_ptr = LLVMGetParam(func, 1); +@@ -196,11 +188,7 @@ add_blend_test(struct gallivm_state *gallivm, + + gallivm_verify_function(gallivm, func); + +-#if GALLIVM_USE_ORCJIT +- return func_name; +-#else + return func; +-#endif + } + + +@@ -449,17 +437,13 @@ test_one(unsigned verbose, + const struct pipe_blend_state *blend, + struct lp_type type) + { +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcThreadSafeContextRef context; + #else + LLVMContextRef context; + #endif + struct gallivm_state *gallivm; +-#if GALLIVM_USE_ORCJIT +- const char *func; +-#else + LLVMValueRef func = NULL; +-#endif + blend_test_ptr_t blend_test_ptr; + bool success; + const unsigned n = LP_TEST_NUM_SAMPLES; +@@ -471,9 +455,9 @@ test_one(unsigned verbose, + if (verbose >= 1) + dump_blend_type(stdout, blend, type); + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + context = LLVMOrcCreateNewThreadSafeContext(); +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); + #endif + #else +@@ -488,7 +472,7 @@ test_one(unsigned verbose, + + gallivm_compile_module(gallivm); + +- blend_test_ptr = (blend_test_ptr_t)gallivm_jit_function(gallivm, func); ++ blend_test_ptr = (blend_test_ptr_t)gallivm_jit_function(gallivm, func,"test"); + + gallivm_free_ir(gallivm); + +diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c +index b8c58cd..2468dbb 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_conv.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c +@@ -96,24 +96,16 @@ dump_conv_types(FILE *fp, + } + + +-#if GALLIVM_USE_ORCJIT +-static const char * +-add_conv_test(struct gallivm_state *gallivm, +- struct lp_type src_type, unsigned num_srcs, +- struct lp_type dst_type, unsigned num_dsts) +-#else + static LLVMValueRef + add_conv_test(struct gallivm_state *gallivm, + struct lp_type src_type, unsigned num_srcs, + struct lp_type dst_type, unsigned num_dsts) +-#endif + { + LLVMModuleRef module = gallivm->module; + LLVMContextRef context = gallivm->context; + LLVMBuilderRef builder = gallivm->builder; + LLVMTypeRef args[2]; + LLVMValueRef func; +- const char *func_name = "test"; + LLVMValueRef src_ptr; + LLVMValueRef dst_ptr; + LLVMBasicBlockRef block; +@@ -126,7 +118,7 @@ add_conv_test(struct gallivm_state *gallivm, + args[0] = LLVMPointerType(src_vec_type, 0); + args[1] = LLVMPointerType(dst_vec_type, 0); + +- func = LLVMAddFunction(module, func_name, ++ func = LLVMAddFunction(module, "test", + LLVMFunctionType(LLVMVoidTypeInContext(context), + args, 2, 0)); + LLVMSetFunctionCallConv(func, LLVMCCallConv); +@@ -154,11 +146,7 @@ add_conv_test(struct gallivm_state *gallivm, + + gallivm_verify_function(gallivm, func); + +-#if GALLIVM_USE_ORCJIT +- return func_name; +-#else + return func; +-#endif + } + + +@@ -169,17 +157,13 @@ test_one(unsigned verbose, + struct lp_type src_type, + struct lp_type dst_type) + { +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcThreadSafeContextRef context; + #else + LLVMContextRef context; + #endif + struct gallivm_state *gallivm; +-#if GALLIVM_USE_ORCJIT +- const char *func; +-#else + LLVMValueRef func = NULL; +-#endif + conv_test_ptr_t conv_test_ptr; + bool success; + const unsigned n = LP_TEST_NUM_SAMPLES; +@@ -242,9 +226,9 @@ test_one(unsigned verbose, + eps *= 2; + } + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + context = LLVMOrcCreateNewThreadSafeContext(); +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); + #endif + #else +@@ -259,7 +243,7 @@ test_one(unsigned verbose, + + gallivm_compile_module(gallivm); + +- conv_test_ptr = (conv_test_ptr_t)gallivm_jit_function(gallivm, func); ++ conv_test_ptr = (conv_test_ptr_t)gallivm_jit_function(gallivm, func, "test"); + + gallivm_free_ir(gallivm); + +@@ -364,7 +348,7 @@ test_one(unsigned verbose, + write_tsv_row(fp, src_type, dst_type, cycles_avg, success); + + gallivm_destroy(gallivm); +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcDisposeThreadSafeContext(context); + #else + LLVMContextDispose(context); +diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c +index 23d69c7..c4b38de 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_format.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_format.c +@@ -80,7 +80,7 @@ add_fetch_rgba_test(struct gallivm_state *gallivm, unsigned verbose, + const struct util_format_description *desc, + struct lp_type type, + unsigned use_cache, +- char *name) ++ char *name) + { + LLVMContextRef context = gallivm->context; + LLVMModuleRef module = gallivm->module; +@@ -139,7 +139,7 @@ test_format_float(unsigned verbose, FILE *fp, + const struct util_format_description *desc, + unsigned use_cache) + { +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcThreadSafeContextRef context; + #else + LLVMContextRef context; +@@ -154,9 +154,9 @@ test_format_float(unsigned verbose, FILE *fp, + bool success = true; + unsigned i, j, k, l; + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + context = LLVMOrcCreateNewThreadSafeContext(); +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); + #endif + #else +@@ -172,11 +172,7 @@ test_format_float(unsigned verbose, FILE *fp, + + gallivm_compile_module(gallivm); + +-#if GALLIVM_USE_ORCJIT +- fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch_name); +-#else +- fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch); +-#endif ++ fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch, fetch_name); + + gallivm_free_ir(gallivm); + +@@ -244,7 +240,7 @@ test_format_float(unsigned verbose, FILE *fp, + } + + gallivm_destroy(gallivm); +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcDisposeThreadSafeContext(context); + #else + LLVMContextDispose(context); +@@ -263,7 +259,7 @@ test_format_unorm8(unsigned verbose, FILE *fp, + const struct util_format_description *desc, + unsigned use_cache) + { +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcThreadSafeContextRef context; + #else + LLVMContextRef context; +@@ -278,9 +274,9 @@ test_format_unorm8(unsigned verbose, FILE *fp, + bool success = true; + unsigned i, j, k, l; + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + context = LLVMOrcCreateNewThreadSafeContext(); +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); + #endif + #else +@@ -296,11 +292,7 @@ test_format_unorm8(unsigned verbose, FILE *fp, + + gallivm_compile_module(gallivm); + +-#if GALLIVM_USE_ORCJIT +- fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch_name); +-#else +- fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch); +-#endif ++ fetch_ptr = (fetch_ptr_t) gallivm_jit_function(gallivm, fetch, fetch_name); + + gallivm_free_ir(gallivm); + +@@ -367,7 +359,7 @@ test_format_unorm8(unsigned verbose, FILE *fp, + } + + gallivm_destroy(gallivm); +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcDisposeThreadSafeContext(context); + #else + LLVMContextDispose(context); +diff --git a/src/gallium/drivers/llvmpipe/lp_test_lookup_multiple.c b/src/gallium/drivers/llvmpipe/lp_test_lookup_multiple.c +index 1f59d55..dea0e50 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_lookup_multiple.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_lookup_multiple.c +@@ -92,20 +92,22 @@ test_lookup_multiple(unsigned verbose, FILE *fp, + { + struct gallivm_state *gallivm; + const int N = 10; +- LLVMValueRef func[N]; ++ LLVMValueRef *func = ++ (LLVMValueRef *) malloc(N * sizeof(LLVMValueRef)); + char func_name[N][64]; +- test_printf_t test_lookup_multiple_func[N]; ++ test_printf_t *test_lookup_multiple_func = ++ (test_printf_t *)malloc(N * sizeof(test_printf_t)); + bool success = true; + int i; + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcThreadSafeContextRef context = LLVMOrcCreateNewThreadSafeContext(); +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); + #endif + #else + LLVMContextRef context = LLVMContextCreate(); +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(context, false); + #endif + #endif +@@ -117,16 +119,9 @@ test_lookup_multiple(unsigned verbose, FILE *fp, + + gallivm_compile_module(gallivm); + +-#if GALLIVM_USE_ORCJIT + for(i = 0; i < N; i++){ +- test_lookup_multiple_func[i] = (test_printf_t) gallivm_jit_function(gallivm, func_name[i]); ++ test_lookup_multiple_func[i] = (test_printf_t) gallivm_jit_function(gallivm, func[i], func_name[i]); + } +- (void)func; +-#else +- for(i = 0; i < N; i++){ +- test_lookup_multiple_func[i] = (test_printf_t) gallivm_jit_function(gallivm, func[i]); +- } +-#endif + + gallivm_free_ir(gallivm); + +@@ -134,8 +129,11 @@ test_lookup_multiple(unsigned verbose, FILE *fp, + test_lookup_multiple_func[i](0); + } + ++ FREE(func); ++ FREE(test_lookup_multiple_func); ++ + gallivm_destroy(gallivm); +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcDisposeThreadSafeContext(context); + #else + LLVMContextDispose(context); +@@ -144,7 +142,6 @@ test_lookup_multiple(unsigned verbose, FILE *fp, + return success; + } + +- + bool + test_all(unsigned verbose, FILE *fp) + { +diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c +index 1f9f3b1..f76cc16 100644 +--- a/src/gallium/drivers/llvmpipe/lp_test_printf.c ++++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c +@@ -57,18 +57,12 @@ write_tsv_header(FILE *fp) + typedef void (*test_printf_t)(int i); + + +-#if GALLIVM_USE_ORCJIT +-static const char * +-add_printf_test(struct gallivm_state *gallivm) +-#else + static LLVMValueRef + add_printf_test(struct gallivm_state *gallivm) +-#endif + { + LLVMModuleRef module = gallivm->module; +- const char *func_name = "test_printf"; + LLVMTypeRef args[1] = { LLVMIntTypeInContext(gallivm->context, 32) }; +- LLVMValueRef func = LLVMAddFunction(module, func_name, LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context), args, 1, 0)); ++ LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context), args, 1, 0)); + LLVMBuilderRef builder = gallivm->builder; + LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, func, "entry"); + +@@ -86,11 +80,7 @@ add_printf_test(struct gallivm_state *gallivm) + + gallivm_verify_function(gallivm, func); + +-#if GALLIVM_USE_ORCJIT +- return func_name; +-#else + return func; +-#endif + } + + +@@ -99,23 +89,19 @@ static bool + test_printf(unsigned verbose, FILE *fp, + const struct printf_test_case *testcase) + { +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcThreadSafeContextRef context; + #else + LLVMContextRef context; + #endif + struct gallivm_state *gallivm; +-#if GALLIVM_USE_ORCJIT +- const char *test; +-#else + LLVMValueRef test; +-#endif + test_printf_t test_printf_func; + bool success = true; + +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + context = LLVMOrcCreateNewThreadSafeContext(); +-#if LLVM_VERSION_MAJOR >= 15 ++#if LLVM_VERSION_MAJOR == 15 + LLVMContextSetOpaquePointers(LLVMOrcThreadSafeContextGetContext(context), false); + #endif + #else +@@ -130,14 +116,14 @@ test_printf(unsigned verbose, FILE *fp, + + gallivm_compile_module(gallivm); + +- test_printf_func = (test_printf_t) gallivm_jit_function(gallivm, test); ++ test_printf_func = (test_printf_t) gallivm_jit_function(gallivm, test, "test_printf"); + + gallivm_free_ir(gallivm); + + test_printf_func(0); + + gallivm_destroy(gallivm); +-#if GALLIVM_USE_ORCJIT ++#if GALLIVM_USE_ORCJIT == 1 + LLVMOrcDisposeThreadSafeContext(context); + #else + LLVMContextDispose(context); +diff --git a/src/gallium/drivers/llvmpipe/lp_texture_handle.c b/src/gallium/drivers/llvmpipe/lp_texture_handle.c +index 1f45e4a..dc46dd6 100644 +--- a/src/gallium/drivers/llvmpipe/lp_texture_handle.c ++++ b/src/gallium/drivers/llvmpipe/lp_texture_handle.c +@@ -200,27 +200,17 @@ llvmpipe_sampler_matrix_destroy(struct llvmpipe_context *ctx) + util_dynarray_fini(&ctx->sampler_matrix.gallivms); + } + +-#if GALLIVM_USE_ORCJIT +-static void * +-compile_function(struct llvmpipe_context *ctx, struct gallivm_state *gallivm, LLVMValueRef function, const char *func_name, +- uint8_t cache_key[SHA1_DIGEST_LENGTH]) +-{ +-#else + static void * + compile_function(struct llvmpipe_context *ctx, struct gallivm_state *gallivm, LLVMValueRef function, ++ const char *func_name, bool needs_caching, + uint8_t cache_key[SHA1_DIGEST_LENGTH]) + { +-#endif + gallivm_verify_function(gallivm, function); + gallivm_compile_module(gallivm); + +-#if GALLIVM_USE_ORCJIT +- void *function_ptr = func_to_pointer(gallivm_jit_function(gallivm, func_name)); +-#else +- void *function_ptr = func_to_pointer(gallivm_jit_function(gallivm, function)); +-#endif ++ void *function_ptr = func_to_pointer(gallivm_jit_function(gallivm, function, func_name)); + +- if (!gallivm->cache->data_size) ++ if (needs_caching) + lp_disk_cache_insert_shader(llvmpipe_screen(ctx->pipe.screen), gallivm->cache, cache_key); + + gallivm_free_ir(gallivm); +@@ -329,6 +319,7 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st + + LLVMValueRef outdata[4] = { 0 }; + lp_build_img_op_soa(texture, lp_build_image_soa_dynamic_state(image_soa), gallivm, ¶ms, outdata); ++ bool needs_caching = !cached.data_size; + + for (uint32_t i = 1; i < 4; i++) + if (!outdata[i]) +@@ -344,11 +335,7 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st + + free(image_soa); + +-#if GALLIVM_USE_ORCJIT +- return compile_function(ctx, gallivm, function, "image", cache_key); +-#else +- return compile_function(ctx, gallivm, function, cache_key); +-#endif ++ return compile_function(ctx, gallivm, function, "image", needs_caching, cache_key); + } + + static void * +@@ -487,6 +474,7 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s + } else { + lp_build_sample_nop(gallivm, lp_build_texel_type(type, util_format_description(texture->format)), coords, texel_out); + } ++ bool needs_caching = !cached.data_size; + + LLVMBuildAggregateRet(gallivm->builder, texel_out, 4); + +@@ -495,11 +483,7 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s + + free(sampler_soa); + +-#if GALLIVM_USE_ORCJIT +- return compile_function(ctx, gallivm, function, "sample", cache_key); +-#else +- return compile_function(ctx, gallivm, function, cache_key); +-#endif ++ return compile_function(ctx, gallivm, function,"sample", needs_caching, cache_key); + } + + static void * +@@ -567,6 +551,7 @@ compile_size_function(struct llvmpipe_context *ctx, struct lp_static_texture_sta + LLVMValueRef out_sizes[4] = { 0 }; + params.sizes_out = out_sizes; + lp_build_size_query_soa(gallivm, texture, lp_build_sampler_soa_dynamic_state(sampler_soa), ¶ms); ++ bool needs_caching = !cached.data_size; + + for (uint32_t i = 0; i < 4; i++) + if (!out_sizes[i]) +@@ -579,11 +564,7 @@ compile_size_function(struct llvmpipe_context *ctx, struct lp_static_texture_sta + + free(sampler_soa); + +-#if GALLIVM_USE_ORCJIT +- return compile_function(ctx, gallivm, function, "size", cache_key); +-#else +- return compile_function(ctx, gallivm, function, cache_key); +-#endif ++ return compile_function(ctx, gallivm, function, "size", needs_caching, cache_key); + } + + static void +diff --git a/src/util/detect_arch.h b/src/util/detect_arch.h +index 34b6507..75fa7ed 100644 +--- a/src/util/detect_arch.h ++++ b/src/util/detect_arch.h +@@ -94,7 +94,7 @@ + #endif + + #if defined(__mips__) +-#define DETECT_ARCH_MIPS 1 ++#define DETECT_ARCH_HPPA 1 + #endif + + #if defined(__riscv) +@@ -145,7 +145,7 @@ + #endif + + #ifndef DETECT_ARCH_MIPS +-#define DETECT_ARCH_MIPS 0 ++#define DETECT_ARCH_HPPA 0 + #endif + + #ifndef DETECT_ARCH_RISCV diff --git a/0002-llvmpipe-support-loongarch64-orcjit.patch b/0002-llvmpipe-support-loongarch64-orcjit.patch new file mode 100644 index 0000000000000000000000000000000000000000..0aa0c5eb76138aaaf06069b31a6cbf72e7d3e971 --- /dev/null +++ b/0002-llvmpipe-support-loongarch64-orcjit.patch @@ -0,0 +1,35 @@ +From 486ff712babd672bdaa8830e250653f12879f1da Mon Sep 17 00:00:00 2001 +From: zhaojiale +Date: Sun, 12 May 2024 10:17:10 +0800 +Subject: [PATCH] llvmpipe: support loongarch64 orcjit + +Signed-off-by: zhaojiale +--- + src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp +index 797c9e1..17767f4 100644 +--- a/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp ++++ b/src/gallium/auxiliary/gallivm/lp_bld_init_orc.cpp +@@ -52,7 +52,7 @@ + /* conflict with ObjectLinkingLayer.h */ + #include "util/u_memory.h" + +-#if DETECT_ARCH_RISCV64 == 1 || DETECT_ARCH_RISCV32 == 1 || (defined(_WIN32) && LLVM_VERSION_MAJOR >= 15) ++#if DETECT_ARCH_RISCV64 == 1 || DETECT_ARCH_RISCV32 == 1 || DETECT_ARCH_LOONGARCH64 == 1 || (defined(_WIN32) && LLVM_VERSION_MAJOR >= 15) + /* use ObjectLinkingLayer (JITLINK backend) */ + #define USE_JITLINK + #endif +@@ -570,7 +570,7 @@ llvm::orc::JITTargetMachineBuilder LPJit::create_jtdb() { + + std::vector MAttrs; + +-#if LLVM_VERSION_MAJOR >= 4 && (DETECT_ARCH_X86 == 1 || DETECT_ARCH_X86_64 == 1 || DETECT_ARCH_ARM == 1) ++#if LLVM_VERSION_MAJOR >= 4 && (DETECT_ARCH_X86 == 1 || DETECT_ARCH_X86_64 == 1 || DETECT_ARCH_ARM == 1 || DETECT_ARCH_LOONGARCH64 == 1) + /* llvm-3.3+ implements sys::getHostCPUFeatures for Arm + * and llvm-3.7+ for x86, which allows us to enable/disable + * code generation based on the results of cpuid on these +-- +2.43.0 + diff --git a/mesa.spec b/mesa.spec index 4deac08ac4957d65b935d759d3523d211b81c29d..4e6fdb648c84beaf0b81abc2c111d2d55ad04bca 100644 --- a/mesa.spec +++ b/mesa.spec @@ -1,4 +1,4 @@ -%define anolis_release 2 +%define anolis_release 3 %global with_hardware 1 %global with_vulkan_hw 1 @@ -47,6 +47,10 @@ Source1: Mesa-MLAA-License-Clarification-Email.txt Patch10: gnome-shell-glthread-disable.patch Patch11: 0001-zink-initialize-drm_fd-to-1.patch +Patch12: 0001-26018_upstream_orcjit.patch +Patch13: 0002-26018_upstream_orcjit_patch_update.patch +Patch14: 0001-add_loongarch64_basic_support.patch +Patch15: 0002-llvmpipe-support-loongarch64-orcjit.patch BuildRequires: meson BuildRequires: gcc @@ -363,6 +367,7 @@ export RUSTFLAGS="%build_rustflags" -Dglx=dri \ -Degl=enabled \ -Dglvnd=true \ + -Dllvm-orcjit=true \ %if 0%{?with_intel_clc} -Dintel-clc=enabled \ %endif @@ -634,6 +639,9 @@ popd %endif %changelog +* Sun May 12 2024 Jiale Zhao - 23.3.0-3 +- Add upstream orcjit patch and support loongarch64 orcjit + * Mon Mar 25 2024 Bo Ren - 23.3.0-2 - Rebuild with python3.11