summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2020-07-15 20:12:33 -0500
committerMarge Bot <eric+marge@anholt.net>2020-08-19 19:43:31 +0000
commitdf9596353a60bd38bc0185501750a7f4da5a06c5 (patch)
treec070da5cb51f0b96e930c5ddb4860c178b0e409b
parent9f3c595dfc4cd1745e10698f0c037a7f32b63789 (diff)
nir/large_constants: Handle incomplete derefs
This pass works entirely with variables, all we have to do is ignore any derefs we see which we can't chase back to the variable. The one interesting case we have to handle is if we have a complex use of a deref_var. In that case, we have to flag it non-constant. Reviewed-by: Jesse Natalie <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6210>
-rw-r--r--src/compiler/nir/nir_opt_large_constants.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_opt_large_constants.c b/src/compiler/nir/nir_opt_large_constants.c
index 25c40292033..53bcea9322a 100644
--- a/src/compiler/nir/nir_opt_large_constants.c
+++ b/src/compiler/nir/nir_opt_large_constants.c
@@ -199,6 +199,19 @@ nir_opt_large_constants(nir_shader *shader,
*/
nir_foreach_block(block, impl) {
nir_foreach_instr(instr, block) {
+ if (instr->type == nir_instr_type_deref) {
+ /* If we ever see a complex use of a deref_var, we have to assume
+ * that variable is non-constant because we can't guarantee we
+ * will find all of the writers of that variable.
+ */
+ nir_deref_instr *deref = nir_instr_as_deref(instr);
+ if (deref->type == nir_deref_type_var &&
+ deref->mode == nir_var_function_temp &&
+ nir_deref_instr_has_complex_use(deref))
+ var_infos[deref->var->index].is_constant = false;
+ continue;
+ }
+
if (instr->type != nir_instr_type_intrinsic)
continue;
@@ -228,6 +241,9 @@ nir_opt_large_constants(nir_shader *shader,
if (dst_deref && dst_deref->mode == nir_var_function_temp) {
nir_variable *var = nir_deref_instr_get_variable(dst_deref);
+ if (var == NULL)
+ continue;
+
assert(var->data.mode == nir_var_function_temp);
struct var_info *info = &var_infos[var->index];
@@ -253,6 +269,9 @@ nir_opt_large_constants(nir_shader *shader,
if (src_deref && src_deref->mode == nir_var_function_temp) {
nir_variable *var = nir_deref_instr_get_variable(src_deref);
+ if (var == NULL)
+ continue;
+
assert(var->data.mode == nir_var_function_temp);
/* We only consider variables constant if all the reads are
@@ -334,6 +353,9 @@ nir_opt_large_constants(nir_shader *shader,
continue;
nir_variable *var = nir_deref_instr_get_variable(deref);
+ if (var == NULL)
+ continue;
+
struct var_info *info = &var_infos[var->index];
if (info->is_constant) {
b.cursor = nir_after_instr(&intrin->instr);
@@ -352,6 +374,9 @@ nir_opt_large_constants(nir_shader *shader,
continue;
nir_variable *var = nir_deref_instr_get_variable(deref);
+ if (var == NULL)
+ continue;
+
struct var_info *info = &var_infos[var->index];
if (info->is_constant) {
nir_instr_remove(&intrin->instr);