From aa6bdbd54a4c824661e4b65eb4fc6a357058f778 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 11 May 2023 13:20:43 -0400 Subject: [PATCH] nir: Use nir_foreach_phi(_safe) The pattern shows up all the time open-coded. Use the macro instead. Signed-off-by: Alyssa Rosenzweig Reviewed-by: Konstantin Seurer Reviewed-by: Jesse Natalie Part-of: --- src/compiler/nir/nir.c | 6 +--- src/compiler/nir/nir.h | 9 ++--- src/compiler/nir/nir_control_flow.c | 29 ++++------------ src/compiler/nir/nir_divergence_analysis.c | 34 +++++-------------- src/compiler/nir/nir_from_ssa.c | 30 +++------------- src/compiler/nir/nir_liveness.c | 12 ++----- src/compiler/nir/nir_lower_phis_to_scalar.c | 16 +++------ src/compiler/nir/nir_lower_shader_calls.c | 7 +--- .../nir/nir_opt_conditional_discard.c | 6 +--- src/compiler/nir/nir_opt_dead_cf.c | 8 ++--- src/compiler/nir/nir_opt_if.c | 24 ++++--------- src/compiler/nir/nir_opt_peephole_select.c | 6 +--- src/compiler/nir/nir_opt_phi_precision.c | 8 ++--- src/compiler/nir/nir_opt_remove_phis.c | 9 ++--- src/compiler/nir/nir_validate.c | 7 ++-- 15 files changed, 48 insertions(+), 163 deletions(-) diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 6ba22c7332e..08354cc3aeb 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -1496,11 +1496,7 @@ nir_foreach_phi_src_leaving_block(nir_block *block, if (block->successors[i] == NULL) continue; - nir_foreach_instr(instr, block->successors[i]) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi(phi, block->successors[i]) { nir_foreach_phi_src(phi_src, phi) { if (phi_src->pred == block) { if (!cb(&phi_src->src, state)) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 45edbaaa619..c1c324b85e4 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2916,12 +2916,9 @@ static inline nir_phi_instr * nir_block_last_phi_instr(nir_block *block) { nir_phi_instr *last_phi = NULL; - nir_foreach_instr(instr, block) { - if (instr->type == nir_instr_type_phi) - last_phi = nir_instr_as_phi(instr); - else - return last_phi; - } + nir_foreach_phi(instr, block) + last_phi = instr; + return last_phi; } diff --git a/src/compiler/nir/nir_control_flow.c b/src/compiler/nir/nir_control_flow.c index 79f7ea7ea7d..aafbdd136f9 100644 --- a/src/compiler/nir/nir_control_flow.c +++ b/src/compiler/nir/nir_control_flow.c @@ -197,13 +197,10 @@ split_block_beginning(nir_block *block) /* Any phi nodes must stay part of the new block, or else their * sources will be messed up. */ - nir_foreach_instr_safe(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - exec_node_remove(&instr->node); - instr->block = new_block; - exec_list_push_tail(&new_block->instr_list, &instr->node); + nir_foreach_phi_safe(phi, block) { + exec_node_remove(&phi->instr.node); + phi->instr.block = new_block; + exec_list_push_tail(&new_block->instr_list, &phi->instr.node); } return new_block; @@ -212,11 +209,7 @@ split_block_beginning(nir_block *block) static void rewrite_phi_preds(nir_block *block, nir_block *old_pred, nir_block *new_pred) { - nir_foreach_instr_safe(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi_safe(phi, block) { nir_foreach_phi_src(src, phi) { if (src->pred == old_pred) { src->pred = new_pred; @@ -230,11 +223,7 @@ void nir_insert_phi_undef(nir_block *block, nir_block *pred) { nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node); - nir_foreach_instr(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi(phi, block) { nir_ssa_undef_instr *undef = nir_ssa_undef_instr_create(impl->function->shader, phi->dest.ssa.num_components, @@ -476,11 +465,7 @@ nir_loop_remove_continue_construct(nir_loop *loop) static void remove_phi_src(nir_block *block, nir_block *pred) { - nir_foreach_instr(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi(phi, block) { nir_foreach_phi_src_safe(src, phi) { if (src->pred == pred) { list_del(&src->src.use_link); diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c index 2197d16cf91..d749733a992 100644 --- a/src/compiler/nir/nir_divergence_analysis.c +++ b/src/compiler/nir/nir_divergence_analysis.c @@ -1032,14 +1032,10 @@ visit_if(nir_if *if_stmt, struct divergence_state *state) progress |= visit_cf_list(&if_stmt->else_list, &else_state); /* handle phis after the IF */ - nir_foreach_instr(instr, nir_cf_node_cf_tree_next(&if_stmt->cf_node)) { - if (instr->type != nir_instr_type_phi) - break; - + nir_foreach_phi(phi, nir_cf_node_cf_tree_next(&if_stmt->cf_node)) { if (state->first_visit) - nir_instr_as_phi(instr)->dest.ssa.divergent = false; - progress |= visit_if_merge_phi(nir_instr_as_phi(instr), - if_stmt->condition.ssa->divergent); + phi->dest.ssa.divergent = false; + progress |= visit_if_merge_phi(phi, if_stmt->condition.ssa->divergent); } /* join loop divergence information from both branch legs */ @@ -1066,11 +1062,7 @@ visit_loop(nir_loop *loop, struct divergence_state *state) /* handle loop header phis first: we have no knowledge yet about * the loop's control flow or any loop-carried sources. */ - nir_foreach_instr(instr, loop_header) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi(phi, loop_header) { if (!state->first_visit && phi->dest.ssa.divergent) continue; @@ -1096,12 +1088,8 @@ visit_loop(nir_loop *loop, struct divergence_state *state) repeat = false; /* revisit loop header phis to see if something has changed */ - nir_foreach_instr(instr, loop_header) { - if (instr->type != nir_instr_type_phi) - break; - - repeat |= visit_loop_header_phi(nir_instr_as_phi(instr), - loop_preheader, + nir_foreach_phi(phi, loop_header) { + repeat |= visit_loop_header_phi(phi, loop_preheader, loop_state.divergent_loop_continue); } @@ -1110,14 +1098,10 @@ visit_loop(nir_loop *loop, struct divergence_state *state) } while (repeat); /* handle phis after the loop */ - nir_foreach_instr(instr, nir_cf_node_cf_tree_next(&loop->cf_node)) { - if (instr->type != nir_instr_type_phi) - break; - + nir_foreach_phi(phi, nir_cf_node_cf_tree_next(&loop->cf_node)) { if (state->first_visit) - nir_instr_as_phi(instr)->dest.ssa.divergent = false; - progress |= visit_loop_exit_phi(nir_instr_as_phi(instr), - loop_state.divergent_loop_break); + phi->dest.ssa.divergent = false; + progress |= visit_loop_exit_phi(phi, loop_state.divergent_loop_break); } loop->divergent = (loop_state.divergent_loop_break || loop_state.divergent_loop_continue); diff --git a/src/compiler/nir/nir_from_ssa.c b/src/compiler/nir/nir_from_ssa.c index 1a29c0e913a..a7cfc4ed13b 100644 --- a/src/compiler/nir/nir_from_ssa.c +++ b/src/compiler/nir/nir_from_ssa.c @@ -377,12 +377,8 @@ static bool isolate_phi_nodes_block(nir_shader *shader, nir_block *block, void *dead_ctx) { nir_instr *last_phi_instr = NULL; - nir_foreach_instr(instr, block) { - /* Phi nodes only ever come at the start of a block */ - if (instr->type != nir_instr_type_phi) - break; - - last_phi_instr = instr; + nir_foreach_phi(phi, block) { + last_phi_instr = &phi->instr; } /* If we don't have any phis, then there's nothing for us to do. */ @@ -396,12 +392,7 @@ isolate_phi_nodes_block(nir_shader *shader, nir_block *block, void *dead_ctx) nir_parallel_copy_instr_create(shader); nir_instr_insert_after(last_phi_instr, &block_pcopy->instr); - nir_foreach_instr(instr, block) { - /* Phi nodes only ever come at the start of a block */ - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi(phi, block) { assert(phi->dest.is_ssa); nir_foreach_phi_src(src, phi) { if (nir_src_is_undef(src->src)) @@ -447,13 +438,7 @@ isolate_phi_nodes_block(nir_shader *shader, nir_block *block, void *dead_ctx) static bool coalesce_phi_nodes_block(nir_block *block, struct from_ssa_state *state) { - nir_foreach_instr(instr, block) { - /* Phi nodes only ever come at the start of a block */ - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); - + nir_foreach_phi(phi, block) { assert(phi->dest.is_ssa); merge_node *dest_node = get_merge_node(&phi->dest.ssa, state); @@ -1012,13 +997,8 @@ nir_lower_phis_to_regs_block(nir_block *block) _mesa_key_pointer_equal); bool progress = false; - nir_foreach_instr_safe(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi_safe(phi, block) { assert(phi->dest.is_ssa); - nir_register *reg = create_reg_for_ssa_def(&phi->dest.ssa, b.impl); b.cursor = nir_after_instr(&phi->instr); diff --git a/src/compiler/nir/nir_liveness.c b/src/compiler/nir/nir_liveness.c index 4dfda8c5588..ce5fe18f6cb 100644 --- a/src/compiler/nir/nir_liveness.c +++ b/src/compiler/nir/nir_liveness.c @@ -108,20 +108,12 @@ propagate_across_edge(nir_block *pred, nir_block *succ, BITSET_WORD *live = state->tmp_live; memcpy(live, succ->live_in, state->bitset_words * sizeof *live); - nir_foreach_instr(instr, succ) { - if (instr->type != nir_instr_type_phi) - break; - nir_phi_instr *phi = nir_instr_as_phi(instr); - + nir_foreach_phi(phi, succ) { assert(phi->dest.is_ssa); set_ssa_def_dead(&phi->dest.ssa, live); } - nir_foreach_instr(instr, succ) { - if (instr->type != nir_instr_type_phi) - break; - nir_phi_instr *phi = nir_instr_as_phi(instr); - + nir_foreach_phi(phi, succ) { nir_foreach_phi_src(src, phi) { if (src->pred == pred) { set_src_live(&src->src, live); diff --git a/src/compiler/nir/nir_lower_phis_to_scalar.c b/src/compiler/nir/nir_lower_phis_to_scalar.c index 60e256f8621..2fc86bb609f 100644 --- a/src/compiler/nir/nir_lower_phis_to_scalar.c +++ b/src/compiler/nir/nir_lower_phis_to_scalar.c @@ -189,22 +189,14 @@ lower_phis_to_scalar_block(nir_block *block, /* Find the last phi node in the block */ nir_phi_instr *last_phi = NULL; - nir_foreach_instr(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - last_phi = nir_instr_as_phi(instr); + nir_foreach_phi(phi, block) { + last_phi = phi; } /* We have to handle the phi nodes in their own pass due to the way * we're modifying the linked list of instructions. */ - nir_foreach_instr_safe(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); - + nir_foreach_phi_safe(phi, block) { if (!should_lower_phi(phi, state)) continue; @@ -267,7 +259,7 @@ lower_phis_to_scalar_block(nir_block *block, * the last phi node so once we get here, we can't trust even the * safe iterator to stop properly. We have to break manually. */ - if (instr == &last_phi->instr) + if (phi == last_phi) break; } diff --git a/src/compiler/nir/nir_lower_shader_calls.c b/src/compiler/nir/nir_lower_shader_calls.c index d0144eaf602..0c1c28810a8 100644 --- a/src/compiler/nir/nir_lower_shader_calls.c +++ b/src/compiler/nir/nir_lower_shader_calls.c @@ -860,12 +860,7 @@ cf_node_contains_block(nir_cf_node *node, nir_block *block) static void rewrite_phis_to_pred(nir_block *block, nir_block *pred) { - nir_foreach_instr(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); - + nir_foreach_phi(phi, block) { ASSERTED bool found = false; nir_foreach_phi_src(phi_src, phi) { if (phi_src->pred == pred) { diff --git a/src/compiler/nir/nir_opt_conditional_discard.c b/src/compiler/nir/nir_opt_conditional_discard.c index 4fe80aba372..ba3d0b80ebc 100644 --- a/src/compiler/nir/nir_opt_conditional_discard.c +++ b/src/compiler/nir/nir_opt_conditional_discard.c @@ -63,11 +63,7 @@ nir_opt_conditional_discard_block(nir_builder *b, nir_block *block) * make sure no subsequent phi nodes point at this if. */ nir_block *after = nir_cf_node_as_block(nir_cf_node_next(&if_stmt->cf_node)); - nir_foreach_instr_safe(instr, after) { - if (instr->type != nir_instr_type_phi) - break; - nir_phi_instr *phi = nir_instr_as_phi(instr); - + nir_foreach_phi_safe(phi, after) { nir_foreach_phi_src(phi_src, phi) { if (phi_src->pred == then_block || phi_src->pred == else_block) diff --git a/src/compiler/nir/nir_opt_dead_cf.c b/src/compiler/nir/nir_opt_dead_cf.c index fbb935842fe..e11937639dc 100644 --- a/src/compiler/nir/nir_opt_dead_cf.c +++ b/src/compiler/nir/nir_opt_dead_cf.c @@ -90,11 +90,7 @@ opt_constant_if(nir_if *if_stmt, bool condition) nir_block *last_block = condition ? nir_if_last_then_block(if_stmt) : nir_if_last_else_block(if_stmt); - nir_foreach_instr_safe(instr, after) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi_safe(phi, after) { nir_ssa_def *def = NULL; nir_foreach_phi_src(phi_src, phi) { if (phi_src->pred != last_block) @@ -107,7 +103,7 @@ opt_constant_if(nir_if *if_stmt, bool condition) assert(def); assert(phi->dest.is_ssa); nir_ssa_def_rewrite_uses(&phi->dest.ssa, def); - nir_instr_remove(instr); + nir_instr_remove(&phi->instr); } /* The control flow list we're about to paste in may include a jump at the diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c index 2ac62487995..c1b4d2132e2 100644 --- a/src/compiler/nir/nir_opt_if.c +++ b/src/compiler/nir/nir_opt_if.c @@ -850,12 +850,7 @@ rewrite_phi_predecessor_blocks(nir_if *nif, nir_block *after_if_block = nir_cf_node_as_block(nir_cf_node_next(&nif->cf_node)); - nir_foreach_instr(instr, after_if_block) { - if (instr->type != nir_instr_type_phi) - continue; - - nir_phi_instr *phi = nir_instr_as_phi(instr); - + nir_foreach_phi(phi, after_if_block) { nir_foreach_phi_src(src, phi) { if (src->pred == old_then_block) { src->pred = new_then_block; @@ -946,11 +941,7 @@ opt_if_phi_is_condition(nir_builder *b, nir_if *nif) bool progress = false; nir_block *after_if_block = nir_cf_node_as_block(nir_cf_node_next(&nif->cf_node)); - nir_foreach_instr_safe(instr, after_if_block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi_safe(phi, after_if_block) { if (phi->dest.ssa.bit_size != cond->bit_size || phi->dest.ssa.num_components != 1) continue; @@ -1564,13 +1555,10 @@ opt_if_merge(nir_if *nif) nir_block *after_next_if_block = nir_cf_node_as_block(nir_cf_node_next(&next_if->cf_node)); - nir_foreach_instr_safe(instr, after_next_if_block) { - if (instr->type != nir_instr_type_phi) - break; - - exec_node_remove(&instr->node); - exec_list_push_tail(&next_blk->instr_list, &instr->node); - instr->block = next_blk; + nir_foreach_phi_safe(phi, after_next_if_block) { + exec_node_remove(&phi->instr.node); + exec_list_push_tail(&next_blk->instr_list, &phi->instr.node); + phi->instr.block = next_blk; } nir_cf_node_remove(&next_if->cf_node); diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c index 7a1fde07289..857c1dd0064 100644 --- a/src/compiler/nir/nir_opt_peephole_select.c +++ b/src/compiler/nir/nir_opt_peephole_select.c @@ -445,11 +445,7 @@ nir_opt_peephole_select_block(nir_block *block, nir_shader *shader, exec_list_push_tail(&prev_block->instr_list, &instr->node); } - nir_foreach_instr_safe(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi_safe(phi, block) { nir_alu_instr *sel = nir_alu_instr_create(shader, nir_op_bcsel); nir_src_copy(&sel->src[0].src, &if_stmt->condition, &sel->instr); /* Splat the condition to all channels */ diff --git a/src/compiler/nir/nir_opt_phi_precision.c b/src/compiler/nir/nir_opt_phi_precision.c index 03b8ef1dbe3..f23d32096dc 100644 --- a/src/compiler/nir/nir_opt_phi_precision.c +++ b/src/compiler/nir/nir_opt_phi_precision.c @@ -468,12 +468,8 @@ nir_opt_phi_precision(nir_shader *shader) nir_builder_init(&b, function->impl); nir_foreach_block (block, function->impl) { - nir_foreach_instr_safe (instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - progress |= lower_phi(&b, nir_instr_as_phi(instr)); - } + nir_foreach_phi_safe (phi, block) + progress |= lower_phi(&b, phi); } if (progress) { diff --git a/src/compiler/nir/nir_opt_remove_phis.c b/src/compiler/nir/nir_opt_remove_phis.c index 20efa41a601..4e7e75fc86d 100644 --- a/src/compiler/nir/nir_opt_remove_phis.c +++ b/src/compiler/nir/nir_opt_remove_phis.c @@ -68,12 +68,7 @@ remove_phis_block(nir_block *block, nir_builder *b) { bool progress = false; - nir_foreach_instr_safe(instr, block) { - if (instr->type != nir_instr_type_phi) - break; - - nir_phi_instr *phi = nir_instr_as_phi(instr); - + nir_foreach_phi_safe(phi, block) { nir_ssa_def *def = NULL; nir_alu_instr *mov = NULL; bool srcs_same = true; @@ -133,7 +128,7 @@ remove_phis_block(nir_block *block, nir_builder *b) assert(phi->dest.is_ssa); nir_ssa_def_rewrite_uses(&phi->dest.ssa, def); - nir_instr_remove(instr); + nir_instr_remove(&phi->instr); progress = true; } diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 1c68ed28c6f..f2ecb8b6b29 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -1212,11 +1212,8 @@ validate_phi_src(nir_phi_instr *instr, nir_block *pred, validate_state *state) static void validate_phi_srcs(nir_block *block, nir_block *succ, validate_state *state) { - nir_foreach_instr(instr, succ) { - if (instr->type != nir_instr_type_phi) - break; - - validate_phi_src(nir_instr_as_phi(instr), block, state); + nir_foreach_phi(phi, succ) { + validate_phi_src(phi, block, state); } }