From 9abf7d575597e9dc534cccbb973f9e98338f48fe Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 6 Sep 2019 09:50:16 +0200 Subject: [PATCH] gallium: Require LLVM >= 3.6 Reviewed-by: Timothy Arceri Reviewed-by: Jose Fonseca --- meson.build | 2 +- scons/llvm.py | 17 +- src/gallium/auxiliary/gallivm/lp_bld_arit.c | 2 +- src/gallium/auxiliary/gallivm/lp_bld_init.c | 178 +++++++----------- src/gallium/auxiliary/gallivm/lp_bld_misc.cpp | 151 ++------------- src/gallium/auxiliary/gallivm/lp_bld_misc.h | 1 - 6 files changed, 85 insertions(+), 266 deletions(-) diff --git a/meson.build b/meson.build index f6017de7b99..b856f3acaec 100644 --- a/meson.build +++ b/meson.build @@ -1264,7 +1264,7 @@ elif with_gallium_swr elif with_gallium_opencl or with_gallium_r600 _llvm_version = '>= 3.9.0' else - _llvm_version = '>= 3.5.0' + _llvm_version = '>= 3.6.0' endif _shared_llvm = get_option('shared-llvm') diff --git a/scons/llvm.py b/scons/llvm.py index 49e513ade18..adb93e7f41e 100644 --- a/scons/llvm.py +++ b/scons/llvm.py @@ -37,7 +37,7 @@ import SCons.Errors import SCons.Util -required_llvm_version = '3.5' +required_llvm_version = '3.6' def generate(env): @@ -171,7 +171,7 @@ def generate(env): 'LLVMRuntimeDyld', 'LLVMObject', 'LLVMMCParser', 'LLVMBitReader', 'LLVMMC', 'LLVMCore', 'LLVMSupport' ]) - elif llvm_version >= distutils.version.LooseVersion('3.6'): + else: env.Prepend(LIBS = [ 'LLVMBitWriter', 'LLVMX86Disassembler', 'LLVMX86AsmParser', 'LLVMX86CodeGen', 'LLVMSelectionDAG', 'LLVMAsmPrinter', @@ -183,19 +183,6 @@ def generate(env): 'LLVMRuntimeDyld', 'LLVMObject', 'LLVMMCParser', 'LLVMBitReader', 'LLVMMC', 'LLVMCore', 'LLVMSupport' ]) - else: - env.Prepend(LIBS = [ - 'LLVMMCDisassembler', - 'LLVMBitWriter', 'LLVMMCJIT', 'LLVMRuntimeDyld', - 'LLVMX86Disassembler', 'LLVMX86AsmParser', 'LLVMX86CodeGen', - 'LLVMSelectionDAG', 'LLVMAsmPrinter', 'LLVMX86Desc', - 'LLVMObject', 'LLVMMCParser', 'LLVMBitReader', 'LLVMX86Info', - 'LLVMX86AsmPrinter', 'LLVMX86Utils', 'LLVMJIT', - 'LLVMExecutionEngine', 'LLVMCodeGen', 'LLVMScalarOpts', - 'LLVMInstCombine', 'LLVMTransformUtils', 'LLVMipa', - 'LLVMAnalysis', 'LLVMTarget', 'LLVMMC', 'LLVMCore', - 'LLVMSupport' - ]) env.Append(LIBS = [ 'imagehlp', 'psapi', diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c index 1cb81f258aa..9bf74f0a15b 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c @@ -1832,7 +1832,7 @@ lp_build_abs(struct lp_build_context *bld, return a; if(type.floating) { - if ((LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 6)) && (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 9)) { + if (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 9) { /* Workaround llvm.org/PR27332 */ LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->gallivm, type); unsigned long long absMask = ~(1ULL << (type.width - 1)); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c index 52e1ace9e0d..23d330cff54 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c @@ -49,19 +49,6 @@ #include #endif -/* Only MCJIT is available as of LLVM SVN r216982 */ -#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6) -# define USE_MCJIT 1 -#elif defined(PIPE_ARCH_PPC_64) || defined(PIPE_ARCH_S390) || defined(PIPE_ARCH_ARM) || defined(PIPE_ARCH_AARCH64) -# define USE_MCJIT 1 -#endif - -#if defined(USE_MCJIT) -static const bool use_mcjit = USE_MCJIT; -#else -static bool use_mcjit = FALSE; -#endif - unsigned gallivm_perf = 0; static const struct debug_named_value lp_bld_perf_flags[] = { @@ -224,12 +211,8 @@ gallivm_free_ir(struct gallivm_state *gallivm) FREE(gallivm->module_name); - if (!use_mcjit) { - /* Don't free the TargetData, it's owned by the exec engine */ - } else { - if (gallivm->target) { - LLVMDisposeTargetData(gallivm->target); - } + if (gallivm->target) { + LLVMDisposeTargetData(gallivm->target); } if (gallivm->builder) @@ -283,7 +266,6 @@ init_gallivm_engine(struct gallivm_state *gallivm) gallivm->module, gallivm->memorymgr, (unsigned) optlevel, - use_mcjit, &error); if (ret) { _debug_printf("%s\n", error); @@ -292,31 +274,25 @@ init_gallivm_engine(struct gallivm_state *gallivm) } } - if (!use_mcjit) { - gallivm->target = LLVMGetExecutionEngineTargetData(gallivm->engine); - if (!gallivm->target) - goto fail; - } else { - if (0) { - /* - * Dump the data layout strings. - */ + if (0) { + /* + * Dump the data layout strings. + */ - LLVMTargetDataRef target = LLVMGetExecutionEngineTargetData(gallivm->engine); - char *data_layout; - char *engine_data_layout; + LLVMTargetDataRef target = LLVMGetExecutionEngineTargetData(gallivm->engine); + char *data_layout; + char *engine_data_layout; - data_layout = LLVMCopyStringRepOfTargetData(gallivm->target); - engine_data_layout = LLVMCopyStringRepOfTargetData(target); + data_layout = LLVMCopyStringRepOfTargetData(gallivm->target); + engine_data_layout = LLVMCopyStringRepOfTargetData(target); - if (1) { - debug_printf("module target data = %s\n", data_layout); - debug_printf("engine target data = %s\n", engine_data_layout); - } + if (1) { + debug_printf("module target data = %s\n", data_layout); + debug_printf("engine target data = %s\n", engine_data_layout); + } - free(data_layout); - free(engine_data_layout); - } + free(data_layout); + free(engine_data_layout); } return TRUE; @@ -371,44 +347,39 @@ init_gallivm_state(struct gallivm_state *gallivm, const char *name, * complete when MC-JIT is created. So defer the MC-JIT engine creation for * now. */ - if (!use_mcjit) { - if (!init_gallivm_engine(gallivm)) { - goto fail; - } - } else { - /* - * MC-JIT engine compiles the module immediately on creation, so we can't - * obtain the target data from it. Instead we create a target data layout - * from a string. - * - * The produced layout strings are not precisely the same, but should make - * no difference for the kind of optimization passes we run. - * - * For reference this is the layout string on x64: - * - * e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64 - * - * See also: - * - http://llvm.org/docs/LangRef.html#datalayout - */ - { - const unsigned pointer_size = 8 * sizeof(void *); - char layout[512]; - snprintf(layout, sizeof layout, "%c-p:%u:%u:%u-i64:64:64-a0:0:%u-s0:%u:%u", + /* + * MC-JIT engine compiles the module immediately on creation, so we can't + * obtain the target data from it. Instead we create a target data layout + * from a string. + * + * The produced layout strings are not precisely the same, but should make + * no difference for the kind of optimization passes we run. + * + * For reference this is the layout string on x64: + * + * e-p:64:64:64-S128-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f16:16:16-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64 + * + * See also: + * - http://llvm.org/docs/LangRef.html#datalayout + */ + + { + const unsigned pointer_size = 8 * sizeof(void *); + char layout[512]; + snprintf(layout, sizeof layout, "%c-p:%u:%u:%u-i64:64:64-a0:0:%u-s0:%u:%u", #ifdef PIPE_ARCH_LITTLE_ENDIAN - 'e', // little endian + 'e', // little endian #else - 'E', // big endian + 'E', // big endian #endif - pointer_size, pointer_size, pointer_size, // pointer size, abi alignment, preferred alignment - pointer_size, // aggregate preferred alignment - pointer_size, pointer_size); // stack objects abi alignment, preferred alignment + pointer_size, pointer_size, pointer_size, // pointer size, abi alignment, preferred alignment + pointer_size, // aggregate preferred alignment + pointer_size, pointer_size); // stack objects abi alignment, preferred alignment - gallivm->target = LLVMCreateTargetData(layout); - if (!gallivm->target) { - return FALSE; - } + gallivm->target = LLVMCreateTargetData(layout); + if (!gallivm->target) { + return FALSE; } } @@ -435,17 +406,7 @@ lp_build_init(void) * component is linked at buildtime, which is sufficient for its static * constructors to be called at load time. */ -#if defined(USE_MCJIT) -# if USE_MCJIT - LLVMLinkInMCJIT(); -# else - LLVMLinkInJIT(); -# endif -#else - use_mcjit = debug_get_bool_option("GALLIVM_MCJIT", FALSE); - LLVMLinkInJIT(); LLVMLinkInMCJIT(); -#endif #ifdef DEBUG gallivm_debug = debug_get_option_gallivm_debug(); @@ -505,11 +466,6 @@ lp_build_init(void) util_cpu_caps.has_f16c = 0; util_cpu_caps.has_fma = 0; } - if (!use_mcjit) { - /* AVX2 support has only been tested with LLVM 3.4, and it requires - * MCJIT. */ - util_cpu_caps.has_avx2 = 0; - } #ifdef PIPE_ARCH_PPC_64 /* Set the NJ bit in VSCR to 0 so denormalized values are handled as @@ -666,29 +622,27 @@ gallivm_compile_module(struct gallivm_state *gallivm) gallivm->module_name, time_msec); } - if (use_mcjit) { - /* Setting the module's DataLayout to an empty string will cause the - * ExecutionEngine to copy to the DataLayout string from its target - * machine to the module. As of LLVM 3.8 the module and the execution - * engine are required to have the same DataLayout. - * - * We must make sure we do this after running the optimization passes, - * because those passes need a correct datalayout string. For example, - * if those optimization passes see an empty datalayout, they will assume - * this is a little endian target and will do optimizations that break big - * endian machines. - * - * TODO: This is just a temporary work-around. The correct solution is - * for gallivm_init_state() to create a TargetMachine and pull the - * DataLayout from there. Currently, the TargetMachine used by llvmpipe - * is being implicitly created by the EngineBuilder in - * lp_build_create_jit_compiler_for_module() - */ - LLVMSetDataLayout(gallivm->module, ""); - assert(!gallivm->engine); - if (!init_gallivm_engine(gallivm)) { - assert(0); - } + /* Setting the module's DataLayout to an empty string will cause the + * ExecutionEngine to copy to the DataLayout string from its target machine + * to the module. As of LLVM 3.8 the module and the execution engine are + * required to have the same DataLayout. + * + * We must make sure we do this after running the optimization passes, + * because those passes need a correct datalayout string. For example, if + * those optimization passes see an empty datalayout, they will assume this + * is a little endian target and will do optimizations that break big endian + * machines. + * + * TODO: This is just a temporary work-around. The correct solution is for + * gallivm_init_state() to create a TargetMachine and pull the DataLayout + * from there. Currently, the TargetMachine used by llvmpipe is being + * implicitly created by the EngineBuilder in + * lp_build_create_jit_compiler_for_module() + */ + LLVMSetDataLayout(gallivm->module, ""); + assert(!gallivm->engine); + if (!init_gallivm_engine(gallivm)) { + assert(0); } assert(gallivm->engine); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index b3ec969ce3e..23bf1cf7042 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -52,9 +52,7 @@ #include #include -#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6) #include -#endif #include #include #include @@ -64,11 +62,7 @@ #else #include #endif -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 6 -#include -#else #include -#endif #include #include #include @@ -126,7 +120,7 @@ static void init_native_targets() llvm::InitializeNativeTargetAsmPrinter(); llvm::InitializeNativeTargetDisassembler(); -#if DEBUG && (LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6)) +#if DEBUG { char *env_llc_options = getenv("GALLIVM_LLC_OPTIONS"); if (env_llc_options) { @@ -188,11 +182,7 @@ gallivm_dispose_target_library_info(LLVMTargetLibraryInfoRef library_info) } -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 6 -typedef llvm::JITMemoryManager BaseMemoryManager; -#else typedef llvm::RTDyldMemoryManager BaseMemoryManager; -#endif /* @@ -206,76 +196,6 @@ class DelegatingJITMemoryManager : public BaseMemoryManager { virtual BaseMemoryManager *mgr() const = 0; public: -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 6 - /* - * From JITMemoryManager - */ - virtual void setMemoryWritable() { - mgr()->setMemoryWritable(); - } - virtual void setMemoryExecutable() { - mgr()->setMemoryExecutable(); - } - virtual void setPoisonMemory(bool poison) { - mgr()->setPoisonMemory(poison); - } - virtual void AllocateGOT() { - mgr()->AllocateGOT(); - /* - * isManagingGOT() is not virtual in base class so we can't delegate. - * Instead we mirror the value of HasGOT in our instance. - */ - HasGOT = mgr()->isManagingGOT(); - } - virtual uint8_t *getGOTBase() const { - return mgr()->getGOTBase(); - } - virtual uint8_t *startFunctionBody(const llvm::Function *F, - uintptr_t &ActualSize) { - return mgr()->startFunctionBody(F, ActualSize); - } - virtual uint8_t *allocateStub(const llvm::GlobalValue *F, - unsigned StubSize, - unsigned Alignment) { - return mgr()->allocateStub(F, StubSize, Alignment); - } - virtual void endFunctionBody(const llvm::Function *F, - uint8_t *FunctionStart, - uint8_t *FunctionEnd) { - mgr()->endFunctionBody(F, FunctionStart, FunctionEnd); - } - virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) { - return mgr()->allocateSpace(Size, Alignment); - } - virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) { - return mgr()->allocateGlobal(Size, Alignment); - } - virtual void deallocateFunctionBody(void *Body) { - mgr()->deallocateFunctionBody(Body); - } - virtual bool CheckInvariants(std::string &s) { - return mgr()->CheckInvariants(s); - } - virtual size_t GetDefaultCodeSlabSize() { - return mgr()->GetDefaultCodeSlabSize(); - } - virtual size_t GetDefaultDataSlabSize() { - return mgr()->GetDefaultDataSlabSize(); - } - virtual size_t GetDefaultStubSlabSize() { - return mgr()->GetDefaultStubSlabSize(); - } - virtual unsigned GetNumCodeSlabs() { - return mgr()->GetNumCodeSlabs(); - } - virtual unsigned GetNumDataSlabs() { - return mgr()->GetNumDataSlabs(); - } - virtual unsigned GetNumStubSlabs() { - return mgr()->GetNumStubSlabs(); - } -#endif - /* * From RTDyldMemoryManager */ @@ -342,17 +262,6 @@ class ShaderMemoryManager : public DelegatingJITMemoryManager { } ~GeneratedCode() { - /* - * Deallocate things as previously requested and - * free shared manager when no longer used. - */ -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 6 - Vec::iterator i; - - assert(TheMM); - for ( i = FunctionBody.begin(); i != FunctionBody.end(); ++i ) - TheMM->deallocateFunctionBody(*i); -#endif } }; @@ -408,17 +317,12 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, LLVMMCJITMemoryManagerRef CMM, unsigned OptLevel, - int useMCJIT, char **OutError) { using namespace llvm; std::string Error; -#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6) EngineBuilder builder(std::unique_ptr(unwrap(M))); -#else - EngineBuilder builder(unwrap(M)); -#endif /** * LLVM 3.1+ haven't more "extern unsigned llvm::StackAlignmentOverride" and @@ -445,25 +349,20 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT, .setTargetOptions(options) .setOptLevel((CodeGenOpt::Level)OptLevel); - if (useMCJIT) { -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 6 - builder.setUseMCJIT(true); -#endif #ifdef _WIN32 - /* - * MCJIT works on Windows, but currently 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. - */ + /* + * MCJIT works on Windows, but currently 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 - LLVMSetTarget(M, "x86_64-pc-win32-elf"); + LLVMSetTarget(M, "x86_64-pc-win32-elf"); # else - LLVMSetTarget(M, "i686-pc-win32-elf"); + LLVMSetTarget(M, "i686-pc-win32-elf"); # endif #endif - } llvm::SmallVector MAttrs; @@ -585,28 +484,12 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT, } ShaderMemoryManager *MM = NULL; - if (useMCJIT) { - BaseMemoryManager* JMM = reinterpret_cast(CMM); - MM = new ShaderMemoryManager(JMM); - *OutCode = MM->getGeneratedCode(); - -#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6) - builder.setMCJITMemoryManager(std::unique_ptr(MM)); - MM = NULL; // ownership taken by std::unique_ptr -#else - builder.setMCJITMemoryManager(MM); -#endif - } else { -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 6 - BaseMemoryManager* JMM = reinterpret_cast(CMM); - MM = new ShaderMemoryManager(JMM); - *OutCode = MM->getGeneratedCode(); + BaseMemoryManager* JMM = reinterpret_cast(CMM); + MM = new ShaderMemoryManager(JMM); + *OutCode = MM->getGeneratedCode(); - builder.setJITMemoryManager(MM); -#else - assert(0); -#endif - } + builder.setMCJITMemoryManager(std::unique_ptr(MM)); + MM = NULL; // ownership taken by std::unique_ptr ExecutionEngine *JIT; @@ -639,11 +522,7 @@ LLVMMCJITMemoryManagerRef lp_get_default_memory_manager() { BaseMemoryManager *mm; -#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 6 - mm = llvm::JITMemoryManager::CreateDefaultMemManager(); -#else mm = new llvm::SectionMemoryManager(); -#endif return reinterpret_cast(mm); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.h b/src/gallium/auxiliary/gallivm/lp_bld_misc.h index 5a19ba1bd2d..eb1eac045fd 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.h @@ -59,7 +59,6 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT, LLVMModuleRef M, LLVMMCJITMemoryManagerRef MM, unsigned OptLevel, - int useMCJIT, char **OutError); extern void -- 2.30.2