On Sat, Feb 13, 2016 at 9:14 PM, Jason Ekstrand <ja...@jlekstrand.net> wrote: > --- > src/compiler/nir/nir.c | 63 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > src/compiler/nir/nir.h | 2 ++ > 2 files changed, 65 insertions(+) > > diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c > index cd78475..468065a 100644 > --- a/src/compiler/nir/nir.c > +++ b/src/compiler/nir/nir.c > @@ -716,6 +716,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) {
How can the current node and the previous node both be blocks? It's an invariant of the control-flow modification code that no two blocks ever wind up next to each other. > + 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/compiler/nir/nir.h b/src/compiler/nir/nir.h > index 4c6c22f..c856b83 100644 > --- a/src/compiler/nir/nir.h > +++ b/src/compiler/nir/nir.h > @@ -1803,6 +1803,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 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev