summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConnor Abbott <cwabbott0@gmail.com>2015-05-21 00:37:51 -0400
committerConnor Abbott <cwabbott0@gmail.com>2015-05-21 03:05:44 -0400
commit76f42969d726ae3812c5ceba4fa491e1941c3595 (patch)
tree9b2a2b57485c6a7e68bbf066dd2db65efa89a3f3
parent78e3971712ff1cd032b2b14714bf693b66874164 (diff)
nir: add nir_cf_node_remove_after()
This will be used in deleting unreachable control flow.
-rw-r--r--src/glsl/nir/nir.c45
-rw-r--r--src/glsl/nir/nir.h3
2 files changed, 48 insertions, 0 deletions
diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
index bd4f6cca1f..0223fcd78e 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 5ae261ac93..d6702b41ea 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 */