mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-17 20:28:05 +02:00
Starting with LLVM-22 we won't see the kernel wrapper anymore, and this
is a trivial fix to get around this.
See: 5458eb2511
Cc: mesa-stable
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39374>
69 lines
2.3 KiB
C
69 lines
2.3 KiB
C
/*
|
|
* Copyright 2024 Valve Corporation
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "nir.h"
|
|
|
|
/*
|
|
* After going through the clang -> LLVM -> SPIR-V translator -> vtn pipes,
|
|
* OpenCL kernel's end up translated to 2 nir_functions:
|
|
*
|
|
* - a "wrapper" function that is_entrypoint but not is_exported
|
|
* - the "real" function that is_exported
|
|
*
|
|
* Confusingly, both functions have the same name.
|
|
*
|
|
* Also, workgroup size information is on the wrapper function only, so we can't
|
|
* just ignore the wrappers. But inlining and removing non-exported would delete
|
|
* the whole shader and lose that information.
|
|
*
|
|
* This pass is a silly solution to the silly problem: it looks for shadowed
|
|
* function names, which can only come from these wrappers. It then exports the
|
|
* wrappers and unexports the inner functions. After inlining and removing
|
|
* non-exported functions, we're left with a single function per kernel with
|
|
* workgroup size information preserved.
|
|
*
|
|
* While we're at it, we unexport _prefixed functions. This is an escape hatch
|
|
* to allow defining `kernel`s that are not intended for export, to workaround
|
|
* OpenCL limitations around `static kernel`s and shared local memory outside
|
|
* `kernel`s.
|
|
*/
|
|
void
|
|
nir_fixup_is_exported(nir_shader *nir)
|
|
{
|
|
struct set *seen =
|
|
_mesa_set_create(NULL, _mesa_hash_string, _mesa_key_string_equal);
|
|
struct set *shadowed =
|
|
_mesa_set_create(NULL, _mesa_hash_string, _mesa_key_string_equal);
|
|
|
|
nir_foreach_function(func, nir) {
|
|
if (_mesa_set_search(seen, func->name)) {
|
|
_mesa_set_add(shadowed, func->name);
|
|
} else {
|
|
_mesa_set_add(seen, func->name);
|
|
}
|
|
}
|
|
|
|
nir_foreach_function(func, nir) {
|
|
if (_mesa_set_search(shadowed, func->name)) {
|
|
func->is_exported = func->is_entrypoint;
|
|
} else {
|
|
/* Starting with LLVM-22 we don't see the wrappers anymore, so we
|
|
* can simply export every entrypoint.
|
|
*
|
|
* We could do an LLVM version check here, but that's going to be a
|
|
* mess making nir depending on LLVM in any way and this seems to work
|
|
* for both situations.
|
|
*/
|
|
func->is_exported |= func->is_entrypoint;
|
|
}
|
|
|
|
if (func->name[0] == '_') {
|
|
func->is_exported = func->is_entrypoint = false;
|
|
}
|
|
}
|
|
|
|
_mesa_set_destroy(seen, NULL);
|
|
_mesa_set_destroy(shadowed, NULL);
|
|
}
|