From 74746ac03ac75136d5867f0f18fc99fbbede1bf8 Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Tue, 25 Jul 2023 13:29:44 -0700 Subject: [PATCH] nir: Add nir_opt_reuse_constants() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Faith Ekstrand Part-of: --- src/compiler/nir/meson.build | 1 + src/compiler/nir/nir.h | 2 + src/compiler/nir/nir_opt_reuse_constants.c | 49 ++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 src/compiler/nir/nir_opt_reuse_constants.c diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build index 69700ce97e5..1b77eb2d0c4 100644 --- a/src/compiler/nir/meson.build +++ b/src/compiler/nir/meson.build @@ -265,6 +265,7 @@ files_libnir = files( 'nir_opt_reassociate_bfi.c', 'nir_opt_rematerialize_compares.c', 'nir_opt_remove_phis.c', + 'nir_opt_reuse_constants.c', 'nir_opt_shrink_stores.c', 'nir_opt_shrink_vectors.c', 'nir_opt_sink.c', diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index ae036e886c4..627f44b203e 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -6027,6 +6027,8 @@ bool nir_opt_ray_queries(nir_shader *shader); bool nir_opt_ray_query_ranges(nir_shader *shader); +bool nir_opt_reuse_constants(nir_shader *shader); + void nir_sweep(nir_shader *shader); void nir_remap_dual_slot_attributes(nir_shader *shader, diff --git a/src/compiler/nir/nir_opt_reuse_constants.c b/src/compiler/nir/nir_opt_reuse_constants.c new file mode 100644 index 00000000000..2e559253009 --- /dev/null +++ b/src/compiler/nir/nir_opt_reuse_constants.c @@ -0,0 +1,49 @@ +/* + * 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; +}