[Mesa-dev] [PATCH v2 2/8] nir: propagates if condition evaluation down some alu chains

Jason Ekstrand jason at jlekstrand.net
Fri Aug 17 19:52:03 UTC 2018


Ugh... Now that I think about it more, my suggestions on the previous patch
conflict quite a bit. :(  Let me think some more.

On Fri, Aug 17, 2018 at 2:27 PM Jason Ekstrand <jason at jlekstrand.net> wrote:

> It took me a while to figure out what you're doing here but, once I've
> grokked it, I like it.  That said, I'd like to see your response to my
> comments on patch 1 as that would cause this to get restructured a good
> bit.  (I think it will be much improved for it.)
>
> --Jason
>
> On Mon, Jul 23, 2018 at 3:02 AM Timothy Arceri <tarceri at itsqueeze.com>
> wrote:
>
>> shader-db IVB results:
>>
>> total instructions in shared programs: 9993483 -> 9993472 (-0.00%)
>> instructions in affected programs: 1300 -> 1289 (-0.85%)
>> helped: 11
>> HURT: 0
>>
>> total cycles in shared programs: 219476091 -> 219476059 (-0.00%)
>> cycles in affected programs: 7675 -> 7643 (-0.42%)
>> helped: 10
>> HURT: 1
>> ---
>>  src/compiler/nir/nir_opt_if.c | 155 ++++++++++++++++++++++++++++++++--
>>  1 file changed, 149 insertions(+), 6 deletions(-)
>>
>> diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c
>> index b3d5046a76e..c9e50cec1fe 100644
>> --- a/src/compiler/nir/nir_opt_if.c
>> +++ b/src/compiler/nir/nir_opt_if.c
>> @@ -404,9 +404,134 @@ replace_if_condition_use_with_const(nir_src *use,
>> unsigned nir_boolean,
>>        nir_instr_rewrite_src(use->parent_instr, use, new_src);
>>  }
>>
>> +/*
>> + * This propagates if condition evaluation down the chain of some alu
>> + * instructions. For example by checking the use of some of the
>> following alu
>> + * instruction we can eventually replace ssa_107 with NIR_TRUE.
>> + *
>> + *   loop {
>> + *      block block_1:
>> + *      vec1 32 ssa_85 = load_const (0x00000002)
>> + *      vec1 32 ssa_86 = ieq ssa_48, ssa_85
>> + *      vec1 32 ssa_87 = load_const (0x00000001)
>> + *      vec1 32 ssa_88 = ieq ssa_48, ssa_87
>> + *      vec1 32 ssa_89 = ior ssa_86, ssa_88
>> + *      vec1 32 ssa_90 = ieq ssa_48, ssa_0
>> + *      vec1 32 ssa_91 = ior ssa_89, ssa_90
>> + *      if ssa_86 {
>> + *         block block_2:
>> + *             ...
>> + *            break
>> + *      } else {
>> + *            block block_3:
>> + *      }
>> + *      block block_4:
>> + *      if ssa_88 {
>> + *            block block_5:
>> + *             ...
>> + *            break
>> + *      } else {
>> + *            block block_6:
>> + *      }
>> + *      block block_7:
>> + *      if ssa_90 {
>> + *            block block_8:
>> + *             ...
>> + *            break
>> + *      } else {
>> + *            block block_9:
>> + *      }
>> + *      block block_10:
>> + *      vec1 32 ssa_107 = inot ssa_91
>> + *      if ssa_107 {
>> + *            block block_11:
>> + *            break
>> + *      } else {
>> + *            block block_12:
>> + *      }
>> + *   }
>> + */
>> +static bool
>> +propagate_condition_eval(nir_builder *b, nir_if *nif, nir_src *use_src,
>> +                         nir_src *alu_use, nir_alu_instr *alu, void
>> *mem_ctx,
>> +                         bool if_condition)
>> +{
>> +   bool progress = false;
>> +
>> +   nir_block *use_block;
>> +   if (if_condition) {
>> +      use_block =
>> +
>>  nir_cf_node_as_block(nir_cf_node_prev(&alu_use->parent_if->cf_node));
>> +   } else {
>> +      use_block = alu_use->parent_instr->block;
>> +   }
>> +
>> +   if (nir_op_infos[alu->op].num_inputs == 1) {
>> +      if (nir_block_dominates(nir_if_first_then_block(nif), use_block)) {
>> +         replace_if_condition_use_with_const(alu_use, NIR_TRUE, mem_ctx,
>> +                                             if_condition);
>> +         progress = true;
>> +      } else if (nir_block_dominates(nir_if_first_else_block(nif),
>> +                                     use_block)) {
>> +         replace_if_condition_use_with_const(alu_use, NIR_FALSE, mem_ctx,
>> +                                             if_condition);
>> +         progress = true;
>> +      }
>> +   } else {
>> +      assert(alu->op == nir_op_ior || alu->op == nir_op_iand);
>> +
>> +      bool found = false;
>> +      unsigned nir_boolean = 0;
>> +      if (nir_block_dominates(nir_if_first_then_block(nif), use_block)) {
>> +         nir_boolean = NIR_TRUE;
>> +         found = true;
>> +      } else if (nir_block_dominates(nir_if_first_else_block(nif),
>> +                                     use_block)) {
>> +         nir_boolean = NIR_FALSE;
>> +         found = true;
>> +      }
>> +
>> +      if (found) {
>> +         nir_ssa_def *def[2];
>> +         for (unsigned i = 0; i < 2; i++) {
>> +            if (alu->src[i].src.ssa == use_src->ssa) {
>> +               if (if_condition) {
>> +                  b->cursor =
>> +                     nir_before_cf_node(&alu_use->parent_if->cf_node);
>> +               } else {
>> +                  b->cursor = nir_before_instr(alu_use->parent_instr);
>> +               }
>> +
>> +               nir_const_value value;
>> +               value.u32[0] = nir_boolean;
>> +
>> +               def[i] = nir_build_imm(b, 1, 32, value);
>> +            } else {
>> +               def[i] = alu->src[i].src.ssa;
>> +            }
>> +         }
>> +
>> +         nir_ssa_def *nalu =
>> +            nir_build_alu(b, alu->op, def[0], def[1], NULL, NULL);
>> +
>> +         /* Rewrite use to use new alu instruction */
>> +         nir_src new_src = nir_src_for_ssa(nalu);
>> +
>> +         if (if_condition)
>> +            nir_if_rewrite_condition(alu_use->parent_if, new_src);
>> +         else
>> +            nir_instr_rewrite_src(alu_use->parent_instr, alu_use,
>> new_src);
>> +
>> +         progress = true;
>> +      }
>> +   }
>> +
>> +   return progress;
>> +}
>> +
>>  static bool
>> -evaluate_condition_use(nir_if *nif, nir_src *use_src, void *mem_ctx,
>> -                       bool if_condition)
>> +evaluate_condition_use(nir_builder *b, nir_if *nif, nir_src *use_src,
>> +                       void *mem_ctx, bool if_condition)
>>  {
>>     bool progress = false;
>>
>> @@ -428,23 +553,41 @@ evaluate_condition_use(nir_if *nif, nir_src
>> *use_src, void *mem_ctx,
>>        progress = true;
>>     }
>>
>> +   if (!if_condition && use_src->parent_instr->type ==
>> nir_instr_type_alu &&
>> +       (nir_instr_as_alu(use_src->parent_instr)->op == nir_op_ior ||
>> +        nir_instr_as_alu(use_src->parent_instr)->op == nir_op_iand ||
>> +
>> nir_op_infos[nir_instr_as_alu(use_src->parent_instr)->op].num_inputs == 1))
>> {
>> +
>> +         nir_alu_instr *alu = nir_instr_as_alu(use_src->parent_instr);
>> +
>> +         nir_foreach_use_safe(alu_use, &alu->dest.dest.ssa) {
>> +            progress |= propagate_condition_eval(b, nif, use_src,
>> alu_use, alu,
>> +                                                 mem_ctx, false);
>> +         }
>> +
>> +         nir_foreach_if_use_safe(alu_use, &alu->dest.dest.ssa) {
>> +            progress |= propagate_condition_eval(b, nif, use_src,
>> alu_use, alu,
>> +                                                 mem_ctx, true);
>> +         }
>> +   }
>> +
>>     return progress;
>>  }
>>
>>  static bool
>> -opt_if_evaluate_condition_use(nir_if *nif, void *mem_ctx)
>> +opt_if_evaluate_condition_use(nir_builder *b, nir_if *nif, void *mem_ctx)
>>  {
>>     bool progress = false;
>>
>>     /* Evaluate any uses of the if condition inside the if branches */
>>     assert(nif->condition.is_ssa);
>>     nir_foreach_use_safe(use_src, nif->condition.ssa) {
>> -      progress |= evaluate_condition_use(nif, use_src, mem_ctx, false);
>> +      progress |= evaluate_condition_use(b, nif, use_src, mem_ctx,
>> false);
>>     }
>>
>>     nir_foreach_if_use_safe(use_src, nif->condition.ssa) {
>>        if (use_src->parent_if != nif)
>> -         progress |= evaluate_condition_use(nif, use_src, mem_ctx, true);
>> +         progress |= evaluate_condition_use(b, nif, use_src, mem_ctx,
>> true);
>>     }
>>
>>     return progress;
>> @@ -500,7 +643,7 @@ opt_if_safe_cf_list(nir_builder *b, struct exec_list
>> *cf_list, void *mem_ctx)
>>           nir_if *nif = nir_cf_node_as_if(cf_node);
>>           progress |= opt_if_safe_cf_list(b, &nif->then_list, mem_ctx);
>>           progress |= opt_if_safe_cf_list(b, &nif->else_list, mem_ctx);
>> -         progress |= opt_if_evaluate_condition_use(nif, mem_ctx);
>> +         progress |= opt_if_evaluate_condition_use(b, nif, mem_ctx);
>>           break;
>>        }
>>
>> --
>> 2.17.1
>>
>> _______________________________________________
>> 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/20180817/efe62d8d/attachment-0001.html>


More information about the mesa-dev mailing list