diff options
author | Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com> | 2020-12-15 23:25:51 -0800 |
---|---|---|
committer | Dylan Baker <dylan.c.baker@intel.com> | 2020-12-18 13:54:48 -0800 |
commit | a46b833725f509ce2b8c2d33ba343ffc108a2339 (patch) | |
tree | 4de6d028047ae28c14fa163b0076b070a3a59a8e | |
parent | d5a9377096a8f4bc16dee075228f64d948522d7e (diff) | |
download | mesa-a46b833725f509ce2b8c2d33ba343ffc108a2339.tar.gz |
nir: Consider pointer initializers in nir_remove_dead_variables
Between the creation of a shader (from GLSL or SPIRV frontends) and
nir_lower_variable_initializers is called, variables may refer to
other variables for initialization. Those referred variables need to
be kept alive, so consider that in the pass.
Fixes: 7acc81056f7 ("compiler/nir: Add support for variable initialization from a pointer")
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8133>
(cherry picked from commit acce4ce04ec1b591b47afeda512a9b554dac14f3)
-rw-r--r-- | .pick_status.json | 2 | ||||
-rw-r--r-- | src/compiler/nir/nir_remove_dead_variables.c | 21 | ||||
-rw-r--r-- | src/compiler/nir/tests/vars_tests.cpp | 48 |
3 files changed, 63 insertions, 8 deletions
diff --git a/.pick_status.json b/.pick_status.json index f3353e615d8..85c13b49fb5 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -31,7 +31,7 @@ "description": "nir: Consider pointer initializers in nir_remove_dead_variables", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": "7acc81056f7ac6a869ef6403573b2572c77dbecf" }, diff --git a/src/compiler/nir/nir_remove_dead_variables.c b/src/compiler/nir/nir_remove_dead_variables.c index 01ea18cc37e..5555ca3f811 100644 --- a/src/compiler/nir/nir_remove_dead_variables.c +++ b/src/compiler/nir/nir_remove_dead_variables.c @@ -67,14 +67,21 @@ add_var_use_deref(nir_deref_instr *deref, struct set *live) if (deref->deref_type != nir_deref_type_var) return; - /* If it's not a local that never escapes the shader, then any access at - * all means we need to keep it alive. + /* Since these local variables don't escape the shader, writing doesn't + * make them live. Only keep them if they are used by some intrinsic. */ - if (!(deref->var->data.mode & (nir_var_function_temp | - nir_var_shader_temp | - nir_var_mem_shared)) || - deref_used_for_not_store(deref)) - _mesa_set_add(live, deref->var); + if ((deref->var->data.mode & (nir_var_function_temp | + nir_var_shader_temp | + nir_var_mem_shared)) && + !deref_used_for_not_store(deref)) + return; + + nir_variable *var = deref->var; + do { + _mesa_set_add(live, var); + /* Also mark the chain of variables used to initialize it. */ + var = var->pointer_initializer; + } while (var); } static void diff --git a/src/compiler/nir/tests/vars_tests.cpp b/src/compiler/nir/tests/vars_tests.cpp index 6d27830cd55..593f183ef9f 100644 --- a/src/compiler/nir/tests/vars_tests.cpp +++ b/src/compiler/nir/tests/vars_tests.cpp @@ -197,6 +197,7 @@ class nir_copy_prop_vars_test : public nir_vars_test {}; class nir_dead_write_vars_test : public nir_vars_test {}; class nir_combine_stores_test : public nir_vars_test {}; class nir_split_vars_test : public nir_vars_test {}; +class nir_remove_dead_variables_test : public nir_vars_test {}; } // namespace @@ -2185,3 +2186,50 @@ TEST_F(nir_split_vars_test, split_wildcard_copy) ASSERT_EQ(count_function_temp_vars(), 8); ASSERT_EQ(count_intrinsics(nir_intrinsic_copy_deref), 4); } + +TEST_F(nir_remove_dead_variables_test, pointer_initializer_used) +{ + nir_variable *x = create_int(nir_var_shader_temp, "x"); + nir_variable *y = create_int(nir_var_shader_temp, "y"); + y->pointer_initializer = x; + nir_variable *out = create_int(nir_var_shader_out, "out"); + + nir_validate_shader(b->shader, NULL); + + nir_copy_var(b, out, y); + + bool progress = nir_remove_dead_variables(b->shader, nir_var_all, NULL); + EXPECT_FALSE(progress); + + nir_validate_shader(b->shader, NULL); + + unsigned count = 0; + nir_foreach_variable_in_shader(var, b->shader) + count++; + + ASSERT_EQ(count, 3); +} + +TEST_F(nir_remove_dead_variables_test, pointer_initializer_dead) +{ + nir_variable *x = create_int(nir_var_shader_temp, "x"); + nir_variable *y = create_int(nir_var_shader_temp, "y"); + nir_variable *z = create_int(nir_var_shader_temp, "z"); + y->pointer_initializer = x; + z->pointer_initializer = y; + + nir_validate_shader(b->shader, NULL); + + bool progress = nir_remove_dead_variables(b->shader, nir_var_all, NULL); + EXPECT_TRUE(progress); + + nir_validate_shader(b->shader, NULL); + + unsigned count = 0; + nir_foreach_variable_in_shader(var, b->shader) + count++; + + ASSERT_EQ(count, 0); +} + + |