From 869b5a562e2d10d39406e9323ffef90f7dc129bb Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 12 Jul 2023 16:15:29 +1000 Subject: [PATCH] nir/opt_copy_prop_vars: remove var hash entry on kill alias If kill alias results in the hash table entry holding an empty copies array then remove the hash entry and return the dynamic array to the unused pool. This helps avoid hash table size getting out of control in very large shaders. 151.09 seconds -> 118.60 seconds Reviewed-by: Emma Anholt Reviewed-by: Faith Ekstrand Part-of: --- src/compiler/nir/nir_opt_copy_prop_vars.c | 37 +++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c index 5fa64a4b08a..6c58e7eae6c 100644 --- a/src/compiler/nir/nir_opt_copy_prop_vars.c +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c @@ -327,19 +327,19 @@ get_copies_dynarray(struct copy_prop_var_state *state) return cp_arr; } -static struct util_dynarray * +static struct copies_dynarray * copies_array_for_var(struct copy_prop_var_state *state, struct hash_table *copies, nir_variable *var) { struct hash_entry *entry = _mesa_hash_table_search(copies, var); if (entry != NULL) - return &((struct copies_dynarray *) entry->data)->arr; + return (struct copies_dynarray *) entry->data; struct copies_dynarray *copies_array = get_copies_dynarray(state); _mesa_hash_table_insert(copies, var, copies_array); - return &copies_array->arr; + return copies_array; } static struct util_dynarray * @@ -352,8 +352,9 @@ copies_array_for_deref(struct copy_prop_var_state *state, if (deref->_path->path[0]->deref_type != nir_deref_type_var) { copies_array = &copies->arr; } else { - copies_array = + struct copies_dynarray *cpda = copies_array_for_var(state, copies->ht, deref->_path->path[0]->var); + copies_array = &cpda->arr; } return copies_array; @@ -497,8 +498,8 @@ lookup_entry_and_kill_aliases(struct copy_prop_var_state *state, deref->_path->path[0]->var->data.mode == nir_var_mem_shared) { hash_table_foreach(copies->ht, ht_entry) { - struct util_dynarray *copies_array = - &((struct copies_dynarray *) ht_entry->data)->arr; + struct copies_dynarray *cp_arr = ht_entry->data; + struct util_dynarray *copies_array = &cp_arr->arr; nir_variable *var = (nir_variable *) ht_entry->key; if (deref->_path->path[0]->deref_type == nir_deref_type_var && @@ -508,18 +509,29 @@ lookup_entry_and_kill_aliases(struct copy_prop_var_state *state, lookup_entry_and_kill_aliases_copy_array(state, copies_array, deref, write_mask, remove_entry, &entry, &entry_removed); + + if (copies_array->size == 0) { + _mesa_hash_table_remove(copies->ht, ht_entry); + list_add(&cp_arr->node, &state->unused_copy_dynarray_list); + } } lookup_entry_and_kill_aliases_copy_array(state, &copies->arr, deref, write_mask, remove_entry, &entry, &entry_removed); } else { - struct util_dynarray *copies_array = + struct copies_dynarray *cpda = copies_array_for_var(state, copies->ht, deref->_path->path[0]->var); + struct util_dynarray *copies_array = &cpda->arr; lookup_entry_and_kill_aliases_copy_array(state, copies_array, deref, write_mask, remove_entry, &entry, &entry_removed); + + if (copies_array->size == 0) { + _mesa_hash_table_remove_key(copies->ht, deref->_path->path[0]->var); + list_add(&cpda->node, &state->unused_copy_dynarray_list); + } } return entry; @@ -871,12 +883,17 @@ invalidate_copies_for_cf_node(struct copy_prop_var_state *state, struct vars_written *written = ht_entry->data; if (written->modes) { hash_table_foreach(copies->ht, ht_entry) { - struct util_dynarray *copies_array = - &((struct copies_dynarray *) ht_entry->data)->arr; + struct copies_dynarray *cp_arr = ht_entry->data; + struct util_dynarray *copies_array = &cp_arr->arr; util_dynarray_foreach_reverse(copies_array, struct copy_entry, entry) { if (nir_deref_mode_may_be(entry->dst.instr, written->modes)) copy_entry_remove(copies_array, entry, NULL); } + + if (copies_array->size == 0) { + _mesa_hash_table_remove(copies->ht, ht_entry); + list_add(&cp_arr->node, &state->unused_copy_dynarray_list); + } } util_dynarray_foreach_reverse(&copies->arr, struct copy_entry, entry) { @@ -1344,7 +1361,7 @@ static void clear_copies_structure(struct copy_prop_var_state *state, struct copies *copies) { - hash_table_foreach_remove(copies->ht, entry) { + hash_table_foreach(copies->ht, entry) { struct copies_dynarray *cp_arr = (struct copies_dynarray *) entry->data; list_add(&cp_arr->node, &state->unused_copy_dynarray_list);