Module: Mesa
Branch: main
Commit: 312510448f25ec89028bd116b53b4133a6218c21
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=312510448f25ec89028bd116b53b4133a6218c21

Author: Daniel Schürmann <[email protected]>
Date:   Thu Dec  2 12:26:02 2021 +0100

nir: create nir_push_continue() and related helpers

nir_control_flow.h:
  void nir_loop_add_continue_construct(nir_loop *loop);
  void nir_loop_remove_continue_construct(nir_loop *loop);

Reviewed-by: Faith Ekstrand <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13962>

---

 src/compiler/nir/nir_builder.c      | 16 ++++++++++++++++
 src/compiler/nir/nir_builder.h      |  3 +++
 src/compiler/nir/nir_control_flow.c | 38 +++++++++++++++++++++++++++++++++++++
 src/compiler/nir/nir_control_flow.h |  4 ++++
 4 files changed, 61 insertions(+)

diff --git a/src/compiler/nir/nir_builder.c b/src/compiler/nir/nir_builder.c
index 711208e5936..8a25316d65b 100644
--- a/src/compiler/nir/nir_builder.c
+++ b/src/compiler/nir/nir_builder.c
@@ -499,6 +499,22 @@ nir_push_loop(nir_builder *build)
    return loop;
 }
 
+nir_loop *
+nir_push_continue(nir_builder *build, nir_loop *loop)
+{
+   if (loop) {
+      assert(nir_builder_is_inside_cf(build, &loop->cf_node));
+   } else {
+      nir_block *block = nir_cursor_current_block(build->cursor);
+      loop = nir_cf_node_as_loop(block->cf_node.parent);
+   }
+
+   nir_loop_add_continue_construct(loop);
+
+   build->cursor = nir_before_cf_list(&loop->continue_list);
+   return loop;
+}
+
 void
 nir_pop_loop(nir_builder *build, nir_loop *loop)
 {
diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h
index 1972f125dae..d92583fb18d 100644
--- a/src/compiler/nir/nir_builder.h
+++ b/src/compiler/nir/nir_builder.h
@@ -159,6 +159,9 @@ nir_if_phi(nir_builder *build, nir_ssa_def *then_def, 
nir_ssa_def *else_def);
 nir_loop *
 nir_push_loop(nir_builder *build);
 
+nir_loop *
+nir_push_continue(nir_builder *build, nir_loop *loop);
+
 void nir_pop_loop(nir_builder *build, nir_loop *loop);
 
 static inline nir_ssa_def *
diff --git a/src/compiler/nir/nir_control_flow.c 
b/src/compiler/nir/nir_control_flow.c
index 43d02f2e176..8a93435ef30 100644
--- a/src/compiler/nir/nir_control_flow.c
+++ b/src/compiler/nir/nir_control_flow.c
@@ -435,6 +435,44 @@ nearest_loop(nir_cf_node *node)
    return nir_cf_node_as_loop(node);
 }
 
+void
+nir_loop_add_continue_construct(nir_loop *loop)
+{
+   assert(!nir_loop_has_continue_construct(loop));
+
+   nir_block *cont = nir_block_create(ralloc_parent(loop));
+   exec_list_push_tail(&loop->continue_list, &cont->cf_node.node);
+   cont->cf_node.parent = &loop->cf_node;
+
+   /* change predecessors and successors */
+   nir_block *header = nir_loop_first_block(loop);
+   nir_block *preheader = nir_block_cf_tree_prev(header);
+   set_foreach(header->predecessors, entry) {
+      nir_block *pred = (nir_block *) entry->key;
+      if (pred != preheader)
+         replace_successor(pred, header, cont);
+   }
+
+   link_blocks(cont, header, NULL);
+}
+
+void
+nir_loop_remove_continue_construct(nir_loop *loop)
+{
+   assert(nir_cf_list_is_empty_block(&loop->continue_list));
+
+   /* change predecessors and successors */
+   nir_block *header = nir_loop_first_block(loop);
+   nir_block *cont = nir_loop_first_continue_block(loop);
+   set_foreach(cont->predecessors, entry) {
+      nir_block *pred = (nir_block*) entry->key;
+      replace_successor(pred, cont, header);
+   }
+   block_remove_pred(header, cont);
+
+   exec_node_remove(&cont->cf_node.node);
+}
+
 static void
 remove_phi_src(nir_block *block, nir_block *pred)
 {
diff --git a/src/compiler/nir/nir_control_flow.h 
b/src/compiler/nir/nir_control_flow.h
index 34e79b7ad80..e31cd8e732d 100644
--- a/src/compiler/nir/nir_control_flow.h
+++ b/src/compiler/nir/nir_control_flow.h
@@ -175,6 +175,10 @@ nir_cf_node_remove(nir_cf_node *node)
 /** inserts undef phi sources from predcessor into phis of the block */
 void nir_insert_phi_undef(nir_block *block, nir_block *pred);
 
+/** Modify loop continue behavior */
+void nir_loop_add_continue_construct(nir_loop *loop);
+void nir_loop_remove_continue_construct(nir_loop *loop);
+
 #ifdef __cplusplus
 }
 #endif

Reply via email to