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 <ja...@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 <tarc...@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@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/mesa-dev >> >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev