nir: Consider pointer initializers in nir_remove_dead_variables
Between the creation of a shader (from GLSL or SPIRV frontends) and
nir_lower_variable_initializers is called, variables may refer to
other variables for initialization. Those referred variables need to
be kept alive, so consider that in the pass.
Fixes: 7acc81056f
("compiler/nir: Add support for variable initialization from a pointer")
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8133>
This commit is contained in:
parent
577bfba959
commit
acce4ce04e
|
@ -67,14 +67,21 @@ add_var_use_deref(nir_deref_instr *deref, struct set *live)
|
|||
if (deref->deref_type != nir_deref_type_var)
|
||||
return;
|
||||
|
||||
/* If it's not a local that never escapes the shader, then any access at
|
||||
* all means we need to keep it alive.
|
||||
/* Since these local variables don't escape the shader, writing doesn't
|
||||
* make them live. Only keep them if they are used by some intrinsic.
|
||||
*/
|
||||
if (!(deref->var->data.mode & (nir_var_function_temp |
|
||||
nir_var_shader_temp |
|
||||
nir_var_mem_shared)) ||
|
||||
deref_used_for_not_store(deref))
|
||||
_mesa_set_add(live, deref->var);
|
||||
if ((deref->var->data.mode & (nir_var_function_temp |
|
||||
nir_var_shader_temp |
|
||||
nir_var_mem_shared)) &&
|
||||
!deref_used_for_not_store(deref))
|
||||
return;
|
||||
|
||||
nir_variable *var = deref->var;
|
||||
do {
|
||||
_mesa_set_add(live, var);
|
||||
/* Also mark the chain of variables used to initialize it. */
|
||||
var = var->pointer_initializer;
|
||||
} while (var);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -196,6 +196,7 @@ class nir_copy_prop_vars_test : public nir_vars_test {};
|
|||
class nir_dead_write_vars_test : public nir_vars_test {};
|
||||
class nir_combine_stores_test : public nir_vars_test {};
|
||||
class nir_split_vars_test : public nir_vars_test {};
|
||||
class nir_remove_dead_variables_test : public nir_vars_test {};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -2184,3 +2185,50 @@ TEST_F(nir_split_vars_test, split_wildcard_copy)
|
|||
ASSERT_EQ(count_function_temp_vars(), 8);
|
||||
ASSERT_EQ(count_intrinsics(nir_intrinsic_copy_deref), 4);
|
||||
}
|
||||
|
||||
TEST_F(nir_remove_dead_variables_test, pointer_initializer_used)
|
||||
{
|
||||
nir_variable *x = create_int(nir_var_shader_temp, "x");
|
||||
nir_variable *y = create_int(nir_var_shader_temp, "y");
|
||||
y->pointer_initializer = x;
|
||||
nir_variable *out = create_int(nir_var_shader_out, "out");
|
||||
|
||||
nir_validate_shader(b->shader, NULL);
|
||||
|
||||
nir_copy_var(b, out, y);
|
||||
|
||||
bool progress = nir_remove_dead_variables(b->shader, nir_var_all, NULL);
|
||||
EXPECT_FALSE(progress);
|
||||
|
||||
nir_validate_shader(b->shader, NULL);
|
||||
|
||||
unsigned count = 0;
|
||||
nir_foreach_variable_in_shader(var, b->shader)
|
||||
count++;
|
||||
|
||||
ASSERT_EQ(count, 3);
|
||||
}
|
||||
|
||||
TEST_F(nir_remove_dead_variables_test, pointer_initializer_dead)
|
||||
{
|
||||
nir_variable *x = create_int(nir_var_shader_temp, "x");
|
||||
nir_variable *y = create_int(nir_var_shader_temp, "y");
|
||||
nir_variable *z = create_int(nir_var_shader_temp, "z");
|
||||
y->pointer_initializer = x;
|
||||
z->pointer_initializer = y;
|
||||
|
||||
nir_validate_shader(b->shader, NULL);
|
||||
|
||||
bool progress = nir_remove_dead_variables(b->shader, nir_var_all, NULL);
|
||||
EXPECT_TRUE(progress);
|
||||
|
||||
nir_validate_shader(b->shader, NULL);
|
||||
|
||||
unsigned count = 0;
|
||||
nir_foreach_variable_in_shader(var, b->shader)
|
||||
count++;
|
||||
|
||||
ASSERT_EQ(count, 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue