[Beignet] [PATCH] GBE: handle dead loop BBs in liveness analysis.

Zhigang Gong zhigang.gong at intel.com
Thu Oct 23 19:10:16 PDT 2014


Considering the following CFG, our previous liveness analysis will only
back traverse from the exit point BB, thus the BB 6 and 7 will not be handled.

    4---
    |   |
    |   |
    5 --|---> 10 ---> ret
    |   |
    |   |
    6<--
    |
    |<--
    7   |
    |   |
     ---

Although the CFG looks not a normal application as once it goes to
block 6, it will enter a dead loop and will never return, we still need
to compile it successfully.

This patch is to fix the bug at:
https://bugs.freedesktop.org/show_bug.cgi?id=85362

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/ir/liveness.cpp | 11 ++++++++++-
 backend/src/ir/liveness.hpp |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/backend/src/ir/liveness.cpp b/backend/src/ir/liveness.cpp
index eaf6728..35b935f 100644
--- a/backend/src/ir/liveness.cpp
+++ b/backend/src/ir/liveness.cpp
@@ -41,7 +41,11 @@ namespace ir {
       }
     });
     // Now with iterative analysis, we compute liveout and livein sets
-    this->computeLiveInOut();
+    while (unvisitBlocks.size()) {
+      if (workSet.size() == 0)
+        workSet.insert(--unvisitBlocks.end(), unvisitBlocks.end());
+      this->computeLiveInOut();
+    }
     // extend register (def in loop, use out-of-loop) liveness to the whole loop
     set<Register> extentRegs;
     this->computeExtraLiveInOut(extentRegs);
@@ -98,6 +102,7 @@ namespace ir {
       this->initInstruction(*info, insn);
     });
     liveness[&bb] = info;
+    unvisitBlocks.insert(info);
     if(!bb.liveout.empty())
       info->liveOut.insert(bb.liveout.begin(), bb.liveout.end());
   }
@@ -124,12 +129,16 @@ namespace ir {
     while(!workSet.empty()) {
       auto currInfo = *workSet.begin();
       workSet.erase(currInfo);
+      if (unvisitBlocks.find(currInfo) != unvisitBlocks.end())
+        unvisitBlocks.erase(currInfo);
       for (auto currOutVar : currInfo->liveOut)
         if (!currInfo->varKill.contains(currOutVar))
           currInfo->upwardUsed.insert(currOutVar);
       bool isChanged = false;
       for (auto prev : currInfo->bb.getPredecessorSet()) {
         BlockInfo *prevInfo = liveness[prev];
+        if (unvisitBlocks.find(currInfo) != unvisitBlocks.end())
+          unvisitBlocks.erase(currInfo);
         for (auto currInVar : currInfo->upwardUsed) {
           if (!prevInfo->bb.undefPhiRegs.contains(currInVar)) {
             auto changed = prevInfo->liveOut.insert(currInVar);
diff --git a/backend/src/ir/liveness.hpp b/backend/src/ir/liveness.hpp
index d55e00d..d1e1a53 100644
--- a/backend/src/ir/liveness.hpp
+++ b/backend/src/ir/liveness.hpp
@@ -132,6 +132,7 @@ namespace ir {
     /*! Set of work list block which has exit(return) instruction */
     typedef set <struct BlockInfo*> WorkSet;
     WorkSet workSet;
+    WorkSet unvisitBlocks;
 
     /*! Use custom allocators */
     GBE_CLASS(Liveness);
-- 
1.8.3.2



More information about the Beignet mailing list