mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-27 04:04:23 +08:00
nir/lcssa: Fix rematerializing derefs
This would pull derefs out of loops by emitting the pattern `deref(phi(deref))` which is not allowed by nir_validate. Reviewed-by: Rhys Perry <pendingchaos02@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23712>
This commit is contained in:
parent
29dc1b193a
commit
439e8c42cc
@ -223,6 +223,11 @@ convert_loop_exit_for_ssa(nir_def *def, void *void_state)
|
||||
if (all_uses_inside_loop)
|
||||
return true;
|
||||
|
||||
if (def->parent_instr->type == nir_instr_type_deref) {
|
||||
nir_rematerialize_deref_in_use_blocks(nir_instr_as_deref(def->parent_instr));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Initialize a phi-instruction */
|
||||
nir_phi_instr *phi = nir_phi_instr_create(state->shader);
|
||||
nir_def_init(&phi->instr, &phi->def, def->num_components,
|
||||
@ -239,23 +244,6 @@ convert_loop_exit_for_ssa(nir_def *def, void *void_state)
|
||||
nir_instr_insert_before_block(state->block_after_loop, &phi->instr);
|
||||
nir_def *dest = &phi->def;
|
||||
|
||||
/* 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->modes = instr->modes;
|
||||
cast->type = instr->type;
|
||||
cast->parent = nir_src_for_ssa(&phi->def);
|
||||
cast->cast.ptr_stride = nir_deref_instr_array_stride(instr);
|
||||
|
||||
nir_def_init(&cast->instr, &cast->def,
|
||||
phi->def.num_components, phi->def.bit_size);
|
||||
nir_instr_insert(nir_after_phis(state->block_after_loop), &cast->instr);
|
||||
dest = &cast->def;
|
||||
}
|
||||
|
||||
/* Run through all uses and rewrite those outside the loop to point to
|
||||
* the phi instead of pointing to the ssa-def.
|
||||
*/
|
||||
@ -340,8 +328,8 @@ convert_to_lcssa(nir_cf_node *cf_node, lcssa_state *state)
|
||||
}
|
||||
}
|
||||
|
||||
nir_foreach_block_in_cf_node(block, cf_node) {
|
||||
nir_foreach_instr(instr, block) {
|
||||
nir_foreach_block_in_cf_node_reverse(block, cf_node) {
|
||||
nir_foreach_instr_reverse_safe(instr, block) {
|
||||
nir_foreach_def(instr, convert_loop_exit_for_ssa, state);
|
||||
|
||||
/* for outer loops, invariant instructions can be variant */
|
||||
@ -381,8 +369,8 @@ nir_convert_loop_to_lcssa(nir_loop *loop)
|
||||
state->skip_invariants = false;
|
||||
state->skip_bool_invariants = false;
|
||||
|
||||
nir_foreach_block_in_cf_node(block, &loop->cf_node) {
|
||||
nir_foreach_instr(instr, block)
|
||||
nir_foreach_block_in_cf_node_reverse(block, &loop->cf_node) {
|
||||
nir_foreach_instr_reverse_safe(instr, block)
|
||||
nir_foreach_def(instr, convert_loop_exit_for_ssa, state);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user