mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-12 23:00:16 +01:00
nir/lcssa: handle deref instructions properly
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Fixes: 414148cdc1 "nir: Support deref instructions in loop_analyze"
This commit is contained in:
parent
7c56a68c8b
commit
204846ad06
2 changed files with 26 additions and 14 deletions
|
|
@ -216,17 +216,15 @@ nir_deref_instr_has_complex_use(nir_deref_instr *deref)
|
|||
unsigned
|
||||
nir_deref_instr_ptr_as_array_stride(nir_deref_instr *deref)
|
||||
{
|
||||
assert(deref->deref_type == nir_deref_type_ptr_as_array);
|
||||
nir_deref_instr *parent = nir_deref_instr_parent(deref);
|
||||
switch (parent->deref_type) {
|
||||
switch (deref->deref_type) {
|
||||
case nir_deref_type_array:
|
||||
return glsl_get_explicit_stride(nir_deref_instr_parent(parent)->type);
|
||||
return glsl_get_explicit_stride(nir_deref_instr_parent(deref)->type);
|
||||
case nir_deref_type_ptr_as_array:
|
||||
return nir_deref_instr_ptr_as_array_stride(parent);
|
||||
return nir_deref_instr_ptr_as_array_stride(nir_deref_instr_parent(deref));
|
||||
case nir_deref_type_cast:
|
||||
return parent->cast.ptr_stride;
|
||||
return deref->cast.ptr_stride;
|
||||
default:
|
||||
unreachable("Invalid parent for ptr_as_array deref");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,9 +111,6 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
|
|||
if (all_uses_inside_loop)
|
||||
return true;
|
||||
|
||||
/* We don't want derefs ending up in phi sources */
|
||||
assert(def->parent_instr->type != nir_instr_type_deref);
|
||||
|
||||
/* Initialize a phi-instruction */
|
||||
nir_phi_instr *phi = nir_phi_instr_create(state->shader);
|
||||
nir_ssa_dest_init(&phi->instr, &phi->dest,
|
||||
|
|
@ -131,6 +128,25 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
|
|||
}
|
||||
|
||||
nir_instr_insert_before_block(block_after_loop, &phi->instr);
|
||||
nir_ssa_def *dest = &phi->dest.ssa;
|
||||
|
||||
/* deref instructions need a cast after the phi */
|
||||
if (def->parent_instr->type == nir_instr_type_deref) {
|
||||
nir_deref_instr *cast =
|
||||
nir_deref_instr_create(state->shader, nir_deref_type_cast);
|
||||
|
||||
nir_deref_instr *instr = nir_instr_as_deref(def->parent_instr);
|
||||
cast->mode = instr->mode;
|
||||
cast->type = instr->type;
|
||||
cast->parent = nir_src_for_ssa(&phi->dest.ssa);
|
||||
cast->cast.ptr_stride = nir_deref_instr_ptr_as_array_stride(instr);
|
||||
|
||||
nir_ssa_dest_init(&cast->instr, &cast->dest,
|
||||
phi->dest.ssa.num_components,
|
||||
phi->dest.ssa.bit_size, NULL);
|
||||
nir_instr_insert(nir_after_phis(block_after_loop), &cast->instr);
|
||||
dest = &cast->dest.ssa;
|
||||
}
|
||||
|
||||
/* Run through all uses and rewrite those outside the loop to point to
|
||||
* the phi instead of pointing to the ssa-def.
|
||||
|
|
@ -142,15 +158,13 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
|
|||
}
|
||||
|
||||
if (!is_use_inside_loop(use, state->loop)) {
|
||||
nir_instr_rewrite_src(use->parent_instr, use,
|
||||
nir_src_for_ssa(&phi->dest.ssa));
|
||||
nir_instr_rewrite_src(use->parent_instr, use, nir_src_for_ssa(dest));
|
||||
}
|
||||
}
|
||||
|
||||
nir_foreach_if_use_safe(use, def) {
|
||||
if (!is_if_use_inside_loop(use, state->loop)) {
|
||||
nir_if_rewrite_condition(use->parent_if,
|
||||
nir_src_for_ssa(&phi->dest.ssa));
|
||||
nir_if_rewrite_condition(use->parent_if, nir_src_for_ssa(dest));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue