summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-12-26 10:32:10 -0800
committerJason Ekstrand <[email protected]>2016-03-24 15:20:44 -0700
commit7022a673cd6b9e4bdd4c55fe1d7c76c04d27d4e6 (patch)
treeab9a4d74c093476d79beb9e0ae2fc1faaa6ebec5 /src
parent124f229ece8ffa7d1f8d530771f183f7803d6cdc (diff)
nir: Add a function for comparing cursors
Reviewed-by: Jordan Justen <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/compiler/nir/nir.c56
-rw-r--r--src/compiler/nir/nir.h2
2 files changed, 58 insertions, 0 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 20f1a182b77..b67916dc86b 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -724,6 +724,62 @@ 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:
+ assert(nir_cf_node_prev(&cursor.block->cf_node) == NULL ||
+ nir_cf_node_prev(&cursor.block->cf_node)->type != nir_cf_node_block);
+ if (exec_list_is_empty(&cursor.block->instr_list)) {
+ /* Empty block. After is as good as before. */
+ 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/compiler/nir/nir.h b/src/compiler/nir/nir.h
index a4596096b59..718d281d7de 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1867,6 +1867,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)
{