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.g...@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 _______________________________________________ Beignet mailing list Beignet@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/beignet