[Mesa-dev] [PATCH v2 06/14] nir: add nir_cf_node_remove_after()

Connor Abbott cwabbott0 at gmail.com
Thu May 21 09:41:01 PDT 2015


This will be used in deleting unreachable control flow.

Signed-off-by: Connor Abbott <cwabbott0 at gmail.com>
---
 src/glsl/nir/nir.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 src/glsl/nir/nir.h |  3 +++
 2 files changed, 48 insertions(+)

diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
index bd4f6cc..0223fcd 100644
--- a/src/glsl/nir/nir.c
+++ b/src/glsl/nir/nir.c
@@ -1381,6 +1381,51 @@ nir_cf_node_remove(nir_cf_node *node)
    }
 }
 
+void
+nir_cf_node_remove_after(nir_cf_node *node)
+{
+   nir_function_impl *impl = nir_cf_node_get_function(node);
+
+   /*
+    * For non-block cf nodes, empty the block after it and then delete the
+    * rest of the nodes after the block so that the list still ends with a
+    * block.
+    */
+
+   if (node->type != nir_cf_node_block) {
+      node = nir_cf_node_next(node);
+      cleanup_cf_node(node, impl);
+      exec_list_make_empty(&nir_cf_node_as_block(node)->instr_list);
+   }
+
+   /*
+    * Now that we know that node is a block, we can just nuke everything after
+    * it.
+    */
+
+   while (!nir_cf_node_is_last(node)) {
+      nir_cf_node *next = nir_cf_node_next(node);
+
+      cleanup_cf_node(next, impl);
+
+      if (nir_cf_node_is_last(next)) {
+         nir_block *next_block = nir_cf_node_as_block(next);
+         exec_list_make_empty(&next_block->instr_list);
+
+         /*
+          * There are a number of issues here around fixing up successors and
+          * phi nodes, but those are solved already by the stitch_blocks()
+          * function.
+          */
+
+         stitch_blocks(nir_cf_node_as_block(node), next_block);
+      } else {
+         exec_node_remove(&next->node);
+      }
+   }
+}
+
+
 static bool
 add_use_cb(nir_src *src, void *state)
 {
diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
index 5ae261a..d6702b4 100644
--- a/src/glsl/nir/nir.h
+++ b/src/glsl/nir/nir.h
@@ -1521,6 +1521,9 @@ void nir_cf_node_insert_end(struct exec_list *list, nir_cf_node *node);
 /** removes a control flow node, doing any cleanup necessary */
 void nir_cf_node_remove(nir_cf_node *node);
 
+/** removes everything after the given control flow node */
+void nir_cf_node_remove_after(nir_cf_node *node);
+
 /** requests that the given pieces of metadata be generated */
 void nir_metadata_require(nir_function_impl *impl, nir_metadata required);
 /** dirties all but the preserved metadata */
-- 
2.1.0



More information about the mesa-dev mailing list