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