[Mesa-dev] [PATCH] radeonsi: Add debug option to enable LLVM GlobalISel (v2)

Marek Olšák maraeo at gmail.com
Fri Jul 20 03:18:17 UTC 2018


From: Tom Stellard <tstellar at redhat.com>

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 <marek.olsak at amd.com>
---
 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(&timestamp_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



More information about the mesa-dev mailing list