From: Tom Stellard <[email protected]> R600_DEBUG=gisel will tell LLVM to use GlobalISel rather than SelectionDAG for instruction selection.
v2: mareko: move the helper to src/amd/common Signed-off-by: Marek Olšák <[email protected]> --- src/amd/common/ac_llvm_helper.cpp | 7 +++++++ src/amd/common/ac_llvm_util.c | 11 +++++++++-- src/amd/common/ac_llvm_util.h | 2 ++ src/gallium/drivers/radeonsi/si_pipe.c | 3 +++ src/gallium/drivers/radeonsi/si_pipe.h | 1 + 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/amd/common/ac_llvm_helper.cpp b/src/amd/common/ac_llvm_helper.cpp index e0943135fad..a4b2fde786a 100644 --- a/src/amd/common/ac_llvm_helper.cpp +++ b/src/amd/common/ac_llvm_helper.cpp @@ -164,10 +164,17 @@ bool ac_compile_module_to_binary(struct ac_compiler_passes *p, LLVMModuleRef mod if (!success) fprintf(stderr, "amd: cannot read an ELF shader binary\n"); return success; } void ac_llvm_add_barrier_noop_pass(LLVMPassManagerRef passmgr) { llvm::unwrap(passmgr)->add(llvm::createBarrierNoopPass()); } + +void ac_enable_global_isel(LLVMTargetMachineRef tm) +{ +#if HAVE_LLVM >= 0x0700 + reinterpret_cast<llvm::TargetMachine*>(tm)->setGlobalISel(true); +#endif +} diff --git a/src/amd/common/ac_llvm_util.c b/src/amd/common/ac_llvm_util.c index b6960f7382d..10e1ca99d41 100644 --- a/src/amd/common/ac_llvm_util.c +++ b/src/amd/common/ac_llvm_util.c @@ -27,20 +27,21 @@ #include "ac_llvm_build.h" #include "util/bitscan.h" #include <llvm-c/Core.h> #include <llvm-c/Support.h> #include <llvm-c/Transforms/IPO.h> #include <llvm-c/Transforms/Scalar.h> #if HAVE_LLVM >= 0x0700 #include <llvm-c/Transforms/Utils.h> #endif #include "c11/threads.h" +#include "gallivm/lp_bld_misc.h" #include "util/u_math.h" #include <assert.h> #include <stdio.h> #include <string.h> static void ac_init_llvm_target() { LLVMInitializeAMDGPUTargetInfo(); LLVMInitializeAMDGPUTarget(); @@ -48,23 +49,27 @@ static void ac_init_llvm_target() LLVMInitializeAMDGPUAsmPrinter(); /* For inline assembly. */ LLVMInitializeAMDGPUAsmParser(); /* Workaround for bug in llvm 4.0 that causes image intrinsics * to disappear. * https://reviews.llvm.org/D26348 * * "mesa" is the prefix for error messages. + * + * -global-isel-abort=2 is a no-op unless global isel has been enabled. + * This option tells the backend to fall-back to SelectionDAG and print + * a diagnostic message if global isel fails. */ - const char *argv[2] = { "mesa", "-simplifycfg-sink-common=false" }; - LLVMParseCommandLineOptions(2, argv, NULL); + const char *argv[3] = { "mesa", "-simplifycfg-sink-common=false", "-global-isel-abort=2" }; + LLVMParseCommandLineOptions(3, argv, NULL); } static once_flag ac_init_llvm_target_once_flag = ONCE_FLAG_INIT; void ac_init_llvm_once(void) { call_once(&ac_init_llvm_target_once_flag, ac_init_llvm_target); } static LLVMTargetRef ac_get_llvm_target(const char *triple) @@ -158,20 +163,22 @@ static LLVMTargetMachineRef ac_create_target_machine(enum radeon_family family, target, triple, ac_get_llvm_processor_name(family), features, level, LLVMRelocDefault, LLVMCodeModelDefault); if (out_triple) *out_triple = triple; + if (tm_options & AC_TM_ENABLE_GLOBAL_ISEL) + ac_enable_global_isel(tm); return tm; } static LLVMPassManagerRef ac_create_passmgr(LLVMTargetLibraryInfoRef target_library_info, bool check_ir) { LLVMPassManagerRef passmgr = LLVMCreatePassManager(); if (!passmgr) return NULL; diff --git a/src/amd/common/ac_llvm_util.h b/src/amd/common/ac_llvm_util.h index c0e759b8836..a3adf4fe458 100644 --- a/src/amd/common/ac_llvm_util.h +++ b/src/amd/common/ac_llvm_util.h @@ -57,20 +57,21 @@ enum ac_func_attr { }; enum ac_target_machine_options { AC_TM_SUPPORTS_SPILL = (1 << 0), AC_TM_SISCHED = (1 << 1), AC_TM_FORCE_ENABLE_XNACK = (1 << 2), AC_TM_FORCE_DISABLE_XNACK = (1 << 3), AC_TM_PROMOTE_ALLOCA_TO_SCRATCH = (1 << 4), AC_TM_CHECK_IR = (1 << 5), AC_TM_CREATE_LOW_OPT = (1 << 6), + AC_TM_ENABLE_GLOBAL_ISEL = (1 << 7), }; enum ac_float_mode { AC_FLOAT_MODE_DEFAULT, AC_FLOAT_MODE_NO_SIGNED_ZEROS_FP_MATH, AC_FLOAT_MODE_UNSAFE_FP_MATH, }; /* Per-thread persistent LLVM objects. */ struct ac_llvm_compiler { @@ -136,16 +137,17 @@ bool ac_init_llvm_compiler(struct ac_llvm_compiler *compiler, bool okay_to_leak_target_library_info, enum radeon_family family, enum ac_target_machine_options tm_options); void ac_destroy_llvm_compiler(struct ac_llvm_compiler *compiler); struct ac_compiler_passes *ac_create_llvm_passes(LLVMTargetMachineRef tm); void ac_destroy_llvm_passes(struct ac_compiler_passes *p); bool ac_compile_module_to_binary(struct ac_compiler_passes *p, LLVMModuleRef module, struct ac_shader_binary *binary); void ac_llvm_add_barrier_noop_pass(LLVMPassManagerRef passmgr); +void ac_enable_global_isel(LLVMTargetMachineRef tm); #ifdef __cplusplus } #endif #endif /* AC_LLVM_UTIL_H */ diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 4f00eb5c2e2..cc05d2f8de3 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -50,20 +50,21 @@ static const struct debug_named_value debug_options[] = { { "tes", DBG(TES), "Print tessellation evaluation shaders" }, { "cs", DBG(CS), "Print compute shaders" }, { "noir", DBG(NO_IR), "Don't print the LLVM IR"}, { "notgsi", DBG(NO_TGSI), "Don't print the TGSI"}, { "noasm", DBG(NO_ASM), "Don't print disassembled shaders"}, { "preoptir", DBG(PREOPT_IR), "Print the LLVM IR before initial optimizations" }, /* Shader compiler options the shader cache should be aware of: */ { "unsafemath", DBG(UNSAFE_MATH), "Enable unsafe math shader optimizations" }, { "sisched", DBG(SI_SCHED), "Enable LLVM SI Machine Instruction Scheduler." }, + { "gisel", DBG(GISEL), "Enable LLVM global instruction selector." }, /* Shader compiler options (with no effect on the shader cache): */ { "checkir", DBG(CHECK_IR), "Enable additional sanity checks on shader IR" }, { "nir", DBG(NIR), "Enable experimental NIR shaders" }, { "mono", DBG(MONOLITHIC_SHADERS), "Use old-style monolithic shaders compiled on demand" }, { "nooptvariant", DBG(NO_OPT_VARIANT), "Disable compiling optimized shader variants." }, /* Information logging options: */ { "info", DBG(INFO), "Print driver information" }, { "tex", DBG(TEX), "Print texture info" }, @@ -107,20 +108,21 @@ static const struct debug_named_value debug_options[] = { static void si_init_compiler(struct si_screen *sscreen, struct ac_llvm_compiler *compiler) { /* Only create the less-optimizing version of the compiler on APUs * predating Ryzen (Raven). */ bool create_low_opt_compiler = !sscreen->info.has_dedicated_vram && sscreen->info.chip_class <= VI; enum ac_target_machine_options tm_options = (sscreen->debug_flags & DBG(SI_SCHED) ? AC_TM_SISCHED : 0) | + (sscreen->debug_flags & DBG(GISEL) ? AC_TM_ENABLE_GLOBAL_ISEL : 0) | (sscreen->info.chip_class >= GFX9 ? AC_TM_FORCE_ENABLE_XNACK : 0) | (sscreen->info.chip_class < GFX9 ? AC_TM_FORCE_DISABLE_XNACK : 0) | (!sscreen->llvm_has_working_vgpr_indexing ? AC_TM_PROMOTE_ALLOCA_TO_SCRATCH : 0) | (sscreen->debug_flags & DBG(CHECK_IR) ? AC_TM_CHECK_IR : 0) | (create_low_opt_compiler ? AC_TM_CREATE_LOW_OPT : 0); ac_init_llvm_once(); ac_init_llvm_compiler(compiler, true, sscreen->info.family, tm_options); compiler->passes = ac_create_llvm_passes(compiler->tm); @@ -759,20 +761,21 @@ static void si_disk_cache_create(struct si_screen *sscreen) if (disk_cache_get_function_timestamp(LLVMInitializeAMDGPUTargetInfo, &llvm_timestamp)) { res = asprintf(×tamp_str, "%u_%u", mesa_timestamp, llvm_timestamp); } if (res != -1) { /* These flags affect shader compilation. */ #define ALL_FLAGS (DBG(FS_CORRECT_DERIVS_AFTER_KILL) | \ DBG(SI_SCHED) | \ + DBG(GISEL) | \ DBG(UNSAFE_MATH) | \ DBG(NIR)) uint64_t shader_debug_flags = sscreen->debug_flags & ALL_FLAGS; /* Add the high bits of 32-bit addresses, which affects * how 32-bit addresses are expanded to 64 bits. */ STATIC_ASSERT(ALL_FLAGS <= UINT_MAX); shader_debug_flags |= (uint64_t)sscreen->info.address32_hi << 32; diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 301c168c952..4a3e8bba18e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -114,20 +114,21 @@ enum { DBG_CS = PIPE_SHADER_COMPUTE, DBG_NO_IR, DBG_NO_TGSI, DBG_NO_ASM, DBG_PREOPT_IR, /* Shader compiler options the shader cache should be aware of: */ DBG_FS_CORRECT_DERIVS_AFTER_KILL, DBG_UNSAFE_MATH, DBG_SI_SCHED, + DBG_GISEL, /* Shader compiler options (with no effect on the shader cache): */ DBG_CHECK_IR, DBG_NIR, DBG_MONOLITHIC_SHADERS, DBG_NO_OPT_VARIANT, /* Information logging options: */ DBG_INFO, DBG_TEX, -- 2.17.1 _______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
