GBE: Fix live range for temporary register in replaceReg
authorRuiling Song <ruiling.song@intel.com>
Tue, 4 Nov 2014 07:22:40 +0000 (15:22 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Tue, 4 Nov 2014 07:24:36 +0000 (15:24 +0800)
previously it is simply assigned as [insnID, insnID], But it is used in 2 instruction:
[1] MOV tmp, replacedReg
[2] send null, addr, tmp,...

As minID maxID is equal, it will be treated as temporary register during spill,
and no scratch memory allocated. But scratch register is allocated per instruction,
if tmp in [1] is assigned g100 from spill register pool, instruction [2] would have no idea of that,
it will assign another register like g102 from spill register pool. As no scratch memory allocated,
we cannnot do any spill/unspill operation between them.

To fix this issue, I change the liveness range according to isSrc, so spill/unspill
could work as normally.

This patch fix the cos16 test case failure in piglit under strict conformance.

Signed-off-by: Ruiling Song <ruiling.song@intel.com>
Reviewed-by: Zhigang Gong <zhigang.gong@linux.intel.com>
backend/src/backend/gen_reg_allocation.cpp

index a57edb3..ef519d9 100644 (file)
@@ -194,13 +194,17 @@ namespace gbe
                                    uint32_t regID, bool isSrc,
                                    ir::Type type = ir::TYPE_FLOAT, bool needMov = true) {
       ir::Register reg;
-      if (isSrc)
+      if (isSrc) {
         reg = sel.replaceSrc(insn, regID, type, needMov);
-      else
+        intervals.push_back(reg);
+        intervals[reg].minID = insn->ID - 1;
+        intervals[reg].maxID = insn->ID;
+      } else {
         reg = sel.replaceDst(insn, regID, type, needMov);
-      intervals.push_back(reg);
-      intervals[reg].minID = insn->ID;
-      intervals[reg].maxID = insn->ID;
+        intervals.push_back(reg);
+        intervals[reg].minID = insn->ID;
+        intervals[reg].maxID = insn->ID + 1;
+      }
       return reg;
     }
     /*! Use custom allocator */