[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:27:50 UTC 2018
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/51b3ca0a/attachment-0001.html>
More information about the mesa-dev
mailing list