nir: rewrite nir_foreach_block and friends
authorConnor Abbott <cwabbott0@gmail.com>
Fri, 8 Apr 2016 06:11:44 +0000 (02:11 -0400)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 27 Apr 2016 22:05:40 +0000 (15:05 -0700)
commit122d27e9981342dc267c5aebf1a8dd8ce30689ce
treeb294e9c3126461b6f933a0638187c5818695376a
parent958300137f26ee7d32d87a71e0c1843671d73732
nir: rewrite nir_foreach_block and friends

Previously, these were functions which took a callback. This meant that
the per-block code had to be in a separate function, and all the data
that you wanted to pass in had to be a single void *. They walked the
control flow tree recursively, doing a depth-first search, and called
the callback in a preorder, matching the order of the original source
code. But since each node in the control flow tree has a pointer to its
parent, we can implement a "get-next" and "get-previous" method that
does the same thing that the recursive function did with no state at
all. This lets us rewrite nir_foreach_block() as a simple for loop,
which lets us greatly simplify its users in some cases. This does
require us to rewrite every user, although the transformation from the
old nir_foreach_block() to the new nir_foreach_block() is mostly
trivial.

One subtlety, though, is that the new nir_foreach_block() won't handle
the case where the current block is deleted, which the old one could.
There's a new nir_foreach_block_safe() which implements the standard
trick for solving this. Most users don't modify control flow, though, so
they won't need it. Right now, only opt_select_peephole needs it.

The old functions are reimplemented in terms of the new macros, although
they'll go away after everything is converted.

v2: keep an implementation of the old functions around
v3 (Jason Ekstrand): A small cosmetic change and a bugfix in the loop
   handling of nir_cf_node_cf_tree_last().
v4 (Jason Ekstrand): Use the _safe macro in foreach_block_reverse_call

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/nir/nir.c
src/compiler/nir/nir.h