[Mesa-dev] [PATCH 2/2] nir: fix bug with moves in nir_opt_remove_phis()
Connor Abbott
cwabbott0 at gmail.com
Sat Sep 3 00:51:52 UTC 2016
On Fri, Sep 2, 2016 at 8:48 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> 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.
Yeah, if we implement that then we can just get rid of the whole thing.
>
> 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
>
>
More information about the mesa-dev
mailing list