[Beignet] [PATCH 7/8] GBE: Fix one DAG analysis issue and enable multiple round phi copy elimination.

Zhigang Gong zhigang.gong at intel.com
Tue Sep 22 21:44:53 PDT 2015


Even if one value is killed in current BB, we still need to
pass predecessor's definition into this BB. Otherwise, we will
miss one definition.

BB0:
  MOV %foo, %src0

BB1:
  MUL %foo, %src1, %f00
  ...
  BR BB1

In the above case, both BB1 and BB0 are the predecessors of BB1.
When pass the definition of %foo in BB0 to BB1, the previous implementation
will ignore it because %foo is killed in BB1, this is a bug.
This patch fixes it. And thus we can enable multiple round
phi copy elimination safely.

v2:
also need to fix the same issue for special registers and kernel
arguments.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/ir/value.cpp              | 8 ++++----
 backend/src/llvm/llvm_gen_backend.cpp | 1 -
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/backend/src/ir/value.cpp b/backend/src/ir/value.cpp
index d2f0c2e..d5215cb 100644
--- a/backend/src/ir/value.cpp
+++ b/backend/src/ir/value.cpp
@@ -190,7 +190,7 @@ namespace ir {
       // Do not transfer dead values
       if (info.inLiveOut(reg) == false) continue;
       // If we overwrite it, do not transfer the initial value
-      if (info.inVarKill(reg) == true) continue;
+      if ((info.inVarKill(reg) == true) && (info.inUpwardUsed(reg))) continue;
       ValueDef *def = const_cast<ValueDef*>(this->dag.getDefAddress(&arg));
       auto it = blockDefMap->find(reg);
       GBE_ASSERT(it != blockDefMap->end());
@@ -205,7 +205,7 @@ namespace ir {
       // Do not transfer dead values
       if (info.inLiveOut(reg) == false) continue;
       // If we overwrite it, do not transfer the initial value
-      if (info.inVarKill(reg) == true) continue;
+      if ((info.inVarKill(reg) == true) && (info.inUpwardUsed(reg))) continue;
       ValueDef *def = const_cast<ValueDef*>(this->dag.getDefAddress(reg));
       auto it = blockDefMap->find(reg);
       GBE_ASSERT(it != blockDefMap->end());
@@ -219,7 +219,7 @@ namespace ir {
       // Do not transfer dead values
       if (info.inLiveOut(reg) == false) continue;
       // If we overwrite it, do not transfer the initial value
-      if (info.inVarKill(reg) == true) continue;
+      if ((info.inVarKill(reg) == true) && (info.inUpwardUsed(reg))) continue;
       ValueDef *def = const_cast<ValueDef*>(this->dag.getDefAddress(&pushed.second));
       auto it = blockDefMap->find(reg);
       GBE_ASSERT(it != blockDefMap->end());
@@ -242,7 +242,7 @@ namespace ir {
         const BasicBlock &pbb = pred.bb;
         for (auto reg : curr.liveOut) {
           if (pred.inLiveOut(reg) == false) continue;
-          if (curr.inVarKill(reg) == true) continue;
+          if (curr.inVarKill(reg) == true && curr.inUpwardUsed(reg) == false) continue;
           RegDefSet &currSet = this->getDefSet(&bb, reg);
           RegDefSet &predSet = this->getDefSet(&pbb, reg);
 
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index e964eb3..2cdfb0f 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -2405,7 +2405,6 @@ namespace gbe
       } else
         break;
 
-      break;
       nextRedundant->clear();
       replacedRegs.clear();
       revReplacedRegs.clear();
-- 
1.9.1



More information about the Beignet mailing list