GBE: Optimize byte gather read using untyped read.
authorRuiling Song <ruiling.song@intel.com>
Wed, 23 Apr 2014 02:56:50 +0000 (10:56 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Wed, 23 Apr 2014 05:44:02 +0000 (13:44 +0800)
Untyped read seems better than byte gather read.
Some performance test in opencv got doubled after the patch.

Signed-off-by: Ruiling Song <ruiling.song@intel.com>
backend/src/backend/gen_insn_selection.cpp

index bcbf115..8c7ac09 100644 (file)
@@ -2594,19 +2594,22 @@ namespace gbe
       } else {
         GBE_ASSERT(insn.getValueNum() == 1);
         const GenRegister value = sel.selReg(insn.getValue(0));
-        // We need a temporary register if we read bytes or words
-        Register dst = Register(value.value.reg);
-        if (elemSize == GEN_BYTE_SCATTER_WORD ||
-            elemSize == GEN_BYTE_SCATTER_BYTE) {
-          dst = sel.reg(FAMILY_DWORD);
-          sel.BYTE_GATHER(GenRegister::fxgrf(simdWidth, dst), address, elemSize, bti);
-        }
-
-        // Repack bytes or words using a converting mov instruction
+        GBE_ASSERT(elemSize == GEN_BYTE_SCATTER_WORD || elemSize == GEN_BYTE_SCATTER_BYTE);
+
+        Register tmpReg = sel.reg(FAMILY_DWORD);
+        GenRegister tmpAddr = GenRegister::udxgrf(simdWidth, sel.reg(FAMILY_DWORD));
+        GenRegister tmpData = GenRegister::udxgrf(simdWidth, tmpReg);
+        // Get dword aligned addr
+        sel.AND(tmpAddr, GenRegister::retype(address,GEN_TYPE_UD), GenRegister::immud(0xfffffffc));
+        sel.UNTYPED_READ(tmpAddr, &tmpData, 1, bti);
+        // Get the remaining offset from aligned addr
+        sel.AND(tmpAddr, GenRegister::retype(address,GEN_TYPE_UD), GenRegister::immud(0x3));
+        sel.SHL(tmpAddr, tmpAddr, GenRegister::immud(0x3));
+        sel.SHR(tmpData, tmpData, tmpAddr);
         if (elemSize == GEN_BYTE_SCATTER_WORD)
-          sel.MOV(GenRegister::retype(value, GEN_TYPE_UW), GenRegister::unpacked_uw(dst));
+          sel.MOV(GenRegister::retype(value, GEN_TYPE_UW), GenRegister::unpacked_uw(tmpReg));
         else if (elemSize == GEN_BYTE_SCATTER_BYTE)
-          sel.MOV(GenRegister::retype(value, GEN_TYPE_UB), GenRegister::unpacked_ub(dst));
+          sel.MOV(GenRegister::retype(value, GEN_TYPE_UB), GenRegister::unpacked_ub(tmpReg));
       }
     }