nir/cf: return cursor after insertion of cf_list
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Tue, 19 Apr 2022 12:05:04 +0000 (15:05 +0300)
committerMarge Bot <emma+marge@anholt.net>
Mon, 9 May 2022 08:43:40 +0000 (08:43 +0000)
This will be useful to cut code from one location and paste it at
another place and later keep pasting after the previous insertions.

v2: update comment (Jason)
    deal with stiching 2 empty blocks (Jason)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16036>

src/compiler/nir/nir_control_flow.c
src/compiler/nir/nir_control_flow.h

index 2affb05..3e2688f 100644 (file)
@@ -547,9 +547,12 @@ update_if_uses(nir_cf_node *node)
 /**
  * Stitch two basic blocks together into one. The aggregate must have the same
  * predecessors as the first and the same successors as the second.
+ *
+ * Returns a cursor pointing at the end of the before block (i.e.m between the
+ * two blocks) once stiched together.
  */
 
-static void
+static nir_cursor
 stitch_blocks(nir_block *before, nir_block *after)
 {
    /*
@@ -567,7 +570,11 @@ stitch_blocks(nir_block *before, nir_block *after)
          remove_phi_src(after->successors[1], after);
       unlink_block_successors(after);
       exec_node_remove(&after->cf_node.node);
+
+      return nir_after_block(before);
    } else {
+      nir_instr *last_before_instr = nir_block_last_instr(before);
+
       move_successors(after, before);
 
       foreach_list_typed(nir_instr, instr, node, &after->instr_list) {
@@ -576,6 +583,9 @@ stitch_blocks(nir_block *before, nir_block *after)
 
       exec_list_append(&before->instr_list, &after->instr_list);
       exec_node_remove(&after->cf_node.node);
+
+      return last_before_instr ? nir_after_instr(last_before_instr) :
+                                 nir_before_block(before);
    }
 }
 
@@ -777,13 +787,17 @@ relink_jump_halt_cf_node(nir_cf_node *node, nir_block *end_block)
    }
 }
 
-void
+/**
+ * Inserts a list at a given cursor. Returns the cursor at the end of the
+ * insertion (i.e., at the end of the instructions contained in cf_list).
+ */
+nir_cursor
 nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor)
 {
    nir_block *before, *after;
 
    if (exec_list_is_empty(&cf_list->list))
-      return;
+      return cursor;
 
    nir_function_impl *cursor_impl =
       nir_cf_node_get_function(&nir_cursor_current_block(cursor)->cf_node);
@@ -802,8 +816,8 @@ nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor)
 
    stitch_blocks(before,
                  nir_cf_node_as_block(nir_cf_node_next(&before->cf_node)));
-   stitch_blocks(nir_cf_node_as_block(nir_cf_node_prev(&after->cf_node)),
-                 after);
+   return stitch_blocks(nir_cf_node_as_block(nir_cf_node_prev(&after->cf_node)),
+                        after);
 }
 
 void
index c1867a8..f5956ef 100644 (file)
@@ -138,7 +138,7 @@ typedef struct {
 
 void nir_cf_extract(nir_cf_list *extracted, nir_cursor begin, nir_cursor end);
 
-void nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor);
+nir_cursor nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor);
 
 void nir_cf_delete(nir_cf_list *cf_list);