On Sun, Jan 4, 2015 at 7:24 PM, Connor Abbott <cwabbo...@gmail.com> wrote:
> > > On Tue, Dec 16, 2014 at 1:11 AM, Jason Ekstrand <ja...@jlekstrand.net> > wrote: > >> --- >> src/glsl/Makefile.sources | 1 + >> src/glsl/nir/nir.h | 2 + >> src/glsl/nir/nir_lower_global_vars_to_local.c | 107 >> ++++++++++++++++++++++++++ >> 3 files changed, 110 insertions(+) >> create mode 100644 src/glsl/nir/nir_lower_global_vars_to_local.c >> >> diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources >> index 53c3e98..3f5c0bd 100644 >> --- a/src/glsl/Makefile.sources >> +++ b/src/glsl/Makefile.sources >> @@ -22,6 +22,7 @@ NIR_FILES = \ >> $(GLSL_SRCDIR)/nir/nir_intrinsics.h \ >> $(GLSL_SRCDIR)/nir/nir_live_variables.c \ >> $(GLSL_SRCDIR)/nir/nir_lower_atomics.c \ >> + $(GLSL_SRCDIR)/nir/nir_lower_global_vars_to_local.c \ >> $(GLSL_SRCDIR)/nir/nir_lower_locals_to_regs.c \ >> $(GLSL_SRCDIR)/nir/nir_lower_io.c \ >> $(GLSL_SRCDIR)/nir/nir_lower_samplers.cpp \ >> diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h >> index ec9ce07..30146d6 100644 >> --- a/src/glsl/nir/nir.h >> +++ b/src/glsl/nir/nir.h >> @@ -1358,6 +1358,8 @@ void nir_dump_cfg(nir_shader *shader, FILE *fp); >> >> void nir_split_var_copies(nir_shader *shader); >> >> +void nir_lower_global_vars_to_local(nir_shader *shader); >> + >> void nir_lower_locals_to_regs(nir_shader *shader); >> >> void nir_lower_io(nir_shader *shader); >> diff --git a/src/glsl/nir/nir_lower_global_vars_to_local.c >> b/src/glsl/nir/nir_lower_global_vars_to_local.c >> new file mode 100644 >> index 0000000..ec23a0a >> --- /dev/null >> +++ b/src/glsl/nir/nir_lower_global_vars_to_local.c >> @@ -0,0 +1,107 @@ >> +/* >> + * Copyright © 2014 Intel Corporation >> + * >> + * Permission is hereby granted, free of charge, to any person obtaining >> a >> + * copy of this software and associated documentation files (the >> "Software"), >> + * to deal in the Software without restriction, including without >> limitation >> + * the rights to use, copy, modify, merge, publish, distribute, >> sublicense, >> + * and/or sell copies of the Software, and to permit persons to whom the >> + * Software is furnished to do so, subject to the following conditions: >> + * >> + * The above copyright notice and this permission notice (including the >> next >> + * paragraph) shall be included in all copies or substantial portions of >> the >> + * Software. >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >> EXPRESS OR >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >> MERCHANTABILITY, >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT >> SHALL >> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR >> OTHER >> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, >> ARISING >> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER >> DEALINGS >> + * IN THE SOFTWARE. >> + * >> + * Authors: >> + * Jason Ekstrand (ja...@jlekstrand.net) >> + * >> + */ >> + >> +/* >> + * This lowering pass detects when a global variable is only being used >> by >> + * one function and makes it local to that function >> + */ >> + >> +#include "nir.h" >> + >> +struct global_to_local_state { >> + nir_function_impl *impl; >> + /* A hash table keyed on variable pointers that stores the unique >> + * nir_function_impl that uses the given variable. If a variable is >> + * used in multiple functions, the data for the given key will be >> NULL. >> + */ >> + struct hash_table *var_func_table; >> +}; >> + >> +static bool >> +mark_global_var_uses_block(nir_block *block, void *void_state) >> +{ >> + struct global_to_local_state *state = void_state; >> + >> + nir_foreach_instr(block, instr) { >> + if (instr->type != nir_instr_type_intrinsic) >> + continue; >> + >> + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); >> + unsigned num_vars = >> nir_intrinsic_infos[intrin->intrinsic].num_variables; >> + >> + for (unsigned i = 0; i < num_vars; i++) { >> + nir_variable *var = intrin->variables[i]->var; >> + if (var->data.mode != nir_var_global) >> + continue; >> + >> + uint32_t hash = _mesa_hash_pointer(var); >> + struct hash_entry *entry = >> + _mesa_hash_table_search(state->var_func_table, hash, var); >> + >> + if (entry) { >> + if (entry->data != state->impl) >> + entry->data = NULL; >> + } >> + >> + _mesa_hash_table_insert(state->var_func_table, hash, var, >> state->impl); >> > > I think you should be doing: > > if (entry) { > ... > } else { > _mesa_hash_table_insert(state->var_func_table, hash, var, state->impl); > } > Yup. Fixed. > > >> + } >> + } >> + >> + return true; >> +} >> + >> +void >> +nir_lower_global_vars_to_local(nir_shader *shader) >> +{ >> + struct global_to_local_state state; >> + >> + state.var_func_table = _mesa_hash_table_create(NULL, >> + >> _mesa_key_pointer_equal); >> + >> + nir_foreach_overload(shader, overload) { >> + if (overload->impl) { >> + state.impl = overload->impl; >> + nir_foreach_block(overload->impl, mark_global_var_uses_block, >> &state); >> + } >> + } >> + >> + struct hash_entry *entry; >> + hash_table_foreach(state.var_func_table, entry) { >> + nir_variable *var = (void *)entry->key; >> + nir_function_impl *impl = entry->data; >> + >> + assert(var->data.mode == nir_var_global); >> + >> + if (impl != NULL) { >> + exec_node_remove(&var->node); >> + var->data.mode = nir_var_local; >> + exec_list_push_tail(&impl->locals, &var->node); >> + } >> + } >> + >> + _mesa_hash_table_destroy(state.var_func_table, NULL); >> +} >> -- >> 2.2.0 >> >> _______________________________________________ >> mesa-dev mailing list >> mesa-dev@lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/mesa-dev >> > >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev