i965/fs: Skip emitting MACH/MOV for small integers.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 7 Apr 2014 01:38:46 +0000 (18:38 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 8 Apr 2014 07:01:55 +0000 (00:01 -0700)
The vector backend already implemented this optimization, but
surprisingly, we never bothered to implement it in the scalar backend.

In addition to saving two instructions, this eliminates a use of the
accumulator as an explicit source, which is unsupported in SIMD16 mode
on Gen7+, which could help us gain SIMD16 programs.

Cuts 19.23% of the instructions in dolphin/efb2ram.shader_test.

v2: Rebase on is_16bit_integer_constant -> is_uint16_constant rename.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
src/mesa/drivers/dri/i965/brw_fs_visitor.cpp

index ce6d3dad1e59b9a8b783274d5c7c8934f5513452..c89f4d6a05ddc21081b2b8407de047e4affc2799 100644 (file)
@@ -458,18 +458,27 @@ fs_visitor::visit(ir_expression *ir)
          * of one of the operands (src0 on gen6, src1 on gen7).  The
          * MACH accumulates in the contribution of the upper 16 bits
          * of that operand.
-         *
-         * FINISHME: Emit just the MUL if we know an operand is small
-         * enough.
-         */
-        if (brw->gen >= 7)
-           no16("SIMD16 explicit accumulator operands unsupported\n");
-
-        struct brw_reg acc = retype(brw_acc_reg(), this->result.type);
-
-        emit(MUL(acc, op[0], op[1]));
-        emit(MACH(reg_null_d, op[0], op[1]));
-        emit(MOV(this->result, fs_reg(acc)));
+          */
+         if (ir->operands[0]->is_uint16_constant()) {
+            if (brw->gen < 7)
+               emit(MUL(this->result, op[0], op[1]));
+            else
+               emit(MUL(this->result, op[1], op[0]));
+         } else if (ir->operands[1]->is_uint16_constant()) {
+            if (brw->gen < 7)
+               emit(MUL(this->result, op[1], op[0]));
+            else
+               emit(MUL(this->result, op[0], op[1]));
+         } else {
+            if (brw->gen >= 7)
+               no16("SIMD16 explicit accumulator operands unsupported\n");
+
+            struct brw_reg acc = retype(brw_acc_reg(), this->result.type);
+
+            emit(MUL(acc, op[0], op[1]));
+            emit(MACH(reg_null_d, op[0], op[1]));
+            emit(MOV(this->result, fs_reg(acc)));
+         }
       } else {
         emit(MUL(this->result, op[0], op[1]));
       }