[Beignet] [Patch V2] GBE: fix a src/dst register reuse bug.

Yang Rong rong.r.yang at intel.com
Fri Dec 30 04:38:57 UTC 2016


From: "Yang, Rong R" <rong.r.yang at intel.com>

For case:
 mad(8)          g4<1>:F         g4.1<0,1,0>:F   g127.7<0,1,0>:F g46:F
 mad(8)          g5<1>:F         g4.1<0,1,0>:F   g127.7<0,1,0>:F g47:F
src0 is uniform, dst is non-uniform, dst can't reuse the src0.

V2: check the all region field.

Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
 backend/src/backend/gen_insn_selection.cpp | 13 +++++++++++++
 backend/src/backend/gen_insn_selection.hpp |  2 ++
 backend/src/backend/gen_reg_allocation.cpp |  4 +++-
 backend/src/backend/gen_register.hpp       |  8 ++++++++
 4 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index dd21960..53a9d97 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -234,6 +234,19 @@ namespace gbe
     return this->opcode == SEL_OP_LABEL;
   }
 
+  bool SelectionInstruction::sameAsDstRegion(uint32_t srcID) {
+    assert(srcID < srcNum);
+    if (dstNum == 0)
+      return true;
+    GenRegister &srcReg = this->src(srcID);
+    for (uint32_t dstID = 0; dstID < dstNum; ++dstID) {
+      const GenRegister &dstReg = this->dst(dstID);
+      if (!dstReg.isSameRegion(srcReg))
+        return false;
+    }
+    return true;
+  }
+
   bool SelectionInstruction::isNative(void) const {
     return this->opcode == SEL_OP_NOT         || /* ALU1 */
            this->opcode == SEL_OP_LZD         ||
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 01999a2..89d28f2 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -82,6 +82,8 @@ namespace gbe
     bool isBranch(void) const;
     /*! Is it a label instruction (i.e. change the implicit mask) */
     bool isLabel(void) const;
+    /*! Is the src's gen register region is same as all dest regs' region  */
+    bool sameAsDstRegion(uint32_t srcID);
     /*! Is it a simple navtive instruction (i.e. will be one simple ISA) */
     bool isNative(void) const;
     /*! Get the destination register */
diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp
index 2b76eee..6dd570d 100644
--- a/backend/src/backend/gen_reg_allocation.cpp
+++ b/backend/src/backend/gen_reg_allocation.cpp
@@ -1267,7 +1267,9 @@ namespace gbe
           this->intervals[reg].conflictReg = conflictReg;
           int insnsrcID = insnID;
           // If instruction is simple, src and dst can be reused and they will have different IDs
-          if (insn.isNative())
+          // insn may be split in the encoder, if register region are not same, can't be reused.
+          // Because hard to check split or not here, so only check register regio.
+          if (insn.isNative() && insn.sameAsDstRegion(srcID))
             insnsrcID -= 1;
           this->intervals[reg].minID = std::min(this->intervals[reg].minID, insnsrcID);
           this->intervals[reg].maxID = std::max(this->intervals[reg].maxID, insnsrcID);
diff --git a/backend/src/backend/gen_register.hpp b/backend/src/backend/gen_register.hpp
index d9798cf..6c73f5e 100644
--- a/backend/src/backend/gen_register.hpp
+++ b/backend/src/backend/gen_register.hpp
@@ -293,6 +293,14 @@ namespace gbe
       return r;
     }
 
+    INLINE bool isSameRegion(GenRegister reg) const {
+      return reg.file == file &&
+             typeSize(reg.type) == typeSize(type) &&
+             reg.vstride == vstride &&
+             reg.width == width &&
+             reg.hstride == hstride;
+    }
+
     static INLINE uint32_t grfOffset(GenRegister reg) {
       return reg.nr * GEN_REG_SIZE + reg.subnr;
     }
-- 
2.1.4



More information about the Beignet mailing list