mesa/src/compiler/nir/nir_opt_reuse_constants.c
Caio Oliveira 74746ac03a nir: Add nir_opt_reuse_constants()
Currently SPIR-V does pull all the NIR constants it creates into the
first block, but we plan to change that behavior to let those constants
be defined as they are used.

This pass was written to provide a fallback to the old behavior, it will
be used for radv to avoid regressions when performing the SPIR-V change.

Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5282>
2023-08-17 14:58:02 +00:00

49 lines
1.3 KiB
C

/*
* Copyright 2023 Intel Corporation
* SPDX-License-Identifier: MIT
*/
#include "nir.h"
#include "nir_instr_set.h"
bool
nir_opt_reuse_constants(nir_shader *shader)
{
bool progress = false;
struct set *consts = nir_instr_set_create(NULL);
nir_foreach_function_impl(impl, shader) {
_mesa_set_clear(consts, NULL);
nir_block *start_block = nir_start_block(impl);
bool func_progress = false;
nir_foreach_block_safe(block, impl) {
const bool in_start_block = start_block == block;
nir_foreach_instr_safe(instr, block) {
if (instr->type != nir_instr_type_load_const)
continue;
struct set_entry *entry = _mesa_set_search(consts, instr);
if (!entry) {
if (!in_start_block)
nir_instr_move(nir_after_block_before_jump(start_block), instr);
_mesa_set_add(consts, instr);
}
func_progress |= nir_instr_set_add_or_rewrite(consts, instr, nir_instrs_equal);
}
}
if (func_progress) {
nir_metadata_preserve(impl, nir_metadata_block_index |
nir_metadata_dominance);
progress = true;
} else {
nir_metadata_preserve(impl, nir_metadata_all);
}
}
nir_instr_set_destroy(consts);
return progress;
}