<div dir="ltr">Ugh... Now that I think about it more, my suggestions on the previous patch conflict quite a bit. :( Let me think some more.<br></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Aug 17, 2018 at 2:27 PM Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>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.)</div><div><br></div><div>--Jason<br></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Jul 23, 2018 at 3:02 AM Timothy Arceri <<a href="mailto:tarceri@itsqueeze.com" target="_blank">tarceri@itsqueeze.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">shader-db IVB results:<br>
<br>
total instructions in shared programs: 9993483 -> 9993472 (-0.00%)<br>
instructions in affected programs: 1300 -> 1289 (-0.85%)<br>
helped: 11<br>
HURT: 0<br>
<br>
total cycles in shared programs: 219476091 -> 219476059 (-0.00%)<br>
cycles in affected programs: 7675 -> 7643 (-0.42%)<br>
helped: 10<br>
HURT: 1<br>
---<br>
src/compiler/nir/nir_opt_if.c | 155 ++++++++++++++++++++++++++++++++--<br>
1 file changed, 149 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/src/compiler/nir/nir_opt_if.c b/src/compiler/nir/nir_opt_if.c<br>
index b3d5046a76e..c9e50cec1fe 100644<br>
--- a/src/compiler/nir/nir_opt_if.c<br>
+++ b/src/compiler/nir/nir_opt_if.c<br>
@@ -404,9 +404,134 @@ replace_if_condition_use_with_const(nir_src *use, unsigned nir_boolean,<br>
nir_instr_rewrite_src(use->parent_instr, use, new_src);<br>
}<br>
<br>
+/*<br>
+ * This propagates if condition evaluation down the chain of some alu<br>
+ * instructions. For example by checking the use of some of the following alu<br>
+ * instruction we can eventually replace ssa_107 with NIR_TRUE.<br>
+ *<br>
+ * loop {<br>
+ * block block_1:<br>
+ * vec1 32 ssa_85 = load_const (0x00000002)<br>
+ * vec1 32 ssa_86 = ieq ssa_48, ssa_85<br>
+ * vec1 32 ssa_87 = load_const (0x00000001)<br>
+ * vec1 32 ssa_88 = ieq ssa_48, ssa_87<br>
+ * vec1 32 ssa_89 = ior ssa_86, ssa_88<br>
+ * vec1 32 ssa_90 = ieq ssa_48, ssa_0<br>
+ * vec1 32 ssa_91 = ior ssa_89, ssa_90<br>
+ * if ssa_86 {<br>
+ * block block_2:<br>
+ * ...<br>
+ * break<br>
+ * } else {<br>
+ * block block_3:<br>
+ * }<br>
+ * block block_4:<br>
+ * if ssa_88 {<br>
+ * block block_5:<br>
+ * ...<br>
+ * break<br>
+ * } else {<br>
+ * block block_6:<br>
+ * }<br>
+ * block block_7:<br>
+ * if ssa_90 {<br>
+ * block block_8:<br>
+ * ...<br>
+ * break<br>
+ * } else {<br>
+ * block block_9:<br>
+ * }<br>
+ * block block_10:<br>
+ * vec1 32 ssa_107 = inot ssa_91<br>
+ * if ssa_107 {<br>
+ * block block_11:<br>
+ * break<br>
+ * } else {<br>
+ * block block_12:<br>
+ * }<br>
+ * }<br>
+ */<br>
+static bool<br>
+propagate_condition_eval(nir_builder *b, nir_if *nif, nir_src *use_src,<br>
+ nir_src *alu_use, nir_alu_instr *alu, void *mem_ctx,<br>
+ bool if_condition)<br>
+{<br>
+ bool progress = false;<br>
+<br>
+ nir_block *use_block;<br>
+ if (if_condition) {<br>
+ use_block =<br>
+ nir_cf_node_as_block(nir_cf_node_prev(&alu_use->parent_if->cf_node));<br>
+ } else {<br>
+ use_block = alu_use->parent_instr->block;<br>
+ }<br>
+<br>
+ if (nir_op_infos[alu->op].num_inputs == 1) {<br>
+ if (nir_block_dominates(nir_if_first_then_block(nif), use_block)) {<br>
+ replace_if_condition_use_with_const(alu_use, NIR_TRUE, mem_ctx,<br>
+ if_condition);<br>
+ progress = true;<br>
+ } else if (nir_block_dominates(nir_if_first_else_block(nif),<br>
+ use_block)) {<br>
+ replace_if_condition_use_with_const(alu_use, NIR_FALSE, mem_ctx,<br>
+ if_condition);<br>
+ progress = true;<br>
+ }<br>
+ } else {<br>
+ assert(alu->op == nir_op_ior || alu->op == nir_op_iand);<br>
+<br>
+ bool found = false;<br>
+ unsigned nir_boolean = 0;<br>
+ if (nir_block_dominates(nir_if_first_then_block(nif), use_block)) {<br>
+ nir_boolean = NIR_TRUE;<br>
+ found = true;<br>
+ } else if (nir_block_dominates(nir_if_first_else_block(nif),<br>
+ use_block)) {<br>
+ nir_boolean = NIR_FALSE;<br>
+ found = true;<br>
+ }<br>
+<br>
+ if (found) {<br>
+ nir_ssa_def *def[2];<br>
+ for (unsigned i = 0; i < 2; i++) {<br>
+ if (alu->src[i].src.ssa == use_src->ssa) {<br>
+ if (if_condition) {<br>
+ b->cursor =<br>
+ nir_before_cf_node(&alu_use->parent_if->cf_node);<br>
+ } else {<br>
+ b->cursor = nir_before_instr(alu_use->parent_instr);<br>
+ }<br>
+<br>
+ nir_const_value value;<br>
+ value.u32[0] = nir_boolean;<br>
+<br>
+ def[i] = nir_build_imm(b, 1, 32, value);<br>
+ } else {<br>
+ def[i] = alu->src[i].src.ssa;<br>
+ }<br>
+ }<br>
+<br>
+ nir_ssa_def *nalu =<br>
+ nir_build_alu(b, alu->op, def[0], def[1], NULL, NULL);<br>
+<br>
+ /* Rewrite use to use new alu instruction */<br>
+ nir_src new_src = nir_src_for_ssa(nalu);<br>
+<br>
+ if (if_condition)<br>
+ nir_if_rewrite_condition(alu_use->parent_if, new_src);<br>
+ else<br>
+ nir_instr_rewrite_src(alu_use->parent_instr, alu_use, new_src);<br>
+<br>
+ progress = true;<br>
+ }<br>
+ }<br>
+<br>
+ return progress;<br>
+}<br>
+<br>
static bool<br>
-evaluate_condition_use(nir_if *nif, nir_src *use_src, void *mem_ctx,<br>
- bool if_condition)<br>
+evaluate_condition_use(nir_builder *b, nir_if *nif, nir_src *use_src,<br>
+ void *mem_ctx, bool if_condition)<br>
{<br>
bool progress = false;<br>
<br>
@@ -428,23 +553,41 @@ evaluate_condition_use(nir_if *nif, nir_src *use_src, void *mem_ctx,<br>
progress = true;<br>
}<br>
<br>
+ if (!if_condition && use_src->parent_instr->type == nir_instr_type_alu &&<br>
+ (nir_instr_as_alu(use_src->parent_instr)->op == nir_op_ior ||<br>
+ nir_instr_as_alu(use_src->parent_instr)->op == nir_op_iand ||<br>
+ nir_op_infos[nir_instr_as_alu(use_src->parent_instr)->op].num_inputs == 1)) {<br>
+<br>
+ nir_alu_instr *alu = nir_instr_as_alu(use_src->parent_instr);<br>
+<br>
+ nir_foreach_use_safe(alu_use, &alu->dest.dest.ssa) {<br>
+ progress |= propagate_condition_eval(b, nif, use_src, alu_use, alu,<br>
+ mem_ctx, false);<br>
+ }<br>
+<br>
+ nir_foreach_if_use_safe(alu_use, &alu->dest.dest.ssa) {<br>
+ progress |= propagate_condition_eval(b, nif, use_src, alu_use, alu,<br>
+ mem_ctx, true);<br>
+ }<br>
+ }<br>
+<br>
return progress;<br>
}<br>
<br>
static bool<br>
-opt_if_evaluate_condition_use(nir_if *nif, void *mem_ctx)<br>
+opt_if_evaluate_condition_use(nir_builder *b, nir_if *nif, void *mem_ctx)<br>
{<br>
bool progress = false;<br>
<br>
/* Evaluate any uses of the if condition inside the if branches */<br>
assert(nif->condition.is_ssa);<br>
nir_foreach_use_safe(use_src, nif->condition.ssa) {<br>
- progress |= evaluate_condition_use(nif, use_src, mem_ctx, false);<br>
+ progress |= evaluate_condition_use(b, nif, use_src, mem_ctx, false);<br>
}<br>
<br>
nir_foreach_if_use_safe(use_src, nif->condition.ssa) {<br>
if (use_src->parent_if != nif)<br>
- progress |= evaluate_condition_use(nif, use_src, mem_ctx, true);<br>
+ progress |= evaluate_condition_use(b, nif, use_src, mem_ctx, true);<br>
}<br>
<br>
return progress;<br>
@@ -500,7 +643,7 @@ opt_if_safe_cf_list(nir_builder *b, struct exec_list *cf_list, void *mem_ctx)<br>
nir_if *nif = nir_cf_node_as_if(cf_node);<br>
progress |= opt_if_safe_cf_list(b, &nif->then_list, mem_ctx);<br>
progress |= opt_if_safe_cf_list(b, &nif->else_list, mem_ctx);<br>
- progress |= opt_if_evaluate_condition_use(nif, mem_ctx);<br>
+ progress |= opt_if_evaluate_condition_use(b, nif, mem_ctx);<br>
break;<br>
}<br>
<br>
-- <br>
2.17.1<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div>
</blockquote></div>