nir: add callback to nir_remove_dead_variables()

This allows us to do API specific checks before removing variable
without filling nir_remove_dead_variables() with API specific code.

In the following patches we will use this to support the removal
of dead uniforms in GLSL.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4797>
This commit is contained in:
Timothy Arceri
2020-05-28 10:59:28 +10:00
committed by Marge Bot
parent bc79442f3f
commit 04dbf709ed
23 changed files with 78 additions and 51 deletions

View File

@@ -4083,7 +4083,8 @@ bool nir_lower_vars_to_ssa(nir_shader *shader);
bool nir_remove_dead_derefs(nir_shader *shader);
bool nir_remove_dead_derefs_impl(nir_function_impl *impl);
bool nir_remove_dead_variables(nir_shader *shader, nir_variable_mode modes);
bool nir_remove_dead_variables(nir_shader *shader, nir_variable_mode modes,
bool (*can_remove_var)(nir_variable *var));
bool nir_lower_variable_initializers(nir_shader *shader,
nir_variable_mode modes);

View File

@@ -143,11 +143,15 @@ remove_dead_var_writes(nir_shader *shader, struct set *live)
}
static bool
remove_dead_vars(struct exec_list *var_list, struct set *live)
remove_dead_vars(struct exec_list *var_list, struct set *live,
bool (*can_remove_var)(nir_variable *var))
{
bool progress = false;
foreach_list_typed_safe(nir_variable, var, node, var_list) {
if (can_remove_var && !can_remove_var(var))
continue;
struct set_entry *entry = _mesa_set_search(live, var);
if (entry == NULL) {
/* Mark this variable as used by setting the mode to 0 */
@@ -161,35 +165,49 @@ remove_dead_vars(struct exec_list *var_list, struct set *live)
}
bool
nir_remove_dead_variables(nir_shader *shader, nir_variable_mode modes)
nir_remove_dead_variables(nir_shader *shader, nir_variable_mode modes,
bool (*can_remove_var)(nir_variable *var))
{
bool progress = false;
struct set *live = _mesa_pointer_set_create(NULL);
add_var_use_shader(shader, live, modes);
if (modes & nir_var_uniform)
progress = remove_dead_vars(&shader->uniforms, live) || progress;
if (modes & nir_var_uniform) {
progress = remove_dead_vars(&shader->uniforms, live, can_remove_var) ||
progress;
}
if (modes & nir_var_shader_in)
progress = remove_dead_vars(&shader->inputs, live) || progress;
if (modes & nir_var_shader_in) {
progress = remove_dead_vars(&shader->inputs, live, can_remove_var) ||
progress;
}
if (modes & nir_var_shader_out)
progress = remove_dead_vars(&shader->outputs, live) || progress;
if (modes & nir_var_shader_out) {
progress = remove_dead_vars(&shader->outputs, live, can_remove_var) ||
progress;
}
if (modes & nir_var_shader_temp)
progress = remove_dead_vars(&shader->globals, live) || progress;
if (modes & nir_var_shader_temp) {
progress = remove_dead_vars(&shader->globals, live, can_remove_var) ||
progress;
}
if (modes & nir_var_system_value)
progress = remove_dead_vars(&shader->system_values, live) || progress;
if (modes & nir_var_system_value) {
progress = remove_dead_vars(&shader->system_values, live,
can_remove_var) || progress;
}
if (modes & nir_var_mem_shared)
progress = remove_dead_vars(&shader->shared, live) || progress;
if (modes & nir_var_mem_shared) {
progress = remove_dead_vars(&shader->shared, live, can_remove_var) ||
progress;
}
if (modes & nir_var_function_temp) {
nir_foreach_function(function, shader) {
if (function->impl) {
if (remove_dead_vars(&function->impl->locals, live))
if (remove_dead_vars(&function->impl->locals, live,
can_remove_var))
progress = true;
}
}

View File

@@ -5324,7 +5324,7 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
*/
nir_lower_variable_initializers(b->shader, nir_var_shader_out);
nir_remove_dead_variables(b->shader,
nir_var_shader_in | nir_var_shader_out);
nir_var_shader_in | nir_var_shader_out, NULL);
/* We sometimes generate bogus derefs that, while never used, give the
* validator a bit of heartburn. Run dead code to get rid of them.