[Mesa-dev] [PATCH 08/13] nir: add control flow helpers for loop unrolling

Timothy Arceri timothy.arceri at collabora.com
Mon Aug 29 04:59:16 UTC 2016


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



More information about the mesa-dev mailing list