<div dir="ltr">On 4 November 2013 10:31, Eric Anholt <span dir="ltr"><<a href="mailto:eric@anholt.net" target="_blank">eric@anholt.net</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div class="im">Matt Turner <<a href="mailto:mattst88@gmail.com">mattst88@gmail.com</a>> writes:<br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp b/src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp<br>
> new file mode 100644<br>
> index 0000000..9626751<br>
> --- /dev/null<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs_sel_peephole.cpp<br>
<br>
</div><div><div class="h5">> +bool<br>
> +fs_visitor::opt_peephole_sel()<br>
> +{<br>
> + bool progress = false;<br>
> +<br>
> + cfg_t cfg(this);<br>
> +<br>
> + for (int b = 0; b < cfg.num_blocks; b++) {<br>
> + bblock_t *block = cfg.blocks[b];<br>
> +<br>
> + /* IF instructions, by definition, can only be found at the ends of<br>
> + * basic blocks.<br>
> + */<br>
> + fs_inst *if_inst = (fs_inst *) block->end;<br>
> + if (if_inst->opcode != BRW_OPCODE_IF)<br>
> + continue;<br>
> +<br>
> + if (!block->else_inst)<br>
> + continue;<br>
> +<br>
> + fs_inst *else_inst = (fs_inst *) block->else_inst;<br>
> +<br>
> + fs_inst *else_mov[MAX_MOVS] = { NULL };<br>
> + fs_inst *then_mov[MAX_MOVS] = { NULL };<br>
> + bool malformed_mov_found = false;<br>
> +<br>
> + int movs = count_movs_from_if(then_mov, else_mov, if_inst, else_inst);<br>
> +<br>
> + if (movs == 0)<br>
> + continue;<br>
> +<br>
> + fs_inst *sel_inst[MAX_MOVS] = { NULL };<br>
> + fs_inst *mov_imm_inst[MAX_MOVS] = { NULL };<br>
> +<br>
> + /* Generate SEL instructions for pairs of MOVs to a common destination. */<br>
> + for (int i = 0; i < movs; i++) {<br>
> + if (!then_mov[i] || !else_mov[i])<br>
> + break;<br>
> +<br>
> + /* Check that the MOVs are the right form. */<br>
> + if (!then_mov[i]->dst.equals(else_mov[i]->dst) ||<br>
> + then_mov[i]->is_partial_write() ||<br>
> + else_mov[i]->is_partial_write()) {<br>
> + malformed_mov_found = true;<br>
> + break;<br>
> + }<br>
> +<br>
> + /* Only the last source register can be a constant, so if the MOV in<br>
> + * the "then" clause uses a constant, we need to put it in a<br>
> + * temporary.<br>
> + */<br>
> + fs_reg src0(then_mov[i]->src[0]);<br>
> + if (src0.file == IMM) {<br>
> + src0 = fs_reg(this, glsl_type::float_type);<br>
> + src0.type = then_mov[i]->src[0].type;<br>
> + mov_imm_inst[i] = MOV(src0, then_mov[i]->src[0]);<br>
> + }<br>
> +<br>
> + sel_inst[i] = SEL(then_mov[i]->dst, src0, else_mov[i]->src[0]);<br>
> +<br>
> + if (brw->gen == 6 && if_inst->conditional_mod) {<br>
> + /* For Sandybridge with IF with embedded comparison */<br>
> + sel_inst[i]->predicate = BRW_PREDICATE_NORMAL;<br>
> + } else {<br>
> + /* Separate CMP and IF instructions */<br>
> + sel_inst[i]->predicate = if_inst->predicate;<br>
> + sel_inst[i]->predicate_inverse = if_inst->predicate_inverse;<br>
> + }<br>
> + }<br>
> +<br>
> + if (malformed_mov_found)<br>
> + continue;<br>
> +<br>
> + /* Emit a CMP if our IF used the embedded comparison */<br>
> + if (brw->gen == 6 && if_inst->conditional_mod) {<br>
> + fs_inst *cmp_inst = CMP(reg_null_d, if_inst->src[0], if_inst->src[1],<br>
> + if_inst->conditional_mod);<br>
> + if_inst->insert_before(cmp_inst);<br>
> + }<br>
<br>
</div></div>If the IF is using embedded comparison, then our MOVs that we've moved<br>
before it might be updating the registers used in the embedded<br>
comparsion.<br>
</blockquote><div><br></div><div>I think this is ok, because we don't move any MOVs before we get to this code. We just set up the sel_inst and mov_imm_inst arrays. The MOVs don't get added to the instruction stream until after this code, so they appear after the CMP, and stuff should still happen in the correct order.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
I'd be fine with either adding it to the malformed mov check, or just<br>
dropping support for embedded comparisons.<br>
<br>_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
<br></blockquote></div><br></div></div>