gallium: Require LLVM >= 3.6

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
Adam Jackson 2019-09-06 09:50:16 +02:00 committed by Adam Jackson
parent 3c553d9cff
commit 9abf7d5755
6 changed files with 85 additions and 266 deletions

View File

@ -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')

View File

@ -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',

View File

@ -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));

View File

@ -49,19 +49,6 @@
#include <llvm-c/Transforms/Coroutines.h>
#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);

View File

@ -52,9 +52,7 @@
#include <llvm/Config/llvm-config.h>
#include <llvm-c/Core.h>
#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6)
#include <llvm-c/Support.h>
#endif
#include <llvm-c/ExecutionEngine.h>
#include <llvm/Target/TargetOptions.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
@ -64,11 +62,7 @@
#else
#include <llvm/Target/TargetLibraryInfo.h>
#endif
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 6
#include <llvm/ExecutionEngine/JITMemoryManager.h>
#else
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#endif
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/PrettyStackTrace.h>
@ -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<Module>(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<std::string, 16> MAttrs;
@ -585,28 +484,12 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
}
ShaderMemoryManager *MM = NULL;
if (useMCJIT) {
BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(CMM);
MM = new ShaderMemoryManager(JMM);
*OutCode = MM->getGeneratedCode();
BaseMemoryManager* JMM = reinterpret_cast<BaseMemoryManager*>(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<RTDyldMemoryManager>(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<BaseMemoryManager*>(CMM);
MM = new ShaderMemoryManager(JMM);
*OutCode = MM->getGeneratedCode();
builder.setJITMemoryManager(MM);
#else
assert(0);
#endif
}
builder.setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(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<LLVMMCJITMemoryManagerRef>(mm);
}

View File

@ -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