bool nir_deref_instr_has_indirect(nir_deref_instr *instr);
bool nir_deref_instr_is_known_out_of_bounds(nir_deref_instr *instr);
-bool nir_deref_instr_has_complex_use(nir_deref_instr *instr);
+
+typedef enum {
+ nir_deref_instr_has_complex_use_allow_memcpy_src = (1 << 0),
+ nir_deref_instr_has_complex_use_allow_memcpy_dst = (1 << 1),
+} nir_deref_instr_has_complex_use_options;
+
+bool nir_deref_instr_has_complex_use(nir_deref_instr *instr,
+ nir_deref_instr_has_complex_use_options opts);
bool nir_deref_instr_remove_if_unused(nir_deref_instr *instr);
}
bool
-nir_deref_instr_has_complex_use(nir_deref_instr *deref)
+nir_deref_instr_has_complex_use(nir_deref_instr *deref,
+ nir_deref_instr_has_complex_use_options opts)
{
nir_foreach_use(use_src, &deref->dest.ssa) {
nir_instr *use_instr = use_src->parent_instr;
use_deref->deref_type != nir_deref_type_array)
return true;
- if (nir_deref_instr_has_complex_use(use_deref))
+ if (nir_deref_instr_has_complex_use(use_deref, opts))
return true;
continue;
continue;
return true;
+ case nir_intrinsic_memcpy_deref:
+ if (use_src == &use_intrin->src[0] &&
+ (opts & nir_deref_instr_has_complex_use_allow_memcpy_dst))
+ continue;
+ if (use_src == &use_intrin->src[1] &&
+ (opts & nir_deref_instr_has_complex_use_allow_memcpy_src))
+ continue;
+ return true;
+
default:
return true;
}
nir_deref_instr *deref = nir_instr_as_deref(instr);
if (deref->deref_type == nir_deref_type_var &&
deref->var->data.mode == nir_var_function_temp &&
- nir_deref_instr_has_complex_use(deref))
+ nir_deref_instr_has_complex_use(deref, 0))
var_infos[deref->var->index].is_constant = false;
continue;
}
nir_deref_instr *deref = nir_instr_as_deref(instr);
if (deref->deref_type == nir_deref_type_var &&
- nir_deref_instr_has_complex_use(deref))
+ nir_deref_instr_has_complex_use(deref, 0))
register_complex_use(deref, state);
break;
nir_deref_instr *deref = nir_instr_as_deref(instr);
if (deref->deref_type == nir_deref_type_var &&
deref->var->data.mode == nir_var_function_temp &&
- nir_deref_instr_has_complex_use(deref))
+ nir_deref_instr_has_complex_use(deref, 0))
var_infos[deref->var->index].is_constant = false;
continue;
}
* nir_deref_instr_has_complex_use is recursive.
*/
if (deref->deref_type == nir_deref_type_var &&
- nir_deref_instr_has_complex_use(deref))
+ nir_deref_instr_has_complex_use(deref, 0))
_mesa_set_add(complex_vars, deref->var);
}
}
if (!(deref->var->data.mode & modes))
return;
- if (!nir_deref_instr_has_complex_use(deref))
+ if (!nir_deref_instr_has_complex_use(deref, 0))
return;
struct vec_var_usage *usage =