This makes stitch_blocks() available for use else where, and adds a new helper that extracts a cf list without worrying about validation. --- src/compiler/nir/nir_control_flow.c | 34 ++++++++++++++++++++++++++++++++-- src/compiler/nir/nir_control_flow.h | 5 +++++ 2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/src/compiler/nir/nir_control_flow.c b/src/compiler/nir/nir_control_flow.c index a485e71..ed8cd24 100644 --- a/src/compiler/nir/nir_control_flow.c +++ b/src/compiler/nir/nir_control_flow.c @@ -628,8 +628,7 @@ 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. */ - -static void +void stitch_blocks(nir_block *before, nir_block *after) { /* @@ -791,6 +790,37 @@ nir_cf_extract(nir_cf_list *extracted, nir_cursor begin, nir_cursor end) stitch_blocks(block_before, block_after); } +/** + * Its not really possible to extract control flow from a loop while keeping + * the cf valid so this function just rips out what we ask for and any + * validation and fix ups are left to the caller. + */ +void +nir_cf_loop_list_extract(nir_cf_list *extracted, nir_cf_node *begin, + nir_cf_node *end) +{ + extracted->impl = nir_cf_node_get_function(begin); + exec_list_make_empty(&extracted->list); + + /* Dominance and other block-related information is toast. */ + nir_metadata_preserve(extracted->impl, nir_metadata_none); + + nir_cf_node *cf_node = begin; + nir_cf_node *cf_node_end = end; + while (true) { + nir_cf_node *next = nir_cf_node_next(cf_node); + + exec_node_remove(&cf_node->node); + cf_node->parent = NULL; + exec_list_push_tail(&extracted->list, &cf_node->node); + + if (cf_node == cf_node_end) + break; + + cf_node = next; + } +} + void nir_cf_reinsert(nir_cf_list *cf_list, nir_cursor cursor) { diff --git a/src/compiler/nir/nir_control_flow.h b/src/compiler/nir/nir_control_flow.h index b71382f..0d97486 100644 --- a/src/compiler/nir/nir_control_flow.h +++ b/src/compiler/nir/nir_control_flow.h @@ -78,6 +78,9 @@ nir_cf_node_insert_end(struct exec_list *list, nir_cf_node *node) nir_cf_node_insert(nir_after_cf_list(list), node); } +void +stitch_blocks(nir_block *before, nir_block *after); + /** Control flow motion. * @@ -148,6 +151,8 @@ nir_cf_list_extract(nir_cf_list *extracted, struct exec_list *cf_list) nir_after_cf_list(cf_list)); } +void nir_cf_loop_list_extract(nir_cf_list *extracted, nir_cf_node *begin, nir_cf_node *end); + /** removes a control flow node, doing any cleanup necessary */ static inline void nir_cf_node_remove(nir_cf_node *node) -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev