Module: Mesa Branch: main Commit: 0e7e6f2a0d67af0533572b2d9a7ce7149830f225 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0e7e6f2a0d67af0533572b2d9a7ce7149830f225
Author: Alyssa Rosenzweig <[email protected]> Date: Fri Jun 30 17:29:51 2023 -0400 nir: Fix breaking in nir_foreach_phi(_safe) When I reading through some of my older commits I noticed that `break` in `nir_foreach_phi` is broken because I used the two-loop trick wrong. Rewrite the macros to fix this, and also to generally be a lot cleaner. Fixes: 7dc297cc141 ("nir: Add nir_foreach_phi(_safe) macro") Signed-off-by: Alyssa Rosenzweig <[email protected]> Reviewed-by: Jesse Natalie <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23957> --- src/compiler/nir/nir.h | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 95a74adb9b7..3e5188611de 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2962,20 +2962,39 @@ nir_block_ends_in_break(nir_block *block) foreach_list_typed_reverse_safe(nir_instr, instr, node, &(block)->instr_list) /* Phis come first in the block */ -#define nir_foreach_phi_internal(instr, phi) \ - if (instr->type != nir_instr_type_phi) \ - break; \ - else \ - for (nir_phi_instr *phi = nir_instr_as_phi(instr); phi != NULL; \ - phi = NULL) - -#define nir_foreach_phi(instr, block) \ - nir_foreach_instr(nir_foreach_phi_##instr, block) \ - nir_foreach_phi_internal(nir_foreach_phi_##instr, instr) - -#define nir_foreach_phi_safe(instr, block) \ - nir_foreach_instr_safe(nir_foreach_phi_safe_##instr, block) \ - nir_foreach_phi_internal(nir_foreach_phi_safe_##instr, instr) +static inline nir_phi_instr * +nir_first_phi_in_block(nir_block *block) +{ + nir_foreach_instr(instr, block) { + if (instr->type == nir_instr_type_phi) + return nir_instr_as_phi(instr); + else + return NULL; + } + + return NULL; +} + +static inline nir_phi_instr * +nir_next_phi(nir_phi_instr *phi) +{ + nir_instr *next = nir_instr_next(&phi->instr); + + if (next && next->type == nir_instr_type_phi) + return nir_instr_as_phi(next); + else + return NULL; +} + +#define nir_foreach_phi(instr, block) \ + for (nir_phi_instr *instr = nir_first_phi_in_block(block); instr != NULL; \ + instr = nir_next_phi(instr)) + +#define nir_foreach_phi_safe(instr, block) \ + for (nir_phi_instr *instr = nir_first_phi_in_block(block), \ + *__next = instr ? nir_next_phi(instr) : NULL; \ + instr != NULL; \ + instr = __next, __next = instr ? nir_next_phi(instr) : NULL) static inline nir_phi_instr * nir_block_last_phi_instr(nir_block *block)
