[Mesa-dev] [PATCH 2/2] nir: fix bug with moves in nir_opt_remove_phis()

Jason Ekstrand jason at jlekstrand.net
Sat Sep 3 00:48:53 UTC 2016


I think this is conceptually correct but I haven't reviewed it for complete
correctness yet or tested it.

That said, I think this is just a special case of the phi distribution pass
that we talked about on IRC a bit today.  Maybe we should just go ahead and
implement that?  For unary ALU operations, phi distribution is a clear win
and mov is definitely unary.

On Fri, Sep 2, 2016 at 4:28 PM, Connor Abbott <cwabbott0 at gmail.com> wrote:

> In 144cbf8 ("nir: Make nir_opt_remove_phis see through moves."), Ken
> made nir_opt_remove_phis able to coalesce phi nodes whose sources are
> all moves with the same swizzle. However, he didn't add the logic
> necessary for handling the fact that the phi may now have multiple
> different sources, even though the sources point to the same thing. For
> example, if we had something like:
>
> if (...)
>    a1 = b.yx;
> else
>    a2 = b.yx;
> a = phi(a1, a2)
> ... = a
>
> then we would rewrite it to
>
> if (...)
>    a1 = b.yx;
> else
>    a2 = b.yx;
> ... = a1
>
> by picking a random phi source, which in this case is invalid because
> the source doesn't dominate the phi. Instead, we need to change it to:
>
> if (...)
>    a1 = b.yx;
> else
>    a2 = b.yx;
> a3 = b.yx;
> ... = a3;
> ---
>
> This is an alternative to Ken's patch to revert it, although it's
> totally untested (just compile tested).
>
>  src/compiler/nir/nir_opt_remove_phis.c | 22 ++++++++++++++++++++--
>  1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/src/compiler/nir/nir_opt_remove_phis.c
> b/src/compiler/nir/nir_opt_remove_phis.c
> index ee92fbe..acaa6e1 100644
> --- a/src/compiler/nir/nir_opt_remove_phis.c
> +++ b/src/compiler/nir/nir_opt_remove_phis.c
> @@ -26,6 +26,7 @@
>   */
>
>  #include "nir.h"
> +#include "nir_builder.h"
>
>  static nir_alu_instr *
>  get_parent_mov(nir_ssa_def *ssa)
> @@ -63,7 +64,7 @@ matching_mov(nir_alu_instr *mov1, nir_ssa_def *ssa)
>   */
>
>  static bool
> -remove_phis_block(nir_block *block)
> +remove_phis_block(nir_block *block, nir_builder *b)
>  {
>     bool progress = false;
>
> @@ -113,6 +114,21 @@ remove_phis_block(nir_block *block)
>         */
>        assert(def != NULL);
>
> +      if (mov) {
> +         /* If the sources were all mov's from the same source with the
> same
> +          * swizzle, then we can't just pick a random move because it may
> not
> +          * dominate the phi node. Instead, we need to emit our own move
> after
> +          * the phi which uses the shared source, and rewrite uses of the
> phi
> +          * to use the move instead. This is ok, because while the mov's
> may
> +          * not all dominate the phi node, their shared source does.
> +          */
> +
> +         b->cursor = nir_after_phis(block);
> +         def = mov->op == nir_op_imov ?
> +            nir_imov_alu(b, mov->src[0], def->num_components) :
> +            nir_fmov_alu(b, mov->src[0], def->num_components);
> +      }
> +
>        assert(phi->dest.is_ssa);
>        nir_ssa_def_rewrite_uses(&phi->dest.ssa, nir_src_for_ssa(def));
>        nir_instr_remove(instr);
> @@ -127,9 +143,11 @@ static bool
>  remove_phis_impl(nir_function_impl *impl)
>  {
>     bool progress = false;
> +   nir_builder bld;
> +   nir_builder_init(&bld, impl);
>
>     nir_foreach_block(block, impl) {
> -      progress |= remove_phis_block(block);
> +      progress |= remove_phis_block(block, &bld);
>     }
>
>     if (progress) {
> --
> 2.5.5
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160902/3562f7ae/attachment.html>


More information about the mesa-dev mailing list