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 <[email protected]> --- 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 _______________________________________________ Beignet mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/beignet
