diff options
author | Connor Abbott <cwabbott0@gmail.com> | 2015-05-21 00:37:51 -0400 |
---|---|---|
committer | Connor Abbott <cwabbott0@gmail.com> | 2015-05-21 03:05:44 -0400 |
commit | 76f42969d726ae3812c5ceba4fa491e1941c3595 (patch) | |
tree | 9b2a2b57485c6a7e68bbf066dd2db65efa89a3f3 | |
parent | 78e3971712ff1cd032b2b14714bf693b66874164 (diff) |
nir: add nir_cf_node_remove_after()
This will be used in deleting unreachable control flow.
-rw-r--r-- | src/glsl/nir/nir.c | 45 | ||||
-rw-r--r-- | src/glsl/nir/nir.h | 3 |
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 */ |