Module: Mesa Branch: master Commit: 0f2bf55c7e1d9175dd1254706a46a184958b1f22 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0f2bf55c7e1d9175dd1254706a46a184958b1f22
Author: Rhys Perry <[email protected]> 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 <[email protected]> Reviewed-by: Jason Ekstrand <[email protected]> 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; _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
