From: Jason Ekstrand Date: Mon, 20 Jul 2020 21:30:37 +0000 (-0500) Subject: nir: Use a single list for all shader variables X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d70fff99c5bc3a721e20869e7f0be8024ffe5ecd;p=mesa.git nir: Use a single list for all shader variables Instead of having separate lists of variables, roughly sorted by mode, use a single list for all shader-level NIR variables. This makes a few list walks a bit longer here and there but list walks aren't a very common thing in NIR at all. On the other hand, it makes a lot of things like validation, printing, etc. way simpler. Also, there are a number of cases where we move variables from inputs/outputs to globals and this makes it way easier because we no longer have to move them between lists. We only have to deal with that if moving them from the shader to a nir_function_impl. Reviewed-by: Rob Clark Reviewed-By: Mike Blumenkrantz Reviewed-by: Vasily Khoruzhick Part-of: --- diff --git a/src/compiler/glsl/gl_nir_link_uniform_blocks.c b/src/compiler/glsl/gl_nir_link_uniform_blocks.c index 07f1614a40c..1a7fdf35fd2 100644 --- a/src/compiler/glsl/gl_nir_link_uniform_blocks.c +++ b/src/compiler/glsl/gl_nir_link_uniform_blocks.c @@ -417,7 +417,7 @@ allocate_uniform_blocks(void *mem_ctx, *num_variables = 0; *num_blocks = 0; - nir_foreach_variable(var, &shader->Program->nir->uniforms) { + nir_foreach_variable_in_shader(var, shader->Program->nir) { if (block_type == BLOCK_UBO && !nir_variable_is_in_ubo(var)) continue; @@ -557,7 +557,7 @@ link_linked_shader_uniform_blocks(void *mem_ctx, unsigned variable_index = 0; struct gl_uniform_block *blks = *blocks; - nir_foreach_variable(var, &shader->Program->nir->uniforms) { + nir_foreach_variable_in_shader(var, shader->Program->nir) { if (block_type == BLOCK_UBO && !nir_variable_is_in_ubo(var)) continue; diff --git a/src/compiler/glsl/gl_nir_linker.h b/src/compiler/glsl/gl_nir_linker.h index 8240d5f9162..5171a2c68a0 100644 --- a/src/compiler/glsl/gl_nir_linker.h +++ b/src/compiler/glsl/gl_nir_linker.h @@ -36,7 +36,9 @@ struct gl_nir_linker_options { }; #define nir_foreach_gl_uniform_variable(var, shader) \ - nir_foreach_variable(var, &(shader)->uniforms) + nir_foreach_variable_with_modes(var, shader, nir_var_uniform | \ + nir_var_mem_ubo | \ + nir_var_mem_ssbo) bool gl_nir_link_spirv(struct gl_context *ctx, struct gl_shader_program *prog, diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index a9fe16f4069..dc56c4922fc 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -44,10 +44,7 @@ nir_shader_create(void *mem_ctx, { nir_shader *shader = rzalloc(mem_ctx, nir_shader); - exec_list_make_empty(&shader->uniforms); - exec_list_make_empty(&shader->inputs); - exec_list_make_empty(&shader->outputs); - exec_list_make_empty(&shader->shared); + exec_list_make_empty(&shader->variables); shader->options = options; @@ -59,8 +56,6 @@ nir_shader_create(void *mem_ctx, } exec_list_make_empty(&shader->functions); - exec_list_make_empty(&shader->globals); - exec_list_make_empty(&shader->system_values); shader->num_inputs = 0; shader->num_outputs = 0; @@ -104,56 +99,38 @@ nir_reg_remove(nir_register *reg) exec_node_remove(®->node); } -struct exec_list * -nir_variable_list_for_mode(nir_shader *shader, nir_variable_mode mode) +void +nir_shader_add_variable(nir_shader *shader, nir_variable *var) { - switch (mode) { + switch (var->data.mode) { case nir_var_function_temp: assert(!"nir_shader_add_variable cannot be used for local variables"); - return NULL; + return; case nir_var_shader_temp: - return &shader->globals; - case nir_var_shader_in: - return &shader->inputs; - case nir_var_shader_out: - return &shader->outputs; - case nir_var_uniform: case nir_var_mem_ubo: case nir_var_mem_ssbo: - return &shader->uniforms; - case nir_var_mem_shared: - assert(gl_shader_stage_is_compute(shader->info.stage)); - return &shader->shared; + case nir_var_system_value: + break; case nir_var_mem_global: assert(!"nir_shader_add_variable cannot be used for global memory"); - return NULL; - - case nir_var_system_value: - return &shader->system_values; + return; case nir_var_mem_push_const: assert(!"nir_var_push_constant is not supposed to be used for variables"); - return NULL; + return; default: assert(!"invalid mode"); - return NULL; + return; } -} -void -nir_shader_add_variable(nir_shader *shader, nir_variable *var) -{ - struct exec_list *var_list = - nir_variable_list_for_mode(shader, var->data.mode); - if (var_list) - exec_list_push_tail(var_list, &var->node); + exec_list_push_tail(&shader->variables, &var->node); } nir_variable * @@ -1820,35 +1797,12 @@ nir_index_instrs(nir_function_impl *impl) return index; } -static void -index_var_list(struct exec_list *list, unsigned *count) -{ - nir_foreach_variable(var, list) - var->index = (*count)++; -} - unsigned nir_shader_index_vars(nir_shader *shader, nir_variable_mode modes) { unsigned count = 0; - if (modes & nir_var_shader_temp) - index_var_list(&shader->globals, &count); - - if (modes & nir_var_shader_in) - index_var_list(&shader->inputs, &count); - - if (modes & nir_var_shader_out) - index_var_list(&shader->outputs, &count); - - if (modes & (nir_var_uniform | nir_var_mem_ubo | nir_var_mem_ssbo)) - index_var_list(&shader->uniforms, &count); - - if (modes & nir_var_mem_shared) - index_var_list(&shader->shared, &count); - - if (modes & nir_var_system_value) - index_var_list(&shader->system_values, &count); - + nir_foreach_variable_with_modes(var, shader, modes) + var->index = count++; return count; } @@ -1856,7 +1810,8 @@ unsigned nir_function_impl_index_vars(nir_function_impl *impl) { unsigned count = 0; - index_var_list(&impl->locals, &count); + nir_foreach_function_temp_variable(var, impl) + var->index = count++; return count; } diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index f131e0b3f24..b216d293b3e 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -618,7 +618,6 @@ typedef struct nir_variable { struct nir_variable_data *members; } nir_variable; - static inline bool _nir_shader_variable_has_mode(nir_variable *var, unsigned modes) { @@ -627,39 +626,43 @@ _nir_shader_variable_has_mode(nir_variable *var, unsigned modes) return var->data.mode & modes; } -#define nir_foreach_variable(var, var_list) \ +#define nir_foreach_variable_in_list(var, var_list) \ foreach_list_typed(nir_variable, var, node, var_list) -#define nir_foreach_variable_safe(var, var_list) \ +#define nir_foreach_variable_in_list_safe(var, var_list) \ foreach_list_typed_safe(nir_variable, var, node, var_list) +#define nir_foreach_variable_in_shader(var, shader) \ + nir_foreach_variable_in_list(var, &(shader)->variables) + +#define nir_foreach_variable_in_shader_safe(var, shader) \ + nir_foreach_variable_in_list_safe(var, &(shader)->variables) + #define nir_foreach_variable_with_modes(var, shader, modes) \ - nir_foreach_variable(var, nir_variable_list_for_mode(shader, modes)) \ + nir_foreach_variable_in_shader(var, shader) \ if (_nir_shader_variable_has_mode(var, modes)) #define nir_foreach_variable_with_modes_safe(var, shader, modes) \ - nir_foreach_variable_safe(var, nir_variable_list_for_mode(shader, modes)) \ + nir_foreach_variable_in_shader_safe(var, shader) \ if (_nir_shader_variable_has_mode(var, modes)) #define nir_foreach_shader_in_variable(var, shader) \ - nir_foreach_variable(var, &(shader)->inputs) + nir_foreach_variable_with_modes(var, shader, nir_var_shader_in) #define nir_foreach_shader_in_variable_safe(var, shader) \ - nir_foreach_variable_safe(var, &(shader)->inputs) + nir_foreach_variable_with_modes_safe(var, shader, nir_var_shader_in) #define nir_foreach_shader_out_variable(var, shader) \ - nir_foreach_variable(var, &(shader)->outputs) + nir_foreach_variable_with_modes(var, shader, nir_var_shader_out) #define nir_foreach_shader_out_variable_safe(var, shader) \ - nir_foreach_variable_safe(var, &(shader)->outputs) + nir_foreach_variable_with_modes_safe(var, shader, nir_var_shader_out) #define nir_foreach_uniform_variable(var, shader) \ - nir_foreach_variable(var, &(shader)->uniforms) \ - if (var->data.mode == nir_var_uniform) + nir_foreach_variable_with_modes(var, shader, nir_var_uniform) #define nir_foreach_uniform_variable_safe(var, shader) \ - nir_foreach_variable_safe(var, &(shader)->uniforms) \ - if (var->data.mode == nir_var_uniform) + nir_foreach_variable_with_modes_safe(var, shader, nir_var_uniform) static inline bool nir_variable_is_global(const nir_variable *var) @@ -3218,16 +3221,7 @@ typedef struct nir_shader_compiler_options { typedef struct nir_shader { /** list of uniforms (nir_variable) */ - struct exec_list uniforms; - - /** list of inputs (nir_variable) */ - struct exec_list inputs; - - /** list of outputs (nir_variable) */ - struct exec_list outputs; - - /** list of shared compute variables (nir_variable) */ - struct exec_list shared; + struct exec_list variables; /** Set of driver-specific options for the shader. * @@ -3239,12 +3233,6 @@ typedef struct nir_shader { /** Various bits of compile-time information about a given shader */ struct shader_info info; - /** list of global variables in the shader (nir_variable) */ - struct exec_list globals; - - /** list of system value variables in the shader (nir_variable) */ - struct exec_list system_values; - struct exec_list functions; /** < list of nir_function */ /** @@ -3300,9 +3288,6 @@ nir_register *nir_local_reg_create(nir_function_impl *impl); void nir_reg_remove(nir_register *reg); -struct exec_list * -nir_variable_list_for_mode(nir_shader *shader, nir_variable_mode mode); - /** Adds a variable to the appropriate list in nir_shader */ void nir_shader_add_variable(nir_shader *shader, nir_variable *var); diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c index 1aaed566e98..f57fce599c1 100644 --- a/src/compiler/nir/nir_clone.c +++ b/src/compiler/nir/nir_clone.c @@ -728,12 +728,7 @@ nir_shader_clone(void *mem_ctx, const nir_shader *s) nir_shader *ns = nir_shader_create(mem_ctx, s->info.stage, s->options, NULL); state.ns = ns; - clone_var_list(&state, &ns->uniforms, &s->uniforms); - clone_var_list(&state, &ns->inputs, &s->inputs); - clone_var_list(&state, &ns->outputs, &s->outputs); - clone_var_list(&state, &ns->shared, &s->shared); - clone_var_list(&state, &ns->globals, &s->globals); - clone_var_list(&state, &ns->system_values, &s->system_values); + clone_var_list(&state, &ns->variables, &s->variables); /* Go through and clone functions */ foreach_list_typed(nir_function, fxn, node, &s->functions) @@ -796,12 +791,7 @@ nir_shader_replace(nir_shader *dst, nir_shader *src) /* We have to move all the linked lists over separately because we need the * pointers in the list elements to point to the lists in dst and not src. */ - exec_list_move_nodes_to(&src->uniforms, &dst->uniforms); - exec_list_move_nodes_to(&src->inputs, &dst->inputs); - exec_list_move_nodes_to(&src->outputs, &dst->outputs); - exec_list_move_nodes_to(&src->shared, &dst->shared); - exec_list_move_nodes_to(&src->globals, &dst->globals); - exec_list_move_nodes_to(&src->system_values, &dst->system_values); + exec_list_move_nodes_to(&src->variables, &dst->variables); /* Now move the functions over. This takes a tiny bit more work */ exec_list_move_nodes_to(&src->functions, &dst->functions); diff --git a/src/compiler/nir/nir_linking_helpers.c b/src/compiler/nir/nir_linking_helpers.c index 9e6011713ab..e5cd450a014 100644 --- a/src/compiler/nir/nir_linking_helpers.c +++ b/src/compiler/nir/nir_linking_helpers.c @@ -128,9 +128,8 @@ nir_remove_unused_io_vars(nir_shader *shader, uint64_t *used; assert(mode == nir_var_shader_in || mode == nir_var_shader_out); - struct exec_list *var_list = nir_variable_list_for_mode(shader, mode); - nir_foreach_variable_safe(var, var_list) { + nir_foreach_variable_with_modes_safe(var, shader, mode) { if (var->data.patch) used = used_by_other_stage_patches; else @@ -152,9 +151,6 @@ nir_remove_unused_io_vars(nir_shader *shader, var->data.location = 0; var->data.mode = nir_var_shader_temp; - exec_node_remove(&var->node); - exec_list_push_tail(&shader->globals, &var->node); - progress = true; } } @@ -1067,7 +1063,7 @@ nir_link_opt_varyings(nir_shader *producer, nir_shader *consumer) static void insert_sorted(struct exec_list *var_list, nir_variable *new_var) { - nir_foreach_variable(var, var_list) { + nir_foreach_variable_in_list(var, var_list) { if (var->data.location > new_var->data.location) { exec_node_insert_node_before(&var->node, &new_var->node); return; @@ -1100,7 +1096,7 @@ nir_assign_io_var_locations(nir_shader *shader, nir_variable_mode mode, int UNUSED last_loc = 0; bool last_partial = false; - nir_foreach_variable(var, &io_vars) { + nir_foreach_variable_in_list(var, &io_vars) { const struct glsl_type *type = var->type; if (nir_is_per_vertex_io(var, stage) || var->data.per_view) { assert(glsl_type_is_array(type)); @@ -1203,8 +1199,7 @@ nir_assign_io_var_locations(nir_shader *shader, nir_variable_mode mode, if (last_partial) location++; - struct exec_list *var_list = nir_variable_list_for_mode(shader, mode); - exec_list_append(var_list, &io_vars); + exec_list_append(&shader->variables, &io_vars); *size = location; } diff --git a/src/compiler/nir/nir_lower_amul.c b/src/compiler/nir/nir_lower_amul.c index 561cf77af33..52a7d8a2302 100644 --- a/src/compiler/nir/nir_lower_amul.c +++ b/src/compiler/nir/nir_lower_amul.c @@ -235,10 +235,8 @@ nir_lower_amul(nir_shader *shader, /* uniforms list actually includes ubo's and ssbo's: */ int max_slot = 0; - nir_foreach_variable (var, &shader->uniforms) { - if (!(var->data.mode & (nir_var_mem_ubo | nir_var_mem_ssbo))) - continue; - + nir_foreach_variable_with_modes (var, shader, + nir_var_mem_ubo | nir_var_mem_ssbo) { int base = var->data.binding; int size = MAX2(1, glsl_array_size(var->type)); @@ -258,7 +256,7 @@ nir_lower_amul(nir_shader *shader, /* Figure out which UBOs or SSBOs are large enough to be * disqualified from imul24: */ - nir_foreach_variable(var, &shader->uniforms) { + nir_foreach_variable_in_shader (var, shader) { if (var->data.mode == nir_var_mem_ubo) { if (is_large(&state, var)) { state.has_large_ubo = true; diff --git a/src/compiler/nir/nir_lower_clip.c b/src/compiler/nir/nir_lower_clip.c index 3a4775f971b..6e8010cf78b 100644 --- a/src/compiler/nir/nir_lower_clip.c +++ b/src/compiler/nir/nir_lower_clip.c @@ -65,12 +65,7 @@ create_clipdist_var(nir_shader *shader, } else var->type = glsl_vec4_type(); - if (output) { - exec_list_push_tail(&shader->outputs, &var->node); - } - else { - exec_list_push_tail(&shader->inputs, &var->node); - } + nir_shader_add_variable(shader, var); return var; } @@ -245,9 +240,7 @@ lower_clip_outputs(nir_builder *b, nir_variable *position, cv = nir_load_var(b, clipvertex ? clipvertex : position); if (clipvertex) { - exec_node_remove(&clipvertex->node); clipvertex->data.mode = nir_var_shader_temp; - exec_list_push_tail(&b->shader->globals, &clipvertex->node); nir_fixup_deref_modes(b->shader); } } else { diff --git a/src/compiler/nir/nir_lower_global_vars_to_local.c b/src/compiler/nir/nir_lower_global_vars_to_local.c index 563fa3960cc..770c33ca872 100644 --- a/src/compiler/nir/nir_lower_global_vars_to_local.c +++ b/src/compiler/nir/nir_lower_global_vars_to_local.c @@ -83,15 +83,13 @@ nir_lower_global_vars_to_local(nir_shader *shader) } } - nir_foreach_variable_safe(var, &shader->globals) { + nir_foreach_variable_with_modes_safe(var, shader, nir_var_shader_temp) { struct hash_entry *entry = _mesa_hash_table_search(var_func_table, var); if (!entry) continue; nir_function_impl *impl = entry->data; - assert(var->data.mode == nir_var_shader_temp); - if (impl != NULL) { exec_node_remove(&var->node); var->data.mode = nir_var_function_temp; diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c index f8c3fe61535..58c4597c27e 100644 --- a/src/compiler/nir/nir_lower_io.c +++ b/src/compiler/nir/nir_lower_io.c @@ -1470,7 +1470,10 @@ lower_vars_to_explicit(nir_shader *shader, default: unreachable("Unsupported mode"); } - nir_foreach_variable(var, vars) { + nir_foreach_variable_in_list(var, vars) { + if (var->data.mode != mode) + continue; + unsigned size, align; const struct glsl_type *explicit_type = glsl_get_explicit_type_for_size_align(var->type, type_info, &size, &align); @@ -1517,9 +1520,9 @@ nir_lower_vars_to_explicit_types(nir_shader *shader, bool progress = false; if (modes & nir_var_mem_shared) - progress |= lower_vars_to_explicit(shader, &shader->shared, nir_var_mem_shared, type_info); + progress |= lower_vars_to_explicit(shader, &shader->variables, nir_var_mem_shared, type_info); if (modes & nir_var_shader_temp) - progress |= lower_vars_to_explicit(shader, &shader->globals, nir_var_shader_temp, type_info); + progress |= lower_vars_to_explicit(shader, &shader->variables, nir_var_shader_temp, type_info); nir_foreach_function(function, shader) { if (function->impl) { diff --git a/src/compiler/nir/nir_lower_io_to_temporaries.c b/src/compiler/nir/nir_lower_io_to_temporaries.c index ae5f64dcef2..eaeea21f499 100644 --- a/src/compiler/nir/nir_lower_io_to_temporaries.c +++ b/src/compiler/nir/nir_lower_io_to_temporaries.c @@ -312,6 +312,16 @@ create_shadow_temp(struct lower_io_state *state, nir_variable *var) return nvar; } +static void +move_variables_to_list(nir_shader *shader, nir_variable_mode mode, + struct exec_list *dst_list) +{ + nir_foreach_variable_with_modes_safe(var, shader, mode) { + exec_node_remove(&var->node); + exec_list_push_tail(dst_list, &var->node); + } +} + void nir_lower_io_to_temporaries(nir_shader *shader, nir_function_impl *entrypoint, bool outputs, bool inputs) @@ -325,15 +335,13 @@ nir_lower_io_to_temporaries(nir_shader *shader, nir_function_impl *entrypoint, state.entrypoint = entrypoint; state.input_map = _mesa_pointer_hash_table_create(NULL); + exec_list_make_empty(&state.old_inputs); if (inputs) - exec_list_move_nodes_to(&shader->inputs, &state.old_inputs); - else - exec_list_make_empty(&state.old_inputs); + move_variables_to_list(shader, nir_var_shader_in, &state.old_inputs); + exec_list_make_empty(&state.old_outputs); if (outputs) - exec_list_move_nodes_to(&shader->outputs, &state.old_outputs); - else - exec_list_make_empty(&state.old_outputs); + move_variables_to_list(shader, nir_var_shader_out, &state.old_outputs); exec_list_make_empty(&state.new_inputs); exec_list_make_empty(&state.new_outputs); @@ -341,13 +349,13 @@ nir_lower_io_to_temporaries(nir_shader *shader, nir_function_impl *entrypoint, /* Walk over all of the outputs turn each output into a temporary and * make a new variable for the actual output. */ - nir_foreach_variable(var, &state.old_outputs) { + nir_foreach_variable_in_list(var, &state.old_outputs) { nir_variable *output = create_shadow_temp(&state, var); exec_list_push_tail(&state.new_outputs, &output->node); } /* and same for inputs: */ - nir_foreach_variable(var, &state.old_inputs) { + nir_foreach_variable_in_list(var, &state.old_inputs) { nir_variable *input = create_shadow_temp(&state, var); exec_list_push_tail(&state.new_inputs, &input->node); _mesa_hash_table_insert(state.input_map, var, input); @@ -367,10 +375,10 @@ nir_lower_io_to_temporaries(nir_shader *shader, nir_function_impl *entrypoint, nir_metadata_dominance); } - exec_list_append(&shader->inputs, &state.new_inputs); - exec_list_append(&shader->outputs, &state.new_outputs); - exec_list_append(&shader->globals, &state.old_inputs); - exec_list_append(&shader->globals, &state.old_outputs); + exec_list_append(&shader->variables, &state.old_inputs); + exec_list_append(&shader->variables, &state.old_outputs); + exec_list_append(&shader->variables, &state.new_inputs); + exec_list_append(&shader->variables, &state.new_outputs); nir_fixup_deref_modes(shader); diff --git a/src/compiler/nir/nir_lower_system_values.c b/src/compiler/nir/nir_lower_system_values.c index bdc337aecfc..05cf5107d6e 100644 --- a/src/compiler/nir/nir_lower_system_values.c +++ b/src/compiler/nir/nir_lower_system_values.c @@ -328,7 +328,8 @@ nir_lower_system_values(nir_shader *shader) if (progress) nir_remove_dead_derefs(shader); - exec_list_make_empty(&shader->system_values); + nir_foreach_variable_with_modes_safe(var, shader, nir_var_system_value) + exec_node_remove(&var->node); return progress; } diff --git a/src/compiler/nir/nir_lower_variable_initializers.c b/src/compiler/nir/nir_lower_variable_initializers.c index 7b90a196b2d..86252d97511 100644 --- a/src/compiler/nir/nir_lower_variable_initializers.c +++ b/src/compiler/nir/nir_lower_variable_initializers.c @@ -54,13 +54,17 @@ build_constant_load(nir_builder *b, nir_deref_instr *deref, nir_constant *c) } static bool -lower_const_initializer(struct nir_builder *b, struct exec_list *var_list) +lower_const_initializer(struct nir_builder *b, struct exec_list *var_list, + nir_variable_mode modes) { bool progress = false; b->cursor = nir_before_cf_list(&b->impl->body); - nir_foreach_variable(var, var_list) { + nir_foreach_variable_in_list(var, var_list) { + if (!(var->data.mode & modes)) + continue; + if (var->constant_initializer) { build_constant_load(b, nir_build_deref_var(b, var), var->constant_initializer); @@ -107,17 +111,17 @@ nir_lower_variable_initializers(nir_shader *shader, nir_variable_mode modes) nir_builder builder; nir_builder_init(&builder, function->impl); - if ((modes & nir_var_shader_out) && function->is_entrypoint) - impl_progress |= lower_const_initializer(&builder, &shader->outputs); - - if ((modes & nir_var_shader_temp) && function->is_entrypoint) - impl_progress |= lower_const_initializer(&builder, &shader->globals); - - if ((modes & nir_var_system_value) && function->is_entrypoint) - impl_progress |= lower_const_initializer(&builder, &shader->system_values); + if ((modes & ~nir_var_function_temp) && function->is_entrypoint) { + impl_progress |= lower_const_initializer(&builder, + &shader->variables, + modes); + } - if (modes & nir_var_function_temp) - impl_progress |= lower_const_initializer(&builder, &function->impl->locals); + if (modes & nir_var_function_temp) { + impl_progress |= lower_const_initializer(&builder, + &function->impl->locals, + nir_var_function_temp); + } if (impl_progress) { progress = true; diff --git a/src/compiler/nir/nir_opt_access.c b/src/compiler/nir/nir_opt_access.c index 99ecdb5400c..d428e29f6ea 100644 --- a/src/compiler/nir/nir_opt_access.c +++ b/src/compiler/nir/nir_opt_access.c @@ -322,7 +322,9 @@ nir_opt_access(nir_shader *shader) } } - nir_foreach_variable(var, &shader->uniforms) + nir_foreach_variable_with_modes(var, shader, nir_var_uniform | + nir_var_mem_ubo | + nir_var_mem_ssbo) var_progress |= process_variable(&state, var); nir_foreach_function(func, shader) { diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 801744cb966..0e24a68402a 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -936,27 +936,26 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) if (!state->shader) return; - struct exec_list *var_list = NULL; - + nir_variable_mode var_mode; switch (instr->intrinsic) { case nir_intrinsic_load_uniform: - var_list = &state->shader->uniforms; + var_mode = nir_var_uniform; break; case nir_intrinsic_load_input: case nir_intrinsic_load_interpolated_input: case nir_intrinsic_load_per_vertex_input: - var_list = &state->shader->inputs; + var_mode = nir_var_shader_in; break; case nir_intrinsic_load_output: case nir_intrinsic_store_output: case nir_intrinsic_store_per_vertex_output: - var_list = &state->shader->outputs; + var_mode = nir_var_shader_out; break; default: return; } - nir_foreach_variable(var, var_list) { + nir_foreach_variable_with_modes(var, state->shader, var_mode) { if ((var->data.driver_location == nir_intrinsic_base(instr)) && (instr->intrinsic == nir_intrinsic_load_uniform || (nir_intrinsic_component(instr) >= var->data.location_frac && @@ -1519,29 +1518,8 @@ nir_print_shader_annotated(nir_shader *shader, FILE *fp, if (shader->scratch_size) fprintf(fp, "scratch: %u\n", shader->scratch_size); - nir_foreach_variable(var, &shader->uniforms) { + nir_foreach_variable_in_shader(var, shader) print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->inputs) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->outputs) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->shared) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->globals) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->system_values) { - print_var_decl(var, &state); - } foreach_list_typed(nir_function, func, node, &shader->functions) { print_function(func, &state); diff --git a/src/compiler/nir/nir_remove_dead_variables.c b/src/compiler/nir/nir_remove_dead_variables.c index dfeaa249590..5037b862263 100644 --- a/src/compiler/nir/nir_remove_dead_variables.c +++ b/src/compiler/nir/nir_remove_dead_variables.c @@ -148,7 +148,7 @@ remove_dead_vars(struct exec_list *var_list, nir_variable_mode modes, { bool progress = false; - nir_foreach_variable_safe(var, var_list) { + nir_foreach_variable_in_list_safe(var, var_list) { if (!(var->data.mode & modes)) continue; @@ -176,34 +176,9 @@ nir_remove_dead_variables(nir_shader *shader, nir_variable_mode modes, add_var_use_shader(shader, live, modes); - if (modes & nir_var_uniform) { - progress = remove_dead_vars(&shader->uniforms, modes, live, can_remove_var) || - progress; - } - - if (modes & nir_var_shader_in) { - progress = remove_dead_vars(&shader->inputs, modes, live, can_remove_var) || - progress; - } - - if (modes & nir_var_shader_out) { - progress = remove_dead_vars(&shader->outputs, modes, live, can_remove_var) || - progress; - } - - if (modes & nir_var_shader_temp) { - progress = remove_dead_vars(&shader->globals, modes, live, can_remove_var) || - progress; - } - - if (modes & nir_var_system_value) { - progress = remove_dead_vars(&shader->system_values, modes, live, - can_remove_var) || progress; - } - - if (modes & nir_var_mem_shared) { - progress = remove_dead_vars(&shader->shared, modes, live, can_remove_var) || - progress; + if (modes & ~nir_var_function_temp) { + progress = remove_dead_vars(&shader->variables, modes, + live, can_remove_var) || progress; } if (modes & nir_var_function_temp) { diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c index 6688e9e8b17..8baa735def0 100644 --- a/src/compiler/nir/nir_serialize.c +++ b/src/compiler/nir/nir_serialize.c @@ -2013,12 +2013,7 @@ nir_serialize(struct blob *blob, const nir_shader *nir, bool strip) info.name = info.label = NULL; blob_write_bytes(blob, (uint8_t *) &info, sizeof(info)); - write_var_list(&ctx, &nir->uniforms); - write_var_list(&ctx, &nir->inputs); - write_var_list(&ctx, &nir->outputs); - write_var_list(&ctx, &nir->shared); - write_var_list(&ctx, &nir->globals); - write_var_list(&ctx, &nir->system_values); + write_var_list(&ctx, &nir->variables); blob_write_uint32(blob, nir->num_inputs); blob_write_uint32(blob, nir->num_uniforms); @@ -2071,12 +2066,7 @@ nir_deserialize(void *mem_ctx, ctx.nir->info = info; - read_var_list(&ctx, &ctx.nir->uniforms); - read_var_list(&ctx, &ctx.nir->inputs); - read_var_list(&ctx, &ctx.nir->outputs); - read_var_list(&ctx, &ctx.nir->shared); - read_var_list(&ctx, &ctx.nir->globals); - read_var_list(&ctx, &ctx.nir->system_values); + read_var_list(&ctx, &ctx.nir->variables); ctx.nir->num_inputs = blob_read_uint32(blob); ctx.nir->num_uniforms = blob_read_uint32(blob); diff --git a/src/compiler/nir/nir_split_vars.c b/src/compiler/nir/nir_split_vars.c index db320039b93..6aee3109d41 100644 --- a/src/compiler/nir/nir_split_vars.c +++ b/src/compiler/nir/nir_split_vars.c @@ -173,7 +173,7 @@ split_var_list_structs(nir_shader *shader, /* To avoid list confusion (we'll be adding things as we split variables), * pull all of the variables we plan to split off of the list */ - nir_foreach_variable_safe(var, vars) { + nir_foreach_variable_in_list_safe(var, vars) { if (var->data.mode != mode) continue; @@ -193,7 +193,7 @@ split_var_list_structs(nir_shader *shader, exec_list_push_tail(&split_vars, &var->node); } - nir_foreach_variable(var, &split_vars) { + nir_foreach_variable_in_list(var, &split_vars) { state.base_var = var; struct field *root_field = ralloc(mem_ctx, struct field); @@ -308,7 +308,7 @@ nir_split_struct_vars(nir_shader *shader, nir_variable_mode modes) bool has_global_splits = false; if (modes & nir_var_shader_temp) { has_global_splits = split_var_list_structs(shader, NULL, - &shader->globals, + &shader->variables, nir_var_shader_temp, var_field_map, &complex_vars, @@ -382,7 +382,7 @@ init_var_list_array_infos(nir_shader *shader, { bool has_array = false; - nir_foreach_variable(var, vars) { + nir_foreach_variable_in_list(var, vars) { if (var->data.mode != mode) continue; @@ -554,7 +554,7 @@ split_var_list_arrays(nir_shader *shader, struct exec_list split_vars; exec_list_make_empty(&split_vars); - nir_foreach_variable_safe(var, vars) { + nir_foreach_variable_in_list_safe(var, vars) { if (var->data.mode != mode) continue; @@ -601,7 +601,7 @@ split_var_list_arrays(nir_shader *shader, } } - nir_foreach_variable(var, &split_vars) { + nir_foreach_variable_in_list(var, &split_vars) { struct array_var_info *info = get_array_var_info(var, var_info_map); create_split_array_vars(info, 0, &info->root_split, var->name, shader, impl, mem_ctx); @@ -872,7 +872,7 @@ nir_split_array_vars(nir_shader *shader, nir_variable_mode modes) bool has_global_array = false; if (modes & nir_var_shader_temp) { has_global_array = init_var_list_array_infos(shader, - &shader->globals, + &shader->variables, nir_var_shader_temp, var_info_map, &complex_vars, @@ -910,7 +910,7 @@ nir_split_array_vars(nir_shader *shader, nir_variable_mode modes) bool has_global_splits = false; if (modes & nir_var_shader_temp) { has_global_splits = split_var_list_arrays(shader, NULL, - &shader->globals, + &shader->variables, nir_var_shader_temp, var_info_map, mem_ctx); } @@ -1270,7 +1270,7 @@ shrink_vec_var_list(struct exec_list *vars, * Also, if we have a copy that to/from something we can't shrink, we need * to leave components and array_len of any wildcards alone. */ - nir_foreach_variable(var, vars) { + nir_foreach_variable_in_list(var, vars) { if (var->data.mode != mode) continue; @@ -1306,7 +1306,7 @@ shrink_vec_var_list(struct exec_list *vars, bool fp_progress; do { fp_progress = false; - nir_foreach_variable(var, vars) { + nir_foreach_variable_in_list(var, vars) { if (var->data.mode != mode) continue; @@ -1346,7 +1346,7 @@ shrink_vec_var_list(struct exec_list *vars, } while (fp_progress); bool vars_shrunk = false; - nir_foreach_variable_safe(var, vars) { + nir_foreach_variable_in_list_safe(var, vars) { if (var->data.mode != mode) continue; @@ -1618,8 +1618,11 @@ function_impl_has_vars_with_modes(nir_function_impl *impl, { nir_shader *shader = impl->function->shader; - if ((modes & nir_var_shader_temp) && !exec_list_is_empty(&shader->globals)) - return true; + if (modes & ~nir_var_function_temp) { + nir_foreach_variable_with_modes(var, shader, + modes & ~nir_var_function_temp) + return true; + } if ((modes & nir_var_function_temp) && !exec_list_is_empty(&impl->locals)) return true; @@ -1669,7 +1672,7 @@ nir_shrink_vec_array_vars(nir_shader *shader, nir_variable_mode modes) bool globals_shrunk = false; if (modes & nir_var_shader_temp) { - globals_shrunk = shrink_vec_var_list(&shader->globals, + globals_shrunk = shrink_vec_var_list(&shader->variables, nir_var_shader_temp, var_usage_map); } diff --git a/src/compiler/nir/nir_sweep.c b/src/compiler/nir/nir_sweep.c index 56b7a267f64..e2b70f5f767 100644 --- a/src/compiler/nir/nir_sweep.c +++ b/src/compiler/nir/nir_sweep.c @@ -163,12 +163,7 @@ nir_sweep(nir_shader *nir) ralloc_steal(nir, (char *)nir->info.label); /* Variables and registers are not dead. Steal them back. */ - steal_list(nir, nir_variable, &nir->uniforms); - steal_list(nir, nir_variable, &nir->inputs); - steal_list(nir, nir_variable, &nir->outputs); - steal_list(nir, nir_variable, &nir->shared); - steal_list(nir, nir_variable, &nir->globals); - steal_list(nir, nir_variable, &nir->system_values); + steal_list(nir, nir_variable, &nir->variables); /* Recurse into functions, stealing their contents back. */ foreach_list_typed(nir_function, func, node, &nir->functions) { diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 47beec0fa3f..6d498b0b154 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -1288,38 +1288,19 @@ nir_validate_shader(nir_shader *shader, const char *when) state.shader = shader; - exec_list_validate(&shader->uniforms); - nir_foreach_variable(var, &shader->uniforms) { - validate_var_decl(var, nir_var_uniform | - nir_var_mem_ubo | - nir_var_mem_ssbo, - &state); - } - - exec_list_validate(&shader->inputs); - nir_foreach_variable(var, &shader->inputs) { - validate_var_decl(var, nir_var_shader_in, &state); - } - - exec_list_validate(&shader->outputs); - nir_foreach_variable(var, &shader->outputs) { - validate_var_decl(var, nir_var_shader_out, &state); - } - - exec_list_validate(&shader->shared); - nir_foreach_variable(var, &shader->shared) { - validate_var_decl(var, nir_var_mem_shared, &state); - } - - exec_list_validate(&shader->globals); - nir_foreach_variable(var, &shader->globals) { - validate_var_decl(var, nir_var_shader_temp, &state); - } - - exec_list_validate(&shader->system_values); - nir_foreach_variable(var, &shader->system_values) { - validate_var_decl(var, nir_var_system_value, &state); - } + nir_variable_mode valid_modes = + nir_var_shader_in | + nir_var_shader_out | + nir_var_shader_temp | + nir_var_uniform | + nir_var_mem_ubo | + nir_var_system_value | + nir_var_mem_ssbo | + nir_var_mem_shared; + + exec_list_validate(&shader->variables); + nir_foreach_variable_in_shader(var, shader) + validate_var_decl(var, valid_modes, &state); exec_list_validate(&shader->functions); foreach_list_typed(nir_function, func, node, &shader->functions) { diff --git a/src/compiler/nir/tests/vars_tests.cpp b/src/compiler/nir/tests/vars_tests.cpp index 5f17ce0920f..6d27830cd55 100644 --- a/src/compiler/nir/tests/vars_tests.cpp +++ b/src/compiler/nir/tests/vars_tests.cpp @@ -81,7 +81,10 @@ protected: } unsigned count_shader_temp_vars(void) { - return exec_list_length(&b->shader->globals); + unsigned count = 0; + nir_foreach_variable_with_modes(var, b->shader, nir_var_shader_temp) + count++; + return count; } nir_intrinsic_instr *get_intrinsic(nir_intrinsic_op intrinsic, diff --git a/src/freedreno/ir3/ir3_nir_lower_tess.c b/src/freedreno/ir3/ir3_nir_lower_tess.c index 86aaa17f7e4..44b2921dcb7 100644 --- a/src/freedreno/ir3/ir3_nir_lower_tess.c +++ b/src/freedreno/ir3/ir3_nir_lower_tess.c @@ -41,6 +41,7 @@ struct state { nir_variable *vertex_flags_out; struct exec_list old_outputs; + struct exec_list new_outputs; struct exec_list emit_outputs; /* tess ctrl shader on a650 gets the local primitive id at different bits: */ @@ -830,14 +831,19 @@ ir3_nir_lower_gs(nir_shader *shader) * we copy the emit_outputs to the real outputs, so that we get * store_output in uniform control flow. */ - exec_list_move_nodes_to(&shader->outputs, &state.old_outputs); + exec_list_make_empty(&state.old_outputs); + nir_foreach_shader_out_variable_safe(var, shader) { + exec_node_remove(&var->node); + exec_list_push_tail(&state.old_outputs, &var->node); + } + exec_list_make_empty(&state.new_outputs); exec_list_make_empty(&state.emit_outputs); - nir_foreach_variable(var, &state.old_outputs) { + nir_foreach_variable_in_list(var, &state.old_outputs) { /* Create a new output var by cloning the original output var and * stealing the name. */ nir_variable *output = nir_variable_clone(var, shader); - exec_list_push_tail(&shader->outputs, &output->node); + exec_list_push_tail(&state.new_outputs, &output->node); /* Rewrite the original output to be a shadow variable. */ var->name = ralloc_asprintf(var, "%s@gs-temp", output->name); @@ -883,15 +889,16 @@ ir3_nir_lower_gs(nir_shader *shader) nir_builder_instr_insert(&b, &discard_if->instr); - foreach_two_lists(dest_node, &shader->outputs, src_node, &state.emit_outputs) { + foreach_two_lists(dest_node, &state.new_outputs, src_node, &state.emit_outputs) { nir_variable *dest = exec_node_data(nir_variable, dest_node, node); nir_variable *src = exec_node_data(nir_variable, src_node, node); nir_copy_var(&b, dest, src); } } - exec_list_append(&shader->globals, &state.old_outputs); - exec_list_append(&shader->globals, &state.emit_outputs); + exec_list_append(&shader->variables, &state.old_outputs); + exec_list_append(&shader->variables, &state.emit_outputs); + exec_list_append(&shader->variables, &state.new_outputs); nir_metadata_preserve(impl, 0); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index dafc39911f2..15451af4c48 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -67,7 +67,7 @@ static void dump_info(struct ir3_shader_variant *so, const char *str) static void insert_sorted(struct exec_list *var_list, nir_variable *new_var) { - nir_foreach_variable(var, var_list) { + nir_foreach_variable_in_list(var, var_list) { if (var->data.location > new_var->data.location) { exec_node_insert_node_before(&var->node, &new_var->node); return; @@ -85,7 +85,7 @@ sort_varyings(nir_shader *nir, nir_variable_mode mode) exec_node_remove(&var->node); insert_sorted(&new_list, var); } - exec_list_move_nodes_to(&new_list, var_list); + exec_list_append(&nir->variables, &new_list); } static void diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c index 0640828ca2c..f6c2ab67518 100644 --- a/src/gallium/drivers/iris/iris_program.c +++ b/src/gallium/drivers/iris/iris_program.c @@ -286,9 +286,7 @@ iris_fix_edge_flags(nir_shader *nir) return false; } - exec_node_remove(&var->node); var->data.mode = nir_var_shader_temp; - exec_list_push_tail(&nir->globals, &var->node); nir->info.outputs_written &= ~VARYING_BIT_EDGE; nir->info.inputs_read &= ~VERT_BIT_EDGEFLAG; nir_fixup_deref_modes(nir); diff --git a/src/gallium/drivers/lima/standalone/lima_compiler_cmdline.c b/src/gallium/drivers/lima/standalone/lima_compiler_cmdline.c index a9d1fba440b..f510e731052 100644 --- a/src/gallium/drivers/lima/standalone/lima_compiler_cmdline.c +++ b/src/gallium/drivers/lima/standalone/lima_compiler_cmdline.c @@ -48,7 +48,7 @@ print_usage(void) static void insert_sorted(struct exec_list *var_list, nir_variable *new_var) { - nir_foreach_variable(var, var_list) { + nir_foreach_variable_in_list(var, var_list) { if (var->data.location > new_var->data.location && new_var->data.location >= 0) { exec_node_insert_node_before(&var->node, &new_var->node); @@ -67,7 +67,7 @@ sort_varyings(nir_shader *nir, nir_variable_mode mode) exec_node_remove(&var->node); insert_sorted(&new_list, var); } - exec_list_move_nodes_to(&new_list, var_list); + exec_list_append(&nir->variables, &new_list); } static void diff --git a/src/gallium/drivers/r600/sfn/sfn_nir.cpp b/src/gallium/drivers/r600/sfn/sfn_nir.cpp index 250c9e7d2cf..d65a1c92dcf 100644 --- a/src/gallium/drivers/r600/sfn/sfn_nir.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_nir.cpp @@ -282,7 +282,9 @@ bool ShaderFromNir::process_declaration() } // scan declarations - nir_foreach_variable(variable, &sh->uniforms) { + nir_foreach_variable_with_modes(variable, sh, nir_var_uniform | + nir_var_mem_ubo | + nir_var_mem_ssbo) { if (!impl->process_uniforms(variable)) { fprintf(stderr, "R600: error parsing outputs varible %s\n", variable->name); return false; diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index 9fad2bbd433..68a5d00a350 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -2313,7 +2313,9 @@ nir_to_spirv(struct nir_shader *s, const struct pipe_stream_output_info *so_info if (so_info) emit_so_info(&ctx, util_last_bit64(s->info.outputs_written), so_info, local_so_info); - nir_foreach_variable(var, &s->uniforms) + nir_foreach_variable_with_modes(var, s, nir_var_uniform | + nir_var_mem_ubo | + nir_var_mem_ssbo) emit_uniform(&ctx, var); if (s->info.stage == MESA_SHADER_FRAGMENT) { diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 865e1409ff7..4154f79c40e 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -242,7 +242,8 @@ zink_compile_nir(struct zink_screen *screen, struct nir_shader *nir, } ret->num_bindings = 0; - nir_foreach_variable(var, &nir->uniforms) { + nir_foreach_variable_with_modes(var, nir, nir_var_uniform | + nir_var_mem_ubo) { if (var->data.mode == nir_var_mem_ubo) { int binding = zink_binding(nir->info.stage, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, diff --git a/src/intel/blorp/blorp.c b/src/intel/blorp/blorp.c index c3181a19e6c..681c8f1cc0c 100644 --- a/src/intel/blorp/blorp.c +++ b/src/intel/blorp/blorp.c @@ -180,7 +180,6 @@ blorp_compile_fs(struct blorp_context *blorp, void *mem_ctx, memset(wm_prog_data, 0, sizeof(*wm_prog_data)); - assert(exec_list_is_empty(&nir->uniforms)); wm_prog_data->base.nr_params = 0; wm_prog_data->base.param = NULL; diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 8b8a108b3dd..2b3e0c9ef37 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -117,14 +117,12 @@ st_nir_assign_vs_in_locations(struct nir_shader *nir) util_bitcount64(nir->info.inputs_read & BITFIELD64_MASK(var->data.location)); } else { - /* Move unused input variables to the globals list (with no + /* Convert unused input variables to shader_temp (with no * initialization), to avoid confusing drivers looking through the * inputs array and expecting to find inputs with a driver_location * set. */ - exec_node_remove(&var->node); var->data.mode = nir_var_shader_temp; - exec_list_push_tail(&nir->globals, &var->node); removed_inputs = true; } }