[Mesa-dev] [PATCH 07/12] nir: Add a function for comparing cursors

Jason Ekstrand jason at jlekstrand.net
Sat Dec 26 11:09:30 PST 2015


---
 src/glsl/nir/nir.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/glsl/nir/nir.h |  2 ++
 2 files changed, 65 insertions(+)

diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
index 12bd30f..4793673 100644
--- a/src/glsl/nir/nir.c
+++ b/src/glsl/nir/nir.c
@@ -695,6 +695,69 @@ nir_cf_node_get_function(nir_cf_node *node)
    return nir_cf_node_as_function(node);
 }
 
+/* Reduces a cursor by trying to convert everything to after and trying to
+ * go up to block granularity when possible.
+ */
+static nir_cursor
+reduce_cursor(nir_cursor cursor)
+{
+   switch (cursor.option) {
+   case nir_cursor_before_block:
+      if (exec_list_is_empty(&cursor.block->instr_list)) {
+         /* Empty block.  After is as good as before. */
+         cursor.option = nir_cursor_after_block;
+      } else {
+         /* Try to switch to after the previous block if there is one.
+          * (This isn't likely, but it can happen.)
+          */
+         nir_cf_node *prev_node = nir_cf_node_prev(&cursor.block->cf_node);
+         if (prev_node && prev_node->type == nir_cf_node_block) {
+            cursor.block = nir_cf_node_as_block(prev_node);
+            cursor.option = nir_cursor_after_block;
+         }
+      }
+      return cursor;
+
+   case nir_cursor_after_block:
+      return cursor;
+
+   case nir_cursor_before_instr: {
+      nir_instr *prev_instr = nir_instr_prev(cursor.instr);
+      if (prev_instr) {
+         /* Before this instruction is after the previous */
+         cursor.instr = prev_instr;
+         cursor.option = nir_cursor_after_instr;
+      } else {
+         /* No previous instruction.  Switch to before block */
+         cursor.block = cursor.instr->block;
+         cursor.option = nir_cursor_before_block;
+      }
+      return reduce_cursor(cursor);
+   }
+
+   case nir_cursor_after_instr:
+      if (nir_instr_next(cursor.instr) == NULL) {
+         /* This is the last instruction, switch to after block */
+         cursor.option = nir_cursor_after_block;
+         cursor.block = cursor.instr->block;
+      }
+      return cursor;
+
+   default:
+      unreachable("Inavlid cursor option");
+   }
+}
+
+bool
+nir_cursors_equal(nir_cursor a, nir_cursor b)
+{
+   /* Reduced cursors should be unique */
+   a = reduce_cursor(a);
+   b = reduce_cursor(b);
+
+   return a.block == b.block && a.option == b.option;
+}
+
 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 7dc09db..b6c8ffe 100644
--- a/src/glsl/nir/nir.h
+++ b/src/glsl/nir/nir.h
@@ -1710,6 +1710,8 @@ typedef struct {
    };
 } nir_cursor;
 
+bool nir_cursors_equal(nir_cursor a, nir_cursor b);
+
 static inline nir_cursor
 nir_before_block(nir_block *block)
 {
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list