Mesa (master): nir/lcssa: fix nondeterminism in predecessor iteration

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Apr 12 18:49:36 UTC 2021


Module: Mesa
Branch: master
Commit: 0f2bf55c7e1d9175dd1254706a46a184958b1f22
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0f2bf55c7e1d9175dd1254706a46a184958b1f22

Author: Rhys Perry <pendingchaos02 at gmail.com>
Date:   Mon Jan 13 14:32:18 2020 +0000

nir/lcssa: fix nondeterminism in predecessor iteration

set_foreach()'s order on a list of nir_block * isn't deterministic, so we
need to sort the predecessor list.

Signed-off-by: Rhys Perry <pendingchaos02 at gmail.com>
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3364>

---

 src/compiler/nir/nir_to_lcssa.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/compiler/nir/nir_to_lcssa.c b/src/compiler/nir/nir_to_lcssa.c
index 9a53e9aeda3..27b9b2635cc 100644
--- a/src/compiler/nir/nir_to_lcssa.c
+++ b/src/compiler/nir/nir_to_lcssa.c
@@ -45,6 +45,8 @@ typedef struct {
 
    /* The loop we store information for */
    nir_loop *loop;
+   nir_block *block_after_loop;
+   nir_block **exit_blocks;
 
    /* Whether to skip loop invariant variables */
    bool skip_invariants;
@@ -201,12 +203,9 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
          return true;
    }
 
-   nir_block *block_after_loop =
-      nir_cf_node_as_block(nir_cf_node_next(&state->loop->cf_node));
-
    nir_foreach_use(use, def) {
       if (use->parent_instr->type == nir_instr_type_phi &&
-          use->parent_instr->block == block_after_loop) {
+          use->parent_instr->block == state->block_after_loop) {
          continue;
       }
 
@@ -233,15 +232,16 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
    /* Create a phi node with as many sources pointing to the same ssa_def as
     * the block has predecessors.
     */
-   set_foreach(block_after_loop->predecessors, entry) {
+   uint32_t num_exits = state->block_after_loop->predecessors->entries;
+   for (uint32_t i = 0; i < num_exits; i++) {
       nir_phi_src *phi_src = ralloc(phi, nir_phi_src);
       phi_src->src = nir_src_for_ssa(def);
-      phi_src->pred = (nir_block *) entry->key;
+      phi_src->pred = state->exit_blocks[i];
 
       exec_list_push_tail(&phi->srcs, &phi_src->node);
    }
 
-   nir_instr_insert_before_block(block_after_loop, &phi->instr);
+   nir_instr_insert_before_block(state->block_after_loop, &phi->instr);
    nir_ssa_def *dest = &phi->dest.ssa;
 
    /* deref instructions need a cast after the phi */
@@ -258,7 +258,7 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
       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);
+      nir_instr_insert(nir_after_phis(state->block_after_loop), &cast->instr);
       dest = &cast->dest.ssa;
    }
 
@@ -267,7 +267,7 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
     */
    nir_foreach_use_safe(use, def) {
       if (use->parent_instr->type == nir_instr_type_phi &&
-          block_after_loop == use->parent_instr->block) {
+          state->block_after_loop == use->parent_instr->block) {
          continue;
       }
 
@@ -286,6 +286,17 @@ convert_loop_exit_for_ssa(nir_ssa_def *def, void *void_state)
    return true;
 }
 
+static void
+setup_loop_state(lcssa_state *state, nir_loop *loop)
+{
+   state->loop = loop;
+   state->block_after_loop =
+      nir_cf_node_as_block(nir_cf_node_next(&loop->cf_node));
+
+   ralloc_free(state->exit_blocks);
+   state->exit_blocks = nir_block_get_predecessors_sorted(state->block_after_loop, state);
+}
+
 static void
 convert_to_lcssa(nir_cf_node *cf_node, lcssa_state *state)
 {
@@ -313,7 +324,7 @@ convert_to_lcssa(nir_cf_node *cf_node, lcssa_state *state)
       foreach_list_typed(nir_cf_node, nested_node, node, &loop->body)
          convert_to_lcssa(nested_node, state);
 
-      state->loop = loop;
+      setup_loop_state(state, loop);
 
       /* mark loop-invariant instructions */
       if (state->skip_invariants) {
@@ -346,9 +357,7 @@ convert_to_lcssa(nir_cf_node *cf_node, lcssa_state *state)
 end:
       /* For outer loops, the LCSSA-phi should be considered not invariant */
       if (state->skip_invariants) {
-         nir_block *block_after_loop =
-            nir_cf_node_as_block(nir_cf_node_next(&state->loop->cf_node));
-         nir_foreach_instr(instr, block_after_loop) {
+         nir_foreach_instr(instr, state->block_after_loop) {
             if (instr->type == nir_instr_type_phi)
                instr->pass_flags = not_invariant;
             else
@@ -370,7 +379,7 @@ nir_convert_loop_to_lcssa(nir_loop *loop)
    nir_metadata_require(impl, nir_metadata_block_index);
 
    lcssa_state *state = rzalloc(NULL, lcssa_state);
-   state->loop = loop;
+   setup_loop_state(state, loop);
    state->shader = impl->function->shader;
    state->skip_invariants = false;
    state->skip_bool_invariants = false;



More information about the mesa-commit mailing list