[Beignet] [Patch v2] GBE: refine longjmp checking.

Zhigang Gong zhigang.gong at intel.com
Thu Sep 24 17:49:50 PDT 2015


v2:
simplify the logic in function.hpp. Let the user to
prepare correct start and end point. Fix the incorrect
start/end point for one forward jump and one backward
jump case.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/backend/gen_insn_selection.cpp | 17 +++++++++++++++--
 backend/src/ir/function.hpp                | 11 +++++++++++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index ab00269..0380d79 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -1154,7 +1154,19 @@ namespace gbe
     SelectionInstruction *insn = this->appendInsn(SEL_OP_JMPI, 0, 1);
     insn->src(0) = src;
     insn->index = index.value();
-    insn->extra.longjmp = abs(index - origin) > 800;
+    ir::LabelIndex start, end;
+    if (origin.value() < index.value()) {
+    // Forward Jump, need to exclude the target BB. Because we
+    // need to jump to the beginning of it.
+      start = origin;
+      end = ir::LabelIndex(index.value() - 1);
+    } else {
+      start = index;
+      end = origin;
+    }
+    // FIXME, this longjmp check is too hacky. We need to support instruction
+    // insertion at code emission stage in the future.
+    insn->extra.longjmp = ctx.getFunction().getDistance(start, end) > 8000;
     return insn->extra.longjmp ? 2 : 1;
   }
 
@@ -5150,7 +5162,8 @@ namespace gbe
           sel.curr.execWidth = 1;
           sel.curr.noMask = 1;
           sel.curr.predicate = GEN_PREDICATE_NONE;
-          sel.block->endifOffset -= sel.JMPI(GenRegister::immd(0), jip, curr->getLabelIndex());
+          // Actually, the origin of this JMPI should be the beginning of next BB.
+          sel.block->endifOffset -= sel.JMPI(GenRegister::immd(0), jip, ir::LabelIndex(curr->getLabelIndex().value() + 1));
         sel.pop();
       }
     }
diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp
index b5f4ba2..265fdc3 100644
--- a/backend/src/ir/function.hpp
+++ b/backend/src/ir/function.hpp
@@ -486,6 +486,17 @@ namespace ir {
     /*! Get surface starting address register from bti */
     Register getSurfaceBaseReg(uint8_t bti) const;
     void appendSurface(uint8_t bti, Register reg);
+    /*! Get instruction distance between two BBs include both b0 and b1,
+        and b0 must be less than b1. */
+    INLINE uint32_t getDistance(LabelIndex b0, LabelIndex b1) const {
+      uint32_t insnNum = 0;
+      GBE_ASSERT(b0.value() <= b1.value());
+      for(uint32_t i = b0.value(); i <= b1.value(); i++) {
+        BasicBlock &bb = getBlock(LabelIndex(i));
+        insnNum += bb.size();
+      }
+      return insnNum;
+    }
     /*! Output the control flow graph to .dot file */
     void outputCFG();
   private:
-- 
1.9.1



More information about the Beignet mailing list