nir/lower_io_to_vector: Demote the old scalar vars to globals.

This prevents nir_lower_io_to_temporaries from emitting new writes to the
old globals that we meant to have disappear through
DCE/remove_unused_variables.  If you don't do this, then unless you call
nir_opt_undef() and it successfully catches io_to_temps' new writes of
undefs to the scalar components, the scalar vars will stick around and
have stores that conflict with the real vector vars.

This hasn't been a problem for the end result of codegen because
nir_opt_undef() did succeed.  However, things went south with vars_to_ssa
mediump lowering, which obscured the result from opt_undef.  And, it's
really mind-bending to see undef writes to the outputs for a chunk of the
shader compiler pipeline anyway.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18218>
This commit is contained in:
Emma Anholt 2022-08-22 21:47:50 -07:00 committed by Marge Bot
parent 25c180b509
commit 019ca611fa

View file

@ -24,6 +24,7 @@
#include "nir.h"
#include "nir_builder.h"
#include "nir_deref.h"
#include "util/u_dynarray.h"
/** @file nir_lower_io_to_vector.c
*
@ -210,7 +211,8 @@ get_flat_type(const nir_shader *shader, nir_variable *old_vars[MAX_SLOTS][4],
static bool
create_new_io_vars(nir_shader *shader, nir_variable_mode mode,
nir_variable *new_vars[MAX_SLOTS][4],
bool flat_vars[MAX_SLOTS])
bool flat_vars[MAX_SLOTS],
struct util_dynarray *demote_vars)
{
nir_variable *old_vars[MAX_SLOTS][4] = {{0}};
@ -277,7 +279,10 @@ create_new_io_vars(nir_shader *shader, nir_variable_mode mode,
nir_shader_add_variable(shader, var);
for (unsigned i = first; i < frac; i++) {
new_vars[loc][i] = var;
old_vars[loc][i] = NULL;
if (old_vars[loc][i]) {
util_dynarray_append(demote_vars, nir_variable *, old_vars[loc][i]);
old_vars[loc][i] = NULL;
}
}
old_vars[loc][first] = var;
@ -411,6 +416,9 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes)
nir_metadata_require(impl, nir_metadata_dominance);
struct util_dynarray demote_vars;
util_dynarray_init(&demote_vars, NULL);
nir_shader *shader = impl->function->shader;
nir_variable *new_inputs[MAX_SLOTS][4] = {{0}};
nir_variable *new_outputs[MAX_SLOTS][4] = {{0}};
@ -425,7 +433,7 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes)
* so we don't bother doing extra non-work.
*/
if (!create_new_io_vars(shader, nir_var_shader_in,
new_inputs, flat_inputs))
new_inputs, flat_inputs, &demote_vars))
modes &= ~nir_var_shader_in;
}
@ -434,7 +442,7 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes)
* so we don't bother doing extra non-work.
*/
if (!create_new_io_vars(shader, nir_var_shader_out,
new_outputs, flat_outputs))
new_outputs, flat_outputs, &demote_vars))
modes &= ~nir_var_shader_out;
}
@ -585,6 +593,15 @@ nir_lower_io_to_vector_impl(nir_function_impl *impl, nir_variable_mode modes)
}
}
/* Demote the old var to a global, so that things like
* nir_lower_io_to_temporaries() don't trigger on it.
*/
util_dynarray_foreach(&demote_vars, nir_variable *, varp) {
(*varp)->data.mode = nir_var_shader_temp;
}
nir_fixup_deref_modes(b.shader);
util_dynarray_fini(&demote_vars);
if (progress) {
nir_metadata_preserve(impl, nir_metadata_block_index |
nir_metadata_dominance);