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)

Reply via email to