[Mesa-dev] [PATCH 2/2] i965: Emit smarter code for b2i of a comparison
Chris Forbes
chrisf at ijw.co.nz
Tue Jun 10 21:16:49 PDT 2014
s/b2i/b2f/ in the commit message
On Wed, Jun 11, 2014 at 2:13 PM, Ian Romanick <idr at freedesktop.org> wrote:
> From: Ian Romanick <ian.d.romanick at intel.com>
>
> Previously we would emit the comparison, emit an AND to mask off extra
> bits from the comparison result, then convert the result to float. Now,
> do the comparison, then use a cleverly constructed SEL to pick either
> 0.0f or 1.0f.
>
> No piglit regressions on Ivybridge.
>
> NOTE: I have not yet tested actual application performance. I'll do
> that tomorrow.
>
> total instructions in shared programs: 1642311 -> 1639449 (-0.17%)
> instructions in affected programs: 136533 -> 133671 (-2.10%)
> GAINED: 0
> LOST: 0
>
> Programs that are affected appear to save between 1 and 5 instuctions
> (just by skimming the output from shader-db report.py.
>
> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
> ---
> src/mesa/drivers/dri/i965/brw_vec4.h | 1 +
> src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp | 47 ++++++++++++++++++++++++++
> 2 files changed, 48 insertions(+)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4.h b/src/mesa/drivers/dri/i965/brw_vec4.h
> index c2bbd68..27e1e39 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4.h
> +++ b/src/mesa/drivers/dri/i965/brw_vec4.h
> @@ -587,6 +587,7 @@ public:
>
> bool try_emit_sat(ir_expression *ir);
> bool try_emit_mad(ir_expression *ir);
> + bool try_emit_b2f_of_compare(ir_expression *ir);
> void resolve_ud_negate(src_reg *reg);
>
> src_reg get_timestamp();
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> index 249072c..902f02d 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
> @@ -1126,6 +1126,48 @@ vec4_visitor::try_emit_mad(ir_expression *ir)
> return true;
> }
>
> +bool
> +vec4_visitor::try_emit_b2f_of_compare(ir_expression *ir)
> +{
> + ir_expression *const cmp = ir->operands[0]->as_expression();
> +
> + if (cmp == NULL)
> + return false;
> +
> + switch (cmp->operation) {
> + case ir_binop_less:
> + case ir_binop_greater:
> + case ir_binop_lequal:
> + case ir_binop_gequal:
> + case ir_binop_equal:
> + case ir_binop_nequal:
> + break;
> +
> + default:
> + return false;
> + }
> +
> + cmp->operands[0]->accept(this);
> + const src_reg cmp_src0 = this->result;
> +
> + cmp->operands[1]->accept(this);
> + const src_reg cmp_src1 = this->result;
> +
> + this->result = src_reg(this, ir->type);
> +
> + emit(CMP(dst_reg(this->result), cmp_src0, cmp_src1,
> + brw_conditional_for_comparison(cmp->operation)));
> +
> + /* If the comparison is false, this->result will just happen to be zero.
> + */
> + vec4_instruction *const inst = emit(BRW_OPCODE_SEL, dst_reg(this->result),
> + fix_3src_operand(src_reg(1.0f)),
> + this->result);
> + inst->predicate = BRW_PREDICATE_NORMAL;
> +
> + return true;
> +}
> +
> void
> vec4_visitor::emit_bool_comparison(unsigned int op,
> dst_reg dst, src_reg src0, src_reg src1)
> @@ -1202,6 +1244,11 @@ vec4_visitor::visit(ir_expression *ir)
> return;
> }
>
> + if (ir->operation == ir_unop_b2f) {
> + if (try_emit_b2f_of_compare(ir))
> + return;
> + }
> +
> for (operand = 0; operand < ir->get_num_operands(); operand++) {
> this->result.file = BAD_FILE;
> ir->operands[operand]->accept(this);
> --
> 1.8.1.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list