GBE: disable mad for some cases.
authorZhigang Gong <zhigang.gong@intel.com>
Thu, 15 May 2014 05:35:00 +0000 (13:35 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Tue, 27 May 2014 01:49:03 +0000 (09:49 +0800)
One case is one operand is an imm value. Then it turns to
save one instruction but add an extra LOADI instruction.
We don't need to bother to use mad in this case.
And considering when we optimize the simd16 under simd8
mode, we

The other case is under simd16 mode. As mad is a 3-src instruction,
which only support simd8, it will convert one mad(16) instruction to
two mad(8) instructions. Then we don't need to use mad.

Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
Reviewed-by: "Yang, Rong R" <rong.r.yang@intel.com>
backend/src/backend/gen_insn_selection.cpp

index f6f2ece..ecbf9df 100644 (file)
@@ -2260,7 +2260,7 @@ namespace gbe
 
       // XXX TODO: we need a clean support of FP_CONTRACT to remove below line 'return false'
       // if 'pragma FP_CONTRACT OFF' is used in cl kernel, we should not do mad optimization.
-      if (!sel.ctx.relaxMath)
+      if (!sel.ctx.relaxMath || sel.ctx.getSimdWidth() == 16)
         return false;
       // MAD tend to increase liveness of the sources (since there are three of
       // them). TODO refine this strategy. Well, we should be able at least to
@@ -2278,6 +2278,12 @@ namespace gbe
       const GenRegister dst = sel.selReg(insn.getDst(0), TYPE_FLOAT);
       if (child0 && child0->insn.getOpcode() == OP_MUL) {
         GBE_ASSERT(cast<ir::BinaryInstruction>(child0->insn).getType() == TYPE_FLOAT);
+        SelectionDAG *child00 = child0->child[0];
+        SelectionDAG *child01 = child0->child[1];
+        if ((child00 && child00->insn.getOpcode() == OP_LOADI) ||
+            (child01 && child01->insn.getOpcode() == OP_LOADI) ||
+            (child1 && child1->insn.getOpcode() == OP_LOADI))
+          return false;
         const GenRegister src0 = sel.selReg(child0->insn.getSrc(0), TYPE_FLOAT);
         const GenRegister src1 = sel.selReg(child0->insn.getSrc(1), TYPE_FLOAT);
         GenRegister src2 = sel.selReg(insn.getSrc(1), TYPE_FLOAT);
@@ -2290,6 +2296,12 @@ namespace gbe
       }
       if (child1 && child1->insn.getOpcode() == OP_MUL) {
         GBE_ASSERT(cast<ir::BinaryInstruction>(child1->insn).getType() == TYPE_FLOAT);
+        SelectionDAG *child10 = child1->child[0];
+        SelectionDAG *child11 = child1->child[1];
+        if ((child10 && child10->insn.getOpcode() == OP_LOADI) ||
+            (child11 && child11->insn.getOpcode() == OP_LOADI) ||
+            (child0 && child0->insn.getOpcode() == OP_LOADI))
+          return false;
         GenRegister src0 = sel.selReg(child1->insn.getSrc(0), TYPE_FLOAT);
         const GenRegister src1 = sel.selReg(child1->insn.getSrc(1), TYPE_FLOAT);
         const GenRegister src2 = sel.selReg(insn.getSrc(0), TYPE_FLOAT);