summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason@jlekstrand.net>2019-08-30 13:55:02 -0500
committerDylan Baker <dylan@pnwbakers.com>2019-09-09 09:13:30 -0700
commit23bc3a401d36ae48b324ebc28a2e69a72c573580 (patch)
tree9c04fa495d7e71a68cfa74fb17b1119559a8bdd7
parent8889cc12412890d1989c71787be666f27c0b5337 (diff)
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 517142252f0c63189293c7176efbf490b7ae95ea)
-rw-r--r--src/compiler/nir/nir_from_ssa.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/compiler/nir/nir_from_ssa.c b/src/compiler/nir/nir_from_ssa.c
index 2ac67b2b997..b5d79b37459 100644
--- a/src/compiler/nir/nir_from_ssa.c
+++ b/src/compiler/nir/nir_from_ssa.c
@@ -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;
}
}
@@ -902,7 +912,7 @@ nir_lower_phis_to_regs_block(nir_block *block)
nir_foreach_phi_src(src, phi) {
assert(src->src.is_ssa);
- 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);