Signed-off-by: Jason Ekstrand <ja...@jlekstrand.net> Cc: "12.0" <mesa-sta...@lists.freedesktop.org> Cc: Connor Abbott <cwabbo...@gmail.com> --- src/compiler/nir/nir_inline_functions.c | 41 +++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-)
diff --git a/src/compiler/nir/nir_inline_functions.c b/src/compiler/nir/nir_inline_functions.c index c36748d..5e7382a 100644 --- a/src/compiler/nir/nir_inline_functions.c +++ b/src/compiler/nir/nir_inline_functions.c @@ -25,6 +25,19 @@ #include "nir_builder.h" #include "nir_control_flow.h" +static bool +deref_apply_constant_initializer(nir_deref_var *deref, void *state) +{ + struct nir_builder *b = state; + + nir_load_const_instr *initializer = + nir_deref_get_const_initializer_load(b->shader, deref); + + nir_store_deref_var(b, deref, &initializer->def, 0xf); + + return true; +} + static bool inline_function_impl(nir_function_impl *impl, struct set *inlined); static void @@ -174,11 +187,35 @@ inline_functions_block(nir_block *block, nir_builder *b, /* Add copies of all in parameters */ assert(call->num_params == callee_copy->num_params); + b->cursor = nir_before_instr(&call->instr); + + /* Before we insert the copy of the function, we need to lower away + * constant initializers on local variables. This is because constant + * initializers happen (effectively) at the top of the function and, + * since these are about to become locals of the calling function, + * initialization will happen at the top of the caller rather than at + * the top of the callee. This isn't usually a problem, but if we are + * being inlined inside of a loop, it can result in the variable not + * getting re-initizlied properly for all loop iterations. + */ + nir_foreach_variable(local, &callee_copy->locals) { + if (!local->constant_initializer) + continue; + + nir_deref_var deref; + deref.deref.deref_type = nir_deref_type_var, + deref.deref.child = NULL; + deref.deref.type = local->type, + deref.var = local; + + nir_deref_foreach_leaf(&deref, deref_apply_constant_initializer, b); + + local->constant_initializer = NULL; + } + exec_list_append(&b->impl->locals, &callee_copy->locals); exec_list_append(&b->impl->registers, &callee_copy->registers); - b->cursor = nir_before_instr(&call->instr); - /* We now need to tie the two functions together using the * parameters. There are two ways we do this: One is to turn the * parameter into a local variable and do a shadow-copy. The other -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev