nir: Don't infinitely recurse in lower_ssa_defs_to_regs_block

Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
(cherry picked from commit 517142252f)
[Juan A. Suarez: resolve trivial conflicts]
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>

Conflicts:
	src/compiler/nir/nir_from_ssa.c
This commit is contained in:
Jason Ekstrand 2019-08-30 13:55:02 -05:00 committed by Juan A. Suarez Romero
parent 431f5a8a78
commit 01d452de58

View file

@ -827,7 +827,7 @@ nir_convert_from_ssa(nir_shader *shader, bool phi_webs_only)
static void
place_phi_read(nir_shader *shader, nir_register *reg,
nir_ssa_def *def, nir_block *block)
nir_ssa_def *def, nir_block *block, unsigned depth)
{
if (block != def->parent_instr->block) {
/* Try to go up the single-successor tree */
@ -840,14 +840,24 @@ place_phi_read(nir_shader *shader, nir_register *reg,
}
}
if (all_single_successors) {
if (all_single_successors && depth < 32) {
/* All predecessors of this block have exactly one successor and it
* is this block so they must eventually lead here without
* intersecting each other. Place the reads in the predecessors
* instead of this block.
*
* We only let this function recurse 32 times because it can recurse
* indefinitely in the presence of infinite loops. Because we're
* crawling a single-successor chain, it doesn't matter where we
* place it so it's ok to stop at an arbitrary distance.
*
* TODO: One day, we could detect back edges and avoid the recursion
* that way.
*/
set_foreach(block->predecessors, entry)
place_phi_read(shader, reg, def, (nir_block *)entry->key);
set_foreach(block->predecessors, entry) {
place_phi_read(shader, reg, def, (nir_block *)entry->key,
depth + 1);
}
return;
}
}
@ -904,7 +914,7 @@ nir_lower_phis_to_regs_block(nir_block *block)
assert(src->src.is_ssa);
/* We don't want derefs ending up in phi sources */
assert(!nir_src_as_deref(src->src));
place_phi_read(shader, reg, src->src.ssa, src->pred);
place_phi_read(shader, reg, src->src.ssa, src->pred, 0);
}
nir_instr_remove(&phi->instr);