* add missing patches issue/109

This commit is contained in:
Alexander Baldeck 2025-03-03 09:12:04 +01:00
parent ec8c7cd4ab
commit 39645b784e
4 changed files with 1381 additions and 0 deletions

114
mesa/llvm-19-intel.patch Normal file
View File

@ -0,0 +1,114 @@
# --- T2-COPYRIGHT-NOTE-BEGIN ---
# T2 SDE: package/*/mesa/llvm-19-intel.patch
# Copyright (C) 2024 The T2 SDE Project
#
# This Copyright note is generated by scripts/Create-CopyPatch,
# more information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License version 2 as used by the T2 SDE.
# --- T2-COPYRIGHT-NOTE-END ---
commit 6a8ff3b550ec29ec5a6c5c61a2053c2bd0627166
Author: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Date: Thu Oct 19 15:49:51 2023 +0300
intel/compiler: store u_printf_info in prog_data
So that the driver can decode the printf buffer.
We're not going to use the NIR data directly from the driver
(Iris/Anv) because the late compile steps might want to add more
printfs.
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25814>
diff --git a/src/intel/compiler/brw_compiler.c b/src/intel/compiler/brw_compiler.c
index 884efae4dff..de26a47270b 100644
--- a/src/intel/compiler/brw_compiler.c
+++ b/src/intel/compiler/brw_compiler.c
@@ -320,3 +320,28 @@ brw_write_shader_relocs(const struct brw_isa_info *isa,
}
}
}
+
+void
+brw_stage_prog_data_add_printf(struct brw_stage_prog_data *prog_data,
+ void *mem_ctx,
+ const u_printf_info *print)
+{
+ prog_data->printf_info_count++;
+ prog_data->printf_info = reralloc(mem_ctx, prog_data->printf_info,
+ u_printf_info,
+ prog_data->printf_info_count);
+
+ prog_data->printf_info[prog_data->printf_info_count - 1] = *print;
+ if (print->string_size > 0) {
+ prog_data->printf_info[prog_data->printf_info_count - 1].strings =
+ ralloc_size(mem_ctx, print->string_size);
+ memcpy(prog_data->printf_info[prog_data->printf_info_count - 1].strings,
+ print->strings, print->string_size);
+ }
+ if (print->num_args > 0) {
+ prog_data->printf_info[prog_data->printf_info_count - 1].arg_sizes =
+ ralloc_array(mem_ctx, __typeof__(*print->arg_sizes), print->num_args);
+ memcpy(prog_data->printf_info[prog_data->printf_info_count - 1].arg_sizes,
+ print->arg_sizes, sizeof(print->arg_sizes[0]) *print->num_args);
+ }
+}
diff --git a/src/intel/compiler/brw_compiler.h b/src/intel/compiler/brw_compiler.h
index b26044b3238..c4016fc265b 100644
--- a/src/intel/compiler/brw_compiler.h
+++ b/src/intel/compiler/brw_compiler.h
@@ -33,6 +33,7 @@
#include "util/enum_operators.h"
#include "util/ralloc.h"
#include "util/u_math.h"
+#include "util/u_printf.h"
#include "brw_isa_info.h"
#include "intel_shader_enums.h"
@@ -557,6 +558,10 @@ struct brw_stage_prog_data {
/* Whether shader uses atomic operations. */
bool uses_atomic_load_store;
+
+ /* Printf descriptions contained by the shader */
+ uint32_t printf_info_count;
+ u_printf_info *printf_info;
};
static inline uint32_t *
@@ -571,6 +576,11 @@ brw_stage_prog_data_add_params(struct brw_stage_prog_data *prog_data,
return prog_data->param + old_nr_params;
}
+void
+brw_stage_prog_data_add_printf(struct brw_stage_prog_data *prog_data,
+ void *mem_ctx,
+ const u_printf_info *print);
+
enum brw_barycentric_mode {
BRW_BARYCENTRIC_PERSPECTIVE_PIXEL = 0,
BRW_BARYCENTRIC_PERSPECTIVE_CENTROID = 1,
diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp
index 19845f68d15..992fdb3bd7f 100644
--- a/src/intel/compiler/brw_fs_nir.cpp
+++ b/src/intel/compiler/brw_fs_nir.cpp
@@ -8457,6 +8457,12 @@ nir_to_brw(fs_visitor *s)
.bld = fs_builder(s).at_end(),
};
+ for (unsigned i = 0; i < s->nir->printf_info_count; i++) {
+ brw_stage_prog_data_add_printf(s->prog_data,
+ s->mem_ctx,
+ &s->nir->printf_info[i]);
+ }
+
emit_shader_float_controls_execution_mode(ntb);
/* emit the arrays used for inputs and outputs - load/store intrinsics will

View File

@ -0,0 +1,571 @@
# --- T2-COPYRIGHT-NOTE-BEGIN ---
# T2 SDE: package/*/mesa/llvm-19-passmgr-amd.patch
# Copyright (C) 2024 The T2 SDE Project
#
# This Copyright note is generated by scripts/Create-CopyPatch,
# more information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License version 2 as used by the T2 SDE.
# --- T2-COPYRIGHT-NOTE-END ---
commit 38e50221cd9f37877d258dca84b8d3f58dbdcb88
Author: Ganesh Belgur Ramachandra <ganesh.belgurramachandra@amd.com>
Date: Sun Aug 4 11:40:18 2024 -0500
amd,radeonsi: use new pass manager to handle midend optimizations
Adds an optimizer structure that builds an optimization
pipeline to run LLVM passes using the new pass manager.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30506>
diff --git a/src/amd/llvm/ac_llvm_helper.cpp b/src/amd/llvm/ac_llvm_helper.cpp
index af4a50f8409..429796f40ad 100644
--- a/src/amd/llvm/ac_llvm_helper.cpp
+++ b/src/amd/llvm/ac_llvm_helper.cpp
@@ -17,9 +17,14 @@
#include <llvm/Transforms/Scalar.h>
#include <llvm/Transforms/Utils.h>
#include <llvm/CodeGen/Passes.h>
-#include <llvm/Transforms/IPO/AlwaysInliner.h>
+#include <llvm/Passes/PassBuilder.h>
#include <llvm/Transforms/InstCombine/InstCombine.h>
+#include <llvm/Transforms/IPO/AlwaysInliner.h>
#include <llvm/Transforms/IPO/SCCP.h>
+#include <llvm/Transforms/Scalar/EarlyCSE.h>
+#include <llvm/Transforms/Scalar/LICM.h>
+#include <llvm/Transforms/Scalar/SROA.h>
+#include <llvm/Transforms/Scalar/SimplifyCFG.h>
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include <cstring>
@@ -234,6 +239,95 @@ struct raw_memory_ostream : public raw_pwrite_stream {
}
};
+/* The middle-end optimization passes are run using
+ * the LLVM's new pass manager infrastructure.
+ */
+struct ac_midend_optimizer
+{
+ TargetMachine *target_machine;
+ PassBuilder pass_builder;
+ TargetLibraryInfoImpl target_library_info;
+
+ /* Should be declared in this order only,
+ * so that they are destroyed in the correct order
+ * due to inter-analysis-manager references.
+ */
+ LoopAnalysisManager loop_am;
+ FunctionAnalysisManager function_am;
+ CGSCCAnalysisManager cgscc_am;
+ ModuleAnalysisManager module_am;
+
+ /* Pass Managers */
+ LoopPassManager loop_pm;
+ FunctionPassManager function_pm;
+ ModulePassManager module_pm;
+
+ ac_midend_optimizer(TargetMachine *arg_target_machine, bool arg_check_ir)
+ : target_machine(arg_target_machine),
+ pass_builder(target_machine, PipelineTuningOptions(), {}),
+ target_library_info(Triple(target_machine->getTargetTriple()))
+ {
+ /* Build the pipeline and optimize.
+ * Any custom analyses should be registered
+ * before LLVM's default analysis sets.
+ */
+ function_am.registerPass(
+ [&] { return TargetLibraryAnalysis(target_library_info); }
+ );
+
+ pass_builder.registerModuleAnalyses(module_am);
+ pass_builder.registerCGSCCAnalyses(cgscc_am);
+ pass_builder.registerFunctionAnalyses(function_am);
+ pass_builder.registerLoopAnalyses(loop_am);
+ pass_builder.crossRegisterProxies(loop_am, function_am, cgscc_am, module_am);
+
+ if (arg_check_ir)
+ module_pm.addPass(VerifierPass());
+
+ /* Adding inliner pass to the module pass manager directly
+ * ensures that the pass is run on all functions first, which makes sure
+ * that the following passes are only run on the remaining non-inline
+ * function, so it removes useless work done on dead inline functions.
+ */
+ module_pm.addPass(AlwaysInlinerPass());
+
+ /* The following set of passes run on an individual function/loop first
+ * before proceeding to the next.
+ */
+#if LLVM_VERSION_MAJOR >= 16
+ function_pm.addPass(SROAPass(SROAOptions::ModifyCFG));
+#else
+ // Old version of the code
+ function_pm.addPass(SROAPass());
+#endif
+
+ loop_pm.addPass(LICMPass(LICMOptions()));
+ function_pm.addPass(createFunctionToLoopPassAdaptor(std::move(loop_pm), true));
+ function_pm.addPass(SimplifyCFGPass());
+ function_pm.addPass(EarlyCSEPass(true));
+
+ module_pm.addPass(createModuleToFunctionPassAdaptor(std::move(function_pm)));
+ }
+
+ void run(Module &module)
+ {
+ module_pm.run(module, module_am);
+
+ /* After a run(), the results in the analyses managers
+ * aren't useful to optimize a subsequent LLVM module.
+ * If used, it can lead to unexpected crashes.
+ * Hence, the results in the analyses managers
+ * need to be invalidated and cleared before
+ * running optimizations on a new LLVM module.
+ */
+ module_am.invalidate(module, PreservedAnalyses::none());
+ module_am.clear();
+ cgscc_am.clear();
+ function_am.clear();
+ loop_am.clear();
+ }
+};
+
/* The LLVM compiler is represented as a pass manager containing passes for
* optimizations, instruction selection, and code generation.
*/
@@ -277,41 +371,26 @@ bool ac_compile_module_to_elf(struct ac_compiler_passes *p, LLVMModuleRef module
return true;
}
-LLVMPassManagerRef ac_create_passmgr(LLVMTargetLibraryInfoRef target_library_info,
- bool check_ir)
+ac_midend_optimizer *ac_create_midend_optimizer(LLVMTargetMachineRef tm,
+ bool check_ir)
{
- LLVMPassManagerRef passmgr = LLVMCreatePassManager();
- if (!passmgr)
- return NULL;
-
- if (target_library_info)
- LLVMAddTargetLibraryInfo(target_library_info, passmgr);
+ TargetMachine *TM = reinterpret_cast<TargetMachine *>(tm);
+ return new ac_midend_optimizer(TM, check_ir);
+}
- if (check_ir)
- unwrap(passmgr)->add(createVerifierPass());
+void ac_destroy_midend_optimiser(ac_midend_optimizer *meo)
+{
+ delete meo;
+}
- unwrap(passmgr)->add(createAlwaysInlinerLegacyPass());
+bool ac_llvm_optimize_module(ac_midend_optimizer *meo, LLVMModuleRef module)
+{
+ if (!meo)
+ return false;
- /* 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, so it removes useless work done on dead inline functions.
- */
- unwrap(passmgr)->add(createBarrierNoopPass());
-
- #if LLVM_VERSION_MAJOR >= 16
- unwrap(passmgr)->add(createSROAPass(true));
- #else
- unwrap(passmgr)->add(createSROAPass());
- #endif
- /* TODO: restore IPSCCP */
- unwrap(passmgr)->add(createLICMPass());
- unwrap(passmgr)->add(createCFGSimplificationPass());
- /* This is recommended by the instruction combining pass. */
- unwrap(passmgr)->add(createEarlyCSEPass(true));
- unwrap(passmgr)->add(createInstructionCombiningPass());
- return passmgr;
+ /* Runs all the middle-end optimizations, no code generation */
+ meo->run(*unwrap(module));
+ return true;
}
LLVMValueRef ac_build_atomic_rmw(struct ac_llvm_context *ctx, LLVMAtomicRMWBinOp op,
diff --git a/src/amd/llvm/ac_llvm_util.c b/src/amd/llvm/ac_llvm_util.c
index 221cb99ee60..dddcfa32289 100644
--- a/src/amd/llvm/ac_llvm_util.c
+++ b/src/amd/llvm/ac_llvm_util.c
@@ -182,9 +182,9 @@ bool ac_init_llvm_compiler(struct ac_llvm_compiler *compiler, enum radeon_family
if (!compiler->target_library_info)
goto fail;
- compiler->passmgr =
- ac_create_passmgr(compiler->target_library_info, tm_options & AC_TM_CHECK_IR);
- if (!compiler->passmgr)
+ compiler->meo =
+ ac_create_midend_optimizer(compiler->tm, tm_options & AC_TM_CHECK_IR);
+ if (!compiler->meo)
goto fail;
return true;
@@ -198,8 +198,10 @@ void ac_destroy_llvm_compiler(struct ac_llvm_compiler *compiler)
ac_destroy_llvm_passes(compiler->passes);
ac_destroy_llvm_passes(compiler->low_opt_passes);
- if (compiler->passmgr)
- LLVMDisposePassManager(compiler->passmgr);
+ /* delete optimizer pass manager */
+ if (compiler->meo)
+ ac_destroy_midend_optimiser(compiler->meo);
+
if (compiler->target_library_info)
ac_dispose_target_library_info(compiler->target_library_info);
if (compiler->low_opt_tm)
diff --git a/src/amd/llvm/ac_llvm_util.h b/src/amd/llvm/ac_llvm_util.h
index 29f4a6a9bfb..6311cd048d5 100644
--- a/src/amd/llvm/ac_llvm_util.h
+++ b/src/amd/llvm/ac_llvm_util.h
@@ -44,10 +44,10 @@ enum ac_float_mode
/* Per-thread persistent LLVM objects. */
struct ac_llvm_compiler {
LLVMTargetLibraryInfoRef target_library_info;
- LLVMPassManagerRef passmgr;
/* Default compiler. */
LLVMTargetMachineRef tm;
+ struct ac_midend_optimizer *meo;
struct ac_compiler_passes *passes;
/* Optional compiler for faster compilation with fewer optimizations.
@@ -86,12 +86,15 @@ bool ac_init_llvm_compiler(struct ac_llvm_compiler *compiler, enum radeon_family
enum ac_target_machine_options tm_options);
void ac_destroy_llvm_compiler(struct ac_llvm_compiler *compiler);
+struct ac_midend_optimizer *ac_create_midend_optimizer(LLVMTargetMachineRef tm,
+ bool check_ir);
+void ac_destroy_midend_optimiser(struct ac_midend_optimizer *meo);
+bool ac_llvm_optimize_module(struct ac_midend_optimizer *meo, LLVMModuleRef module);
+
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_elf(struct ac_compiler_passes *p, LLVMModuleRef module,
char **pelf_buffer, size_t *pelf_size);
-LLVMPassManagerRef ac_create_passmgr(LLVMTargetLibraryInfoRef target_library_info,
- bool check_ir);
static inline bool ac_has_vec3_support(enum amd_gfx_level chip, bool use_format)
{
diff --git a/src/amd/vulkan/radv_nir_to_llvm.c b/src/amd/vulkan/radv_nir_to_llvm.c
index 5caf1c025fa..91868b5bef6 100644
--- a/src/amd/vulkan/radv_nir_to_llvm.c
+++ b/src/amd/vulkan/radv_nir_to_llvm.c
@@ -193,10 +193,9 @@ radv_load_output(struct radv_shader_context *ctx, unsigned index, unsigned chan)
}
static void
-ac_llvm_finalize_module(struct radv_shader_context *ctx, LLVMPassManagerRef passmgr)
+ac_llvm_finalize_module(struct radv_shader_context *ctx, struct ac_midend_optimizer *meo)
{
- LLVMRunPassManager(passmgr, ctx->ac.module);
-
+ ac_llvm_optimize_module(meo, ctx->ac.module);
ac_llvm_context_dispose(&ctx->ac);
}
@@ -390,7 +389,7 @@ ac_translate_nir_to_llvm(struct ac_llvm_compiler *ac_llvm, const struct radv_nir
fprintf(stderr, "\n");
}
- ac_llvm_finalize_module(&ctx, ac_llvm->passmgr);
+ ac_llvm_finalize_module(&ctx, ac_llvm->meo);
free(name);
diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.c b/src/gallium/drivers/radeonsi/si_shader_llvm.c
index 1342d0e6425..84275bf1d0d 100644
--- a/src/gallium/drivers/radeonsi/si_shader_llvm.c
+++ b/src/gallium/drivers/radeonsi/si_shader_llvm.c
@@ -236,7 +236,7 @@ void si_llvm_optimize_module(struct si_shader_context *ctx)
ac_dump_module(ctx->ac.module);
/* Run the pass */
- LLVMRunPassManager(ctx->compiler->passmgr, ctx->ac.module);
+ ac_llvm_optimize_module(ctx->compiler->meo, ctx->ac.module);
}
void si_llvm_dispose(struct si_shader_context *ctx)
commit 0a352a838a74d0627e76f5e6bfb5e1020cc89b42
Author: Ganesh Belgur Ramachandra <ganesh.belgurramachandra@amd.com>
Date: Sun Aug 4 12:32:06 2024 -0500
amd,radeonsi: reduce legacy::PassManager use to only run backend passes
The legacy::PassManager is only required to run backend optimizations
and for code generation. It should be deprecated when the new PM
can handle code generation on its own.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30506>
diff --git a/src/amd/llvm/ac_llvm_helper.cpp b/src/amd/llvm/ac_llvm_helper.cpp
index 429796f40ad..8ea878943ba 100644
--- a/src/amd/llvm/ac_llvm_helper.cpp
+++ b/src/amd/llvm/ac_llvm_helper.cpp
@@ -328,48 +328,35 @@ struct ac_midend_optimizer
}
};
-/* The LLVM compiler is represented as a pass manager containing passes for
- * optimizations, instruction selection, and code generation.
+/* The backend passes for optimizations, instruction selection,
+ * and code generation in the LLVM compiler still requires the
+ * legacy::PassManager. The use of the legacy PM will be
+ * deprecated when the new PM can handle backend passes.
*/
-struct ac_compiler_passes {
- raw_memory_ostream ostream; /* ELF shader binary stream */
- legacy::PassManager passmgr; /* list of passes */
-};
-
-struct ac_compiler_passes *ac_create_llvm_passes(LLVMTargetMachineRef tm)
+struct ac_backend_optimizer
{
- struct ac_compiler_passes *p = new ac_compiler_passes();
- if (!p)
- return NULL;
-
- TargetMachine *TM = reinterpret_cast<TargetMachine *>(tm);
+ raw_memory_ostream ostream; /* ELF shader binary stream */
+ legacy::PassManager backend_pass_manager; /* for codegen only */
- if (TM->addPassesToEmitFile(p->passmgr, p->ostream, nullptr,
+ ac_backend_optimizer(TargetMachine *arg_target_machine)
+ {
+ /* add backend passes */
+ if (arg_target_machine->addPassesToEmitFile(backend_pass_manager, ostream, nullptr,
#if LLVM_VERSION_MAJOR >= 18
- CodeGenFileType::ObjectFile)) {
+ CodeGenFileType::ObjectFile)) {
#else
- CGFT_ObjectFile)) {
+ CGFT_ObjectFile)) {
#endif
- fprintf(stderr, "amd: TargetMachine can't emit a file of this type!\n");
- delete p;
- return NULL;
+ fprintf(stderr, "amd: TargetMachine can't emit a file of this type!\n");
+ }
}
- return p;
-}
-
-void ac_destroy_llvm_passes(struct ac_compiler_passes *p)
-{
- delete p;
-}
-/* This returns false on failure. */
-bool ac_compile_module_to_elf(struct ac_compiler_passes *p, LLVMModuleRef module,
- char **pelf_buffer, size_t *pelf_size)
-{
- p->passmgr.run(*unwrap(module));
- p->ostream.take(*pelf_buffer, *pelf_size);
- return true;
-}
+ void run(Module &module, char *&out_buffer, size_t &out_size)
+ {
+ backend_pass_manager.run(module);
+ ostream.take(out_buffer, out_size);
+ }
+};
ac_midend_optimizer *ac_create_midend_optimizer(LLVMTargetMachineRef tm,
bool check_ir)
@@ -393,6 +380,28 @@ bool ac_llvm_optimize_module(ac_midend_optimizer *meo, LLVMModuleRef module)
return true;
}
+ac_backend_optimizer *ac_create_backend_optimizer(LLVMTargetMachineRef tm)
+{
+ TargetMachine *TM = reinterpret_cast<TargetMachine *>(tm);
+ return new ac_backend_optimizer(TM);
+}
+
+void ac_destroy_backend_optimizer(ac_backend_optimizer *beo)
+{
+ delete beo;
+}
+
+bool ac_compile_module_to_elf(ac_backend_optimizer *beo, LLVMModuleRef module,
+ char **pelf_buffer, size_t *pelf_size)
+{
+ if (!beo)
+ return false;
+
+ /* Runs all backend optimizations and code generation */
+ beo->run(*unwrap(module), *pelf_buffer, *pelf_size);
+ return true;
+}
+
LLVMValueRef ac_build_atomic_rmw(struct ac_llvm_context *ctx, LLVMAtomicRMWBinOp op,
LLVMValueRef ptr, LLVMValueRef val, const char *sync_scope)
{
diff --git a/src/amd/llvm/ac_llvm_util.c b/src/amd/llvm/ac_llvm_util.c
index dddcfa32289..c8d5e739726 100644
--- a/src/amd/llvm/ac_llvm_util.c
+++ b/src/amd/llvm/ac_llvm_util.c
@@ -195,8 +195,9 @@ fail:
void ac_destroy_llvm_compiler(struct ac_llvm_compiler *compiler)
{
- ac_destroy_llvm_passes(compiler->passes);
- ac_destroy_llvm_passes(compiler->low_opt_passes);
+ /* delete the codegen pass managers */
+ ac_destroy_backend_optimizer(compiler->beo);
+ ac_destroy_backend_optimizer(compiler->low_opt_beo);
/* delete optimizer pass manager */
if (compiler->meo)
diff --git a/src/amd/llvm/ac_llvm_util.h b/src/amd/llvm/ac_llvm_util.h
index 6311cd048d5..0097601c9fc 100644
--- a/src/amd/llvm/ac_llvm_util.h
+++ b/src/amd/llvm/ac_llvm_util.h
@@ -48,13 +48,13 @@ struct ac_llvm_compiler {
/* Default compiler. */
LLVMTargetMachineRef tm;
struct ac_midend_optimizer *meo;
- struct ac_compiler_passes *passes;
+ struct ac_backend_optimizer *beo;
/* Optional compiler for faster compilation with fewer optimizations.
* LLVM modules can be created with "tm" too. There is no difference.
*/
LLVMTargetMachineRef low_opt_tm; /* uses -O1 instead of -O2 */
- struct ac_compiler_passes *low_opt_passes;
+ struct ac_backend_optimizer *low_opt_beo;
};
LLVMTargetRef ac_get_llvm_target(const char *triple);
@@ -91,9 +91,9 @@ struct ac_midend_optimizer *ac_create_midend_optimizer(LLVMTargetMachineRef tm,
void ac_destroy_midend_optimiser(struct ac_midend_optimizer *meo);
bool ac_llvm_optimize_module(struct ac_midend_optimizer *meo, LLVMModuleRef module);
-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_elf(struct ac_compiler_passes *p, LLVMModuleRef module,
+struct ac_backend_optimizer *ac_create_backend_optimizer(LLVMTargetMachineRef tm);
+void ac_destroy_backend_optimizer(struct ac_backend_optimizer *beo);
+bool ac_compile_module_to_elf(struct ac_backend_optimizer *beo, LLVMModuleRef module,
char **pelf_buffer, size_t *pelf_size);
static inline bool ac_has_vec3_support(enum amd_gfx_level chip, bool use_format)
diff --git a/src/amd/vulkan/radv_llvm_helper.cpp b/src/amd/vulkan/radv_llvm_helper.cpp
index 53a4b57cca5..615d90a3b58 100644
--- a/src/amd/vulkan/radv_llvm_helper.cpp
+++ b/src/amd/vulkan/radv_llvm_helper.cpp
@@ -11,7 +11,7 @@ class radv_llvm_per_thread_info {
public:
radv_llvm_per_thread_info(enum radeon_family arg_family, enum ac_target_machine_options arg_tm_options,
unsigned arg_wave_size)
- : family(arg_family), tm_options(arg_tm_options), wave_size(arg_wave_size), passes(NULL)
+ : family(arg_family), tm_options(arg_tm_options), wave_size(arg_wave_size), beo(NULL)
{
}
@@ -25,8 +25,8 @@ public:
if (!ac_init_llvm_compiler(&llvm_info, family, tm_options))
return false;
- passes = ac_create_llvm_passes(llvm_info.tm);
- if (!passes)
+ beo = ac_create_backend_optimizer(llvm_info.tm);
+ if (!beo)
return false;
return true;
@@ -34,7 +34,7 @@ public:
bool compile_to_memory_buffer(LLVMModuleRef module, char **pelf_buffer, size_t *pelf_size)
{
- return ac_compile_module_to_elf(passes, module, pelf_buffer, pelf_size);
+ return ac_compile_module_to_elf(beo, module, pelf_buffer, pelf_size);
}
bool is_same(enum radeon_family arg_family, enum ac_target_machine_options arg_tm_options, unsigned arg_wave_size)
@@ -49,7 +49,7 @@ private:
enum radeon_family family;
enum ac_target_machine_options tm_options;
unsigned wave_size;
- struct ac_compiler_passes *passes;
+ struct ac_backend_optimizer *beo;
};
/* we have to store a linked list per thread due to the possibility of multiple gpus being required */
@@ -68,9 +68,9 @@ radv_compile_to_elf(struct ac_llvm_compiler *info, LLVMModuleRef module, char **
}
if (!thread_info) {
- struct ac_compiler_passes *passes = ac_create_llvm_passes(info->tm);
- bool ret = ac_compile_module_to_elf(passes, module, pelf_buffer, pelf_size);
- ac_destroy_llvm_passes(passes);
+ struct ac_backend_optimizer *beo = ac_create_backend_optimizer(info->tm);
+ bool ret = ac_compile_module_to_elf(beo, module, pelf_buffer, pelf_size);
+ ac_destroy_backend_optimizer(beo);
return ret;
}
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 9fe1c71a21a..318e7b1894e 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -154,9 +154,9 @@ struct ac_llvm_compiler *si_create_llvm_compiler(struct si_screen *sscreen)
if (!ac_init_llvm_compiler(compiler, sscreen->info.family, tm_options))
return NULL;
- compiler->passes = ac_create_llvm_passes(compiler->tm);
+ compiler->beo = ac_create_backend_optimizer(compiler->tm);
if (compiler->low_opt_tm)
- compiler->low_opt_passes = ac_create_llvm_passes(compiler->low_opt_tm);
+ compiler->low_opt_beo = ac_create_backend_optimizer(compiler->low_opt_tm);
return compiler;
#else
diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm.c b/src/gallium/drivers/radeonsi/si_shader_llvm.c
index 84275bf1d0d..966cf753c1c 100644
--- a/src/gallium/drivers/radeonsi/si_shader_llvm.c
+++ b/src/gallium/drivers/radeonsi/si_shader_llvm.c
@@ -73,15 +73,15 @@ bool si_compile_llvm(struct si_screen *sscreen, struct si_shader_binary *binary,
}
if (!si_replace_shader(count, binary)) {
- struct ac_compiler_passes *passes = compiler->passes;
+ struct ac_backend_optimizer *beo = compiler->beo;
- if (less_optimized && compiler->low_opt_passes)
- passes = compiler->low_opt_passes;
+ if (less_optimized && compiler->low_opt_beo)
+ beo = compiler->low_opt_beo;
struct si_llvm_diagnostics diag = {debug};
LLVMContextSetDiagnosticHandler(ac->context, si_diagnostic_handler, &diag);
- if (!ac_compile_module_to_elf(passes, ac->module, (char **)&binary->code_buffer,
+ if (!ac_compile_module_to_elf(beo, ac->module, (char **)&binary->code_buffer,
&binary->code_size))
diag.retval = 1;
@@ -794,7 +794,7 @@ static bool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shade
static bool si_should_optimize_less(struct ac_llvm_compiler *compiler,
struct si_shader_selector *sel)
{
- if (!compiler->low_opt_passes)
+ if (!compiler->low_opt_beo)
return false;
/* Assume a slow CPU. */

612
mesa/llvm-19-passmgr.patch Normal file
View File

@ -0,0 +1,612 @@
# --- T2-COPYRIGHT-NOTE-BEGIN ---
# T2 SDE: package/*/mesa/llvm-19-passmgr.patch
# Copyright (C) 2024 The T2 SDE Project
#
# This Copyright note is generated by scripts/Create-CopyPatch,
# more information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License version 2 as used by the T2 SDE.
# --- T2-COPYRIGHT-NOTE-END ---
commit 47cd0eee2611001499e3aa0a045fbed38c2dc1e5
Author: Dave Airlie <airlied@redhat.com>
Date: Thu Jun 20 15:05:10 2024 +1000
gallivm: create a pass manager wrapper.
With the introduction of the orc jit and looking at the mess that
is integrating with LLVM pass mgmt, encapsulate the passmgr
interactions in an internal abstraction so it can be shared,
and the compiler code isn't so messy to read.
Acked-by: Konstantin Seurer <konstantin.seurer@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29796>
diff --git a/src/gallium/auxiliary/gallivm/lp_bld.h b/src/gallium/auxiliary/gallivm/lp_bld.h
index fd2a4943f56..24e64fec2bf 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld.h
@@ -83,19 +83,12 @@
#define LLVMInsertBasicBlock ILLEGAL_LLVM_FUNCTION
#define LLVMCreateBuilder ILLEGAL_LLVM_FUNCTION
-#if LLVM_VERSION_MAJOR >= 15
-#define GALLIVM_HAVE_CORO 0
-#define GALLIVM_USE_NEW_PASS 1
-#elif LLVM_VERSION_MAJOR >= 8
-#define GALLIVM_HAVE_CORO 1
-#define GALLIVM_USE_NEW_PASS 0
+#if LLVM_VERSION_MAJOR >= 8
+#define GALLIVM_COROUTINES 1
#else
-#define GALLIVM_HAVE_CORO 0
-#define GALLIVM_USE_NEW_PASS 0
+#define GALLIVM_COROUTINES 0
#endif
-#define GALLIVM_COROUTINES (GALLIVM_HAVE_CORO || GALLIVM_USE_NEW_PASS)
-
/* LLVM is transitioning to "opaque pointers", and as such deprecates
* LLVMBuildGEP, LLVMBuildCall, LLVMBuildLoad, replacing them with
* LLVMBuildGEP2, LLVMBuildCall2, LLVMBuildLoad2 respectivelly.
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c
index 62d26141175..195cfa7cdc9 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c
@@ -43,18 +43,6 @@
#include <llvm/Config/llvm-config.h>
#include <llvm-c/Analysis.h>
#include <llvm-c/BitWriter.h>
-#if GALLIVM_USE_NEW_PASS == 1
-#include <llvm-c/Transforms/PassBuilder.h>
-#elif GALLIVM_HAVE_CORO == 1
-#include <llvm-c/Transforms/Scalar.h>
-#if LLVM_VERSION_MAJOR >= 7
-#include <llvm-c/Transforms/Utils.h>
-#endif
-#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64)
-#include <llvm-c/Transforms/IPO.h>
-#endif
-#include <llvm-c/Transforms/Coroutines.h>
-#endif
unsigned gallivm_perf = 0;
@@ -115,23 +103,6 @@ enum LLVM_CodeGenOpt_Level {
static bool
create_pass_manager(struct gallivm_state *gallivm)
{
-#if GALLIVM_USE_NEW_PASS == 0
- assert(!gallivm->passmgr);
- assert(gallivm->target);
-
- gallivm->passmgr = LLVMCreateFunctionPassManagerForModule(gallivm->module);
- if (!gallivm->passmgr)
- return false;
-
-#if GALLIVM_HAVE_CORO == 1
- gallivm->cgpassmgr = LLVMCreatePassManager();
-#endif
- /*
- * TODO: some per module pass manager with IPO passes might be helpful -
- * the generated texture functions may benefit from inlining if they are
- * simple, or constant propagation into them, etc.
- */
-
{
char *td_str;
// New ones from the Module.
@@ -140,58 +111,7 @@ create_pass_manager(struct gallivm_state *gallivm)
free(td_str);
}
-#if GALLIVM_HAVE_CORO == 1
-#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64)
- LLVMAddArgumentPromotionPass(gallivm->cgpassmgr);
- LLVMAddFunctionAttrsPass(gallivm->cgpassmgr);
-#endif
- LLVMAddCoroEarlyPass(gallivm->cgpassmgr);
- LLVMAddCoroSplitPass(gallivm->cgpassmgr);
- LLVMAddCoroElidePass(gallivm->cgpassmgr);
-#endif
-
- if ((gallivm_perf & GALLIVM_PERF_NO_OPT) == 0) {
- /*
- * TODO: Evaluate passes some more - keeping in mind
- * both quality of generated code and compile times.
- */
- /*
- * NOTE: if you change this, don't forget to change the output
- * with GALLIVM_DEBUG_DUMP_BC in gallivm_compile_module.
- */
- LLVMAddScalarReplAggregatesPass(gallivm->passmgr);
- LLVMAddEarlyCSEPass(gallivm->passmgr);
- LLVMAddCFGSimplificationPass(gallivm->passmgr);
- /*
- * FIXME: LICM is potentially quite useful. However, for some
- * rather crazy shaders the compile time can reach _hours_ per shader,
- * due to licm implying lcssa (since llvm 3.5), which can take forever.
- * Even for sane shaders, the cost of licm is rather high (and not just
- * due to lcssa, licm itself too), though mostly only in cases when it
- * can actually move things, so having to disable it is a pity.
- * LLVMAddLICMPass(gallivm->passmgr);
- */
- LLVMAddReassociatePass(gallivm->passmgr);
- LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
-#if LLVM_VERSION_MAJOR <= 11
- LLVMAddConstantPropagationPass(gallivm->passmgr);
-#else
- LLVMAddInstructionSimplifyPass(gallivm->passmgr);
-#endif
- LLVMAddInstructionCombiningPass(gallivm->passmgr);
- LLVMAddGVNPass(gallivm->passmgr);
- }
- else {
- /* We need at least this pass to prevent the backends to fail in
- * unexpected ways.
- */
- LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
- }
-#if GALLIVM_HAVE_CORO == 1
- LLVMAddCoroCleanupPass(gallivm->passmgr);
-#endif
-#endif
- return true;
+ return lp_passmgr_create(gallivm->module, &gallivm->passmgr);
}
/**
@@ -201,17 +121,7 @@ create_pass_manager(struct gallivm_state *gallivm)
void
gallivm_free_ir(struct gallivm_state *gallivm)
{
-#if GALLIVM_USE_NEW_PASS == 0
- if (gallivm->passmgr) {
- LLVMDisposePassManager(gallivm->passmgr);
- }
-
-#if GALLIVM_HAVE_CORO == 1
- if (gallivm->cgpassmgr) {
- LLVMDisposePassManager(gallivm->cgpassmgr);
- }
-#endif
-#endif
+ lp_passmgr_dispose(gallivm->passmgr);
if (gallivm->engine) {
/* This will already destroy any associated module */
@@ -239,12 +149,7 @@ gallivm_free_ir(struct gallivm_state *gallivm)
gallivm->target = NULL;
gallivm->module = NULL;
gallivm->module_name = NULL;
-#if GALLIVM_USE_NEW_PASS == 0
-#if GALLIVM_HAVE_CORO == 1
- gallivm->cgpassmgr = NULL;
-#endif
gallivm->passmgr = NULL;
-#endif
gallivm->context = NULL;
gallivm->builder = NULL;
gallivm->cache = NULL;
@@ -556,8 +461,6 @@ void lp_init_clock_hook(struct gallivm_state *gallivm)
void
gallivm_compile_module(struct gallivm_state *gallivm)
{
- int64_t time_begin = 0;
-
assert(!gallivm->compiled);
if (gallivm->builder) {
@@ -592,65 +495,10 @@ gallivm_compile_module(struct gallivm_state *gallivm)
"[-mattr=<-mattr option(s)>]");
}
- if (gallivm_debug & GALLIVM_DEBUG_PERF)
- time_begin = os_time_get();
-
-#if GALLIVM_USE_NEW_PASS == 1
- char passes[1024];
- passes[0] = 0;
-
- /*
- * there should be some way to combine these two pass runs but I'm not seeing it,
- * at the time of writing.
- */
- strcpy(passes, "default<O0>");
-
- LLVMPassBuilderOptionsRef opts = LLVMCreatePassBuilderOptions();
- LLVMRunPasses(gallivm->module, passes, LLVMGetExecutionEngineTargetMachine(gallivm->engine), opts);
-
- if (!(gallivm_perf & GALLIVM_PERF_NO_OPT))
-#if LLVM_VERSION_MAJOR >= 18
- strcpy(passes, "sroa,early-cse,simplifycfg,reassociate,mem2reg,instsimplify,instcombine<no-verify-fixpoint>");
-#else
- strcpy(passes, "sroa,early-cse,simplifycfg,reassociate,mem2reg,instsimplify,instcombine");
-#endif
- else
- strcpy(passes, "mem2reg");
-
- LLVMRunPasses(gallivm->module, passes, LLVMGetExecutionEngineTargetMachine(gallivm->engine), opts);
- LLVMDisposePassBuilderOptions(opts);
-#else
-#if GALLIVM_HAVE_CORO == 1
- LLVMRunPassManager(gallivm->cgpassmgr, gallivm->module);
-#endif
- /* Run optimization passes */
- LLVMInitializeFunctionPassManager(gallivm->passmgr);
- LLVMValueRef func;
- func = LLVMGetFirstFunction(gallivm->module);
- while (func) {
- if (0) {
- debug_printf("optimizing func %s...\n", LLVMGetValueName(func));
- }
-
- /* Disable frame pointer omission on debug/profile builds */
- /* XXX: And workaround http://llvm.org/PR21435 */
-#if MESA_DEBUG || defined(PROFILE) || DETECT_ARCH_X86 || DETECT_ARCH_X86_64
- LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim", "true");
- LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim-non-leaf", "true");
-#endif
-
- LLVMRunFunctionPassManager(gallivm->passmgr, func);
- func = LLVMGetNextFunction(func);
- }
- LLVMFinalizeFunctionPassManager(gallivm->passmgr);
-#endif
- if (gallivm_debug & GALLIVM_DEBUG_PERF) {
- int64_t time_end = os_time_get();
- int time_msec = (int)((time_end - time_begin) / 1000);
- assert(gallivm->module_name);
- debug_printf("optimizing module %s took %d msec\n",
- gallivm->module_name, time_msec);
- }
+ lp_passmgr_run(gallivm->passmgr,
+ gallivm->module,
+ LLVMGetExecutionEngineTargetMachine(gallivm->engine),
+ gallivm->module_name);
/* Setting the module's DataLayout to an empty string will cause the
* ExecutionEngine to copy to the DataLayout string from its target machine
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h
index f53702f17a1..62ad8a9a60a 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h
@@ -33,6 +33,7 @@
#include "util/compiler.h"
#include "util/u_pointer.h" // for func_pointer
#include "lp_bld.h"
+#include "lp_bld_passmgr.h"
#include <llvm-c/ExecutionEngine.h>
#ifdef __cplusplus
@@ -46,12 +47,7 @@ struct gallivm_state
LLVMModuleRef module;
LLVMExecutionEngineRef engine;
LLVMTargetDataRef target;
-#if GALLIVM_USE_NEW_PASS == 0
- LLVMPassManagerRef passmgr;
-#if GALLIVM_HAVE_CORO == 1
- LLVMPassManagerRef cgpassmgr;
-#endif
-#endif
+ struct lp_passmgr *passmgr;
LLVMContextRef context;
LLVMBuilderRef builder;
LLVMMCJITMemoryManagerRef memorymgr;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_passmgr.c b/src/gallium/auxiliary/gallivm/lp_bld_passmgr.c
new file mode 100644
index 00000000000..0fd61895d73
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_passmgr.c
@@ -0,0 +1,234 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "util/u_debug.h"
+#include "util/os_time.h"
+#include "lp_bld_debug.h"
+#include "lp_bld_passmgr.h"
+#include "lp_bld_init.h"
+
+#if LLVM_VERSION_MAJOR >= 15
+#define HAVE_CORO 0
+#define USE_NEW_PASS 1
+#elif LLVM_VERSION_MAJOR >= 8
+#define HAVE_CORO 1
+#define USE_NEW_PASS 0
+#else
+#define HAVE_CORO 0
+#define USE_NEW_PASS 0
+#endif
+
+#if USE_NEW_PASS == 1
+#include <llvm-c/Transforms/PassBuilder.h>
+#elif HAVE_CORO == 1
+#include <llvm-c/Transforms/Scalar.h>
+#if LLVM_VERSION_MAJOR >= 7
+#include <llvm-c/Transforms/Utils.h>
+#endif
+#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64)
+#include <llvm-c/Transforms/IPO.h>
+#endif
+#include <llvm-c/Transforms/Coroutines.h>
+#endif
+
+#if USE_NEW_PASS == 0
+struct lp_passmgr {
+ LLVMPassManagerRef passmgr;
+#if HAVE_CORO == 1
+ LLVMPassManagerRef cgpassmgr;
+#endif
+};
+#else
+struct lp_passmgr;
+#endif
+
+bool
+lp_passmgr_create(LLVMModuleRef module, struct lp_passmgr **mgr_p)
+{
+ void *mgr = NULL;
+#if USE_NEW_PASS == 0
+ mgr = CALLOC_STRUCT(lp_passmgr);
+ if (!mgr)
+ return false;
+
+ mgr->passmgr = LLVMCreateFunctionPassManagerForModule(module);
+ if (!mgr->passmgr) {
+ free(mgr);
+ return false;
+ }
+
+#if HAVE_CORO == 1
+ mgr->cgpassmgr = LLVMCreatePassManager();
+#endif
+ /*
+ * TODO: some per module pass manager with IPO passes might be helpful -
+ * the generated texture functions may benefit from inlining if they are
+ * simple, or constant propagation into them, etc.
+ */
+
+#if HAVE_CORO == 1
+#if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64)
+ LLVMAddArgumentPromotionPass(mgr->cgpassmgr);
+ LLVMAddFunctionAttrsPass(mgr->cgpassmgr);
+#endif
+ LLVMAddCoroEarlyPass(mgr->cgpassmgr);
+ LLVMAddCoroSplitPass(mgr->cgpassmgr);
+ LLVMAddCoroElidePass(mgr->cgpassmgr);
+#endif
+
+ if ((gallivm_perf & GALLIVM_PERF_NO_OPT) == 0) {
+ /*
+ * TODO: Evaluate passes some more - keeping in mind
+ * both quality of generated code and compile times.
+ */
+ /*
+ * NOTE: if you change this, don't forget to change the output
+ * with GALLIVM_DEBUG_DUMP_BC in gallivm_compile_module.
+ */
+ LLVMAddScalarReplAggregatesPass(mgr->passmgr);
+ LLVMAddEarlyCSEPass(mgr->passmgr);
+ LLVMAddCFGSimplificationPass(mgr->passmgr);
+ /*
+ * FIXME: LICM is potentially quite useful. However, for some
+ * rather crazy shaders the compile time can reach _hours_ per shader,
+ * due to licm implying lcssa (since llvm 3.5), which can take forever.
+ * Even for sane shaders, the cost of licm is rather high (and not just
+ * due to lcssa, licm itself too), though mostly only in cases when it
+ * can actually move things, so having to disable it is a pity.
+ * LLVMAddLICMPass(mgr->passmgr);
+ */
+ LLVMAddReassociatePass(mgr->passmgr);
+ LLVMAddPromoteMemoryToRegisterPass(mgr->passmgr);
+#if LLVM_VERSION_MAJOR <= 11
+ LLVMAddConstantPropagationPass(mgr->passmgr);
+#else
+ LLVMAddInstructionSimplifyPass(mgr->passmgr);
+#endif
+ LLVMAddInstructionCombiningPass(mgr->passmgr);
+ LLVMAddGVNPass(mgr->passmgr);
+ }
+ else {
+ /* We need at least this pass to prevent the backends to fail in
+ * unexpected ways.
+ */
+ LLVMAddPromoteMemoryToRegisterPass(mgr->passmgr);
+ }
+#if HAVE_CORO == 1
+ LLVMAddCoroCleanupPass(mgr->passmgr);
+#endif
+#endif
+ *mgr_p = mgr;
+ return true;
+}
+
+void
+lp_passmgr_run(struct lp_passmgr *mgr,
+ LLVMModuleRef module,
+ LLVMTargetMachineRef tm,
+ const char *module_name)
+{
+ int64_t time_begin;
+
+ if (gallivm_debug & GALLIVM_DEBUG_PERF)
+ time_begin = os_time_get();
+
+#if USE_NEW_PASS == 1
+ char passes[1024];
+ passes[0] = 0;
+
+ /*
+ * there should be some way to combine these two pass runs but I'm not seeing it,
+ * at the time of writing.
+ */
+ strcpy(passes, "default<O0>");
+
+ LLVMPassBuilderOptionsRef opts = LLVMCreatePassBuilderOptions();
+ LLVMRunPasses(module, passes, tm, opts);
+
+ if (!(gallivm_perf & GALLIVM_PERF_NO_OPT))
+#if LLVM_VERSION_MAJOR >= 18
+ strcpy(passes, "sroa,early-cse,simplifycfg,reassociate,mem2reg,instsimplify,instcombine<no-verify-fixpoint>");
+#else
+ strcpy(passes, "sroa,early-cse,simplifycfg,reassociate,mem2reg,instsimplify,instcombine");
+#endif
+ else
+ strcpy(passes, "mem2reg");
+
+ LLVMRunPasses(module, passes, tm, opts);
+ LLVMDisposePassBuilderOptions(opts);
+#else
+#if HAVE_CORO == 1
+ LLVMRunPassManager(mgr->cgpassmgr, module);
+#endif
+ /* Run optimization passes */
+ LLVMInitializeFunctionPassManager(mgr->passmgr);
+ LLVMValueRef func;
+ func = LLVMGetFirstFunction(module);
+ while (func) {
+ if (0) {
+ debug_printf("optimizing func %s...\n", LLVMGetValueName(func));
+ }
+
+ /* Disable frame pointer omission on debug/profile builds */
+ /* XXX: And workaround http://llvm.org/PR21435 */
+#if MESA_DEBUG || defined(PROFILE) || DETECT_ARCH_X86 || DETECT_ARCH_X86_64
+ LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim", "true");
+ LLVMAddTargetDependentFunctionAttr(func, "no-frame-pointer-elim-non-leaf", "true");
+#endif
+
+ LLVMRunFunctionPassManager(mgr->passmgr, func);
+ func = LLVMGetNextFunction(func);
+ }
+ LLVMFinalizeFunctionPassManager(mgr->passmgr);
+#endif
+ if (gallivm_debug & GALLIVM_DEBUG_PERF) {
+ int64_t time_end = os_time_get();
+ int time_msec = (int)((time_end - time_begin) / 1000);
+ assert(module_name);
+ debug_printf("optimizing module %s took %d msec\n",
+ module_name, time_msec);
+ }
+}
+
+void
+lp_passmgr_dispose(struct lp_passmgr *mgr)
+{
+#if USE_NEW_PASS == 0
+ if (mgr->passmgr) {
+ LLVMDisposePassManager(mgr->passmgr);
+ mgr->passmgr = NULL;
+ }
+
+#if HAVE_CORO == 1
+ if (mgr->cgpassmgr) {
+ LLVMDisposePassManager(mgr->cgpassmgr);
+ mgr->cgpassmgr = NULL;
+ }
+#endif
+ FREE(mgr);
+#endif
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_passmgr.h b/src/gallium/auxiliary/gallivm/lp_bld_passmgr.h
new file mode 100644
index 00000000000..4ebf6149117
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_passmgr.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef LP_BLD_PASSMGR_H
+#define LP_BLD_PASSMGR_H
+
+#include "lp_bld.h"
+#include <llvm-c/ExecutionEngine.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct lp_passmgr;
+
+/*
+ * mgr can be returned as NULL for modern pass mgr handling
+ * so use a bool to denote success/fail.
+ */
+bool lp_passmgr_create(LLVMModuleRef module, struct lp_passmgr **mgr);
+void lp_passmgr_run(struct lp_passmgr *mgr,
+ LLVMModuleRef module,
+ LLVMTargetMachineRef tm,
+ const char *module_name);
+void lp_passmgr_dispose(struct lp_passmgr *mgr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gallium/auxiliary/meson.build b/src/gallium/auxiliary/meson.build
index 35ad5247b4c..53459aa2d4a 100644
--- a/src/gallium/auxiliary/meson.build
+++ b/src/gallium/auxiliary/meson.build
@@ -366,6 +366,8 @@ if draw_with_llvm
'gallivm/lp_bld_nir_soa.c',
'gallivm/lp_bld_pack.c',
'gallivm/lp_bld_pack.h',
+ 'gallivm/lp_bld_passmgr.h',
+ 'gallivm/lp_bld_passmgr.c',
'gallivm/lp_bld_printf.c',
'gallivm/lp_bld_printf.h',
'gallivm/lp_bld_quad.c',

84
mesa/llvm-19.patch Normal file
View File

@ -0,0 +1,84 @@
# --- T2-COPYRIGHT-NOTE-BEGIN ---
# T2 SDE: package/*/mesa/llvm-19.patch
# Copyright (C) 2024 The T2 SDE Project
#
# This Copyright note is generated by scripts/Create-CopyPatch,
# more information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License version 2 as used by the T2 SDE.
# --- T2-COPYRIGHT-NOTE-END ---
commit 5a9c052ba78e5d1b0020b8f8320d211d2205a958
Author: Khem Raj <raj.khem@gmail.com>
Date: Mon Jul 1 23:09:29 2024 -0700
amd: Include missing llvm IR header Module.h
With LLVM-19, Module.h header is not being pulled, which results in
compile errors e.g.
src/amd/llvm/ac_llvm_helper.cpp:102:10: error: no matching function for call to unwrap(LLVMOpaqueModule*&)
102 | unwrap(module)->setTargetTriple(TM->getTargetTriple().getTriple());
| ~~~~~~^~~~~~~~
In file included from /mnt/b/yoe/master/build/tmp/work/x86_64-linux/mesa-native/24.0.7/recipe-sysroot-native/usr/include/llvm/IR/Type.h:18,
from /mnt/b/yoe/master/build/tmp/work/x86_64-linux/mesa-native/24.0.7/recipe-sysroot-native/usr/include/llvm/IR/DerivedTypes.h:23,
from /mnt/b/yoe/master/build/tmp/work/x86_64-linux/mesa-native/24.0.7/recipe-sysroot-native/usr/include/llvm/IR/InstrTypes.h:26,
from /mnt/b/yoe/master/build/tmp/work/x86_64-linux/mesa-native/24.0.7/recipe-sysroot-native/usr/include/llvm/Analysis/TargetLibraryInfo.h:14,
from ../mesa-24.0.7/src/amd/llvm/ac_llvm_helper.cpp:8:
Its getting the definition from llvm/IR/Type.h instead of Module.h and caused
confusion to compiler
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11424
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29993>
diff --git a/src/amd/llvm/ac_llvm_helper.cpp b/src/amd/llvm/ac_llvm_helper.cpp
index 5d065279ad1..af4a50f8409 100644
--- a/src/amd/llvm/ac_llvm_helper.cpp
+++ b/src/amd/llvm/ac_llvm_helper.cpp
@@ -8,6 +8,7 @@
#include <llvm/Analysis/TargetLibraryInfo.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LegacyPassManager.h>
+#include <llvm/IR/Module.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/MC/MCSubtargetInfo.h>
commit fa9cd89a85b904615ebc11da609445b5b751e68d
Author: Satadru Pramanik <satadru@umich.edu>
Date: Sat Oct 5 13:35:52 2024 +0000
Update lp_bld_misc.cpp to support llvm-19+.
Fixes #11896.
cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31533>
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index 7975fcf1ac9..5b615d627ff 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -329,8 +329,14 @@ lp_build_fill_mattrs(std::vector<std::string> &MAttrs)
* which allows us to enable/disable code generation based
* on the results of cpuid on these architectures.
*/
- llvm::StringMap<bool> features;
- llvm::sys::getHostCPUFeatures(features);
+ #if LLVM_VERSION_MAJOR >= 19
+ /* llvm-19+ returns StringMap from getHostCPUFeatures.
+ */
+ auto features = llvm::sys::getHostCPUFeatures();
+ #else
+ llvm::StringMap<bool> features;
+ llvm::sys::getHostCPUFeatures(features);
+ #endif
for (llvm::StringMapIterator<bool> f = features.begin();
f != features.end();