[Mesa-dev] [PATCH 1/2] ac: run LLVM optimization passes only on the final function after inlining

Marek Olšák maraeo at gmail.com
Thu Jul 5 21:02:52 UTC 2018


From: Marek Olšák <marek.olsak at amd.com>

---
 src/amd/common/ac_llvm_helper.cpp | 6 ++++++
 src/amd/common/ac_llvm_util.c     | 7 +++++++
 src/amd/common/ac_llvm_util.h     | 1 +
 3 files changed, 14 insertions(+)

diff --git a/src/amd/common/ac_llvm_helper.cpp b/src/amd/common/ac_llvm_helper.cpp
index 4348ebd36ee..e0943135fad 100644
--- a/src/amd/common/ac_llvm_helper.cpp
+++ b/src/amd/common/ac_llvm_helper.cpp
@@ -29,20 +29,21 @@
 #pragma push_macro("DEBUG")
 #undef DEBUG
 
 #include "ac_binary.h"
 #include "ac_llvm_util.h"
 
 #include <llvm-c/Core.h>
 #include <llvm/Target/TargetMachine.h>
 #include <llvm/IR/IRBuilder.h>
 #include <llvm/Analysis/TargetLibraryInfo.h>
+#include <llvm/Transforms/IPO.h>
 
 #include <llvm/IR/LegacyPassManager.h>
 #if HAVE_LLVM < 0x0700
 #include "llvm/Support/raw_ostream.h"
 #endif
 
 void ac_add_attr_dereferenceable(LLVMValueRef val, uint64_t bytes)
 {
    llvm::Argument *A = llvm::unwrap<llvm::Argument>(val);
    A->addAttr(llvm::Attribute::getWithDereferenceableBytes(A->getContext(), bytes));
@@ -158,10 +159,15 @@ bool ac_compile_module_to_binary(struct ac_compiler_passes *p, LLVMModuleRef mod
 	p->passmgr.run(*llvm::unwrap(module));
 
 	llvm::StringRef data = p->ostream.str();
 	bool success = ac_elf_read(data.data(), data.size(), binary);
 	p->code_string = ""; /* release the ELF shader binary */
 
 	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());
+}
diff --git a/src/amd/common/ac_llvm_util.c b/src/amd/common/ac_llvm_util.c
index 5e04452d5a8..9e7a106afa5 100644
--- a/src/amd/common/ac_llvm_util.c
+++ b/src/amd/common/ac_llvm_util.c
@@ -172,20 +172,27 @@ static LLVMPassManagerRef ac_create_passmgr(LLVMTargetLibraryInfoRef target_libr
 	if (!passmgr)
 		return NULL;
 
 	if (target_library_info)
 		LLVMAddTargetLibraryInfo(target_library_info,
 					 passmgr);
 
 	if (check_ir)
 		LLVMAddVerifierPass(passmgr);
 	LLVMAddAlwaysInlinerPass(passmgr);
+	/* Normally, the pass manager runs all passes on one function before
+	 * moving onto another. Adding a barrier no-op pass forces the pass
+	 * manager to run the inliner on all functions first, which makes sure
+	 * that the following passes are only run on the remaining non-inline
+	 * function.
+	 */
+	ac_llvm_add_barrier_noop_pass(passmgr);
 	/* This pass should eliminate all the load and store instructions. */
 	LLVMAddPromoteMemoryToRegisterPass(passmgr);
 	LLVMAddScalarReplAggregatesPass(passmgr);
 	LLVMAddLICMPass(passmgr);
 	LLVMAddAggressiveDCEPass(passmgr);
 	LLVMAddCFGSimplificationPass(passmgr);
 	/* This is recommended by the instruction combining pass. */
 	LLVMAddEarlyCSEMemSSAPass(passmgr);
 	LLVMAddInstructionCombiningPass(passmgr);
 	return passmgr;
diff --git a/src/amd/common/ac_llvm_util.h b/src/amd/common/ac_llvm_util.h
index 373fd8d28db..e5b93037d26 100644
--- a/src/amd/common/ac_llvm_util.h
+++ b/src/amd/common/ac_llvm_util.h
@@ -126,16 +126,17 @@ void ac_init_llvm_once(void);
 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);
 
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* AC_LLVM_UTIL_H */
-- 
2.17.1



More information about the mesa-dev mailing list