From: Zhigang Gong Date: Thu, 27 Mar 2014 01:36:46 +0000 (+0800) Subject: GBE: Only emit long jump when jump a lot of blocks X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7256dacfe269d4f5169b519131635e9e5759000a;p=contrib%2Fbeignet.git GBE: Only emit long jump when jump a lot of blocks Most of the case, we don't need to emit long jump at all. Signed-off-by: Zhigang Gong Reviewed-by: "Yang, Rong R" Reviewed-by: "Song, Ruiling" --- diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp index 147108f..84e9304 100644 --- a/backend/src/backend/gen_context.cpp +++ b/backend/src/backend/gen_context.cpp @@ -1664,7 +1664,7 @@ namespace gbe void GenContext::emitJumpInstruction(const SelectionInstruction &insn) { insertJumpPos(insn); const GenRegister src = ra->genReg(insn.src(0)); - p->JMPI(src); + p->JMPI(src, insn.extra.longjmp); } void GenContext::emitEotInstruction(const SelectionInstruction &insn) { diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp index 06aa769..e8670b9 100644 --- a/backend/src/backend/gen_encoder.cpp +++ b/backend/src/backend/gen_encoder.cpp @@ -1054,9 +1054,10 @@ namespace gbe insn->bits3.gen7_memory_fence.commit_enable = 0x1; } - void GenEncoder::JMPI(GenRegister src) { + void GenEncoder::JMPI(GenRegister src, bool longjmp) { alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src); - NOP(); + if (longjmp) + NOP(); } #define ALU2_BRA(OP) \ @@ -1084,10 +1085,8 @@ namespace gbe this->setSrc1(&insn, GenRegister::immd(jumpDistance)); return; } - else if (insn.header.opcode == GEN_OPCODE_JMPI) { + else if (insn.header.opcode == GEN_OPCODE_JMPI) offset = -2; - /*assert(jumpDistance > -32769 && jumpDistance < 32768);*/ - } this->setSrc1(&insn, GenRegister::immd(jumpDistance + offset)); } else if ( insn.header.predicate_control == GEN_PREDICATE_NONE ) { // For the conditional jump distance out of S15 range, we need to use an diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp index 4bb208f..f5e8548 100644 --- a/backend/src/backend/gen_encoder.hpp +++ b/backend/src/backend/gen_encoder.hpp @@ -135,7 +135,7 @@ namespace gbe /*! Memory fence message (to order loads and stores between threads) */ void FENCE(GenRegister dst); /*! Jump indexed instruction */ - void JMPI(GenRegister src); + void JMPI(GenRegister src, bool longjmp = false); /*! IF indexed instruction */ void IF(GenRegister src); /*! ENDIF indexed instruction */ diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp index 147c3e6..6f38ff2 100644 --- a/backend/src/backend/gen_insn_selection.cpp +++ b/backend/src/backend/gen_insn_selection.cpp @@ -497,8 +497,8 @@ namespace gbe void FENCE(GenRegister dst); /*! Encode a label instruction */ void LABEL(ir::LabelIndex label); - /*! Jump indexed instruction */ - void JMPI(Reg src, ir::LabelIndex target); + /*! Jump indexed instruction, return the encoded instruction count according to jump distance. */ + int JMPI(Reg src, ir::LabelIndex target, ir::LabelIndex origin); /*! IF indexed instruction */ void IF(Reg src, ir::LabelIndex jip, ir::LabelIndex uip, int16_t offset0, int16_t offset1); /*! ENDIF indexed instruction */ @@ -923,10 +923,12 @@ namespace gbe insn->dst(0) = dst; } - void Selection::Opaque::JMPI(Reg src, ir::LabelIndex index) { + int Selection::Opaque::JMPI(Reg src, ir::LabelIndex index, ir::LabelIndex origin) { SelectionInstruction *insn = this->appendInsn(SEL_OP_JMPI, 0, 1); insn->src(0) = src; insn->index = uint16_t(index); + insn->extra.longjmp = abs(index - origin) > 800; + return insn->extra.longjmp ? 2 : 1; } void Selection::Opaque::BRD(Reg src, ir::LabelIndex jip) { @@ -2997,6 +2999,7 @@ namespace gbe const GenRegister src0 = sel.selReg(ocl::blockip); const GenRegister src1 = GenRegister::immuw(label); const uint32_t simdWidth = sel.ctx.getSimdWidth(); + GBE_ASSERTM(label < GEN_MAX_LABEL, "We reached the maximum label number which is reserved for barrier handling"); sel.LABEL(label); // Do not emit any code for the "returning" block. There is no need for it @@ -3037,7 +3040,7 @@ namespace gbe sel.curr.noMask = 1; sel.curr.execWidth = 1; sel.curr.inversePredicate = 1; - sel.JMPI(GenRegister::immd(0), jip); + sel.JMPI(GenRegister::immd(0), jip, label); sel.pop(); // FIXME, if the last BRA is unconditional jump, we don't need to update the label here. sel.push(); @@ -3058,7 +3061,7 @@ namespace gbe sel.curr.noMask = 1; sel.curr.execWidth = 1; sel.curr.inversePredicate = 1; - sel.JMPI(GenRegister::immd(0), jip); + sel.JMPI(GenRegister::immd(0), jip, label); sel.pop(); } sel.push(); @@ -3244,11 +3247,8 @@ namespace gbe sel.curr.execWidth = 1; sel.curr.noMask = 1; sel.curr.predicate = GEN_PREDICATE_NONE; - sel.JMPI(GenRegister::immd(0), jip); + sel.block->endifOffset -= sel.JMPI(GenRegister::immd(0), jip, curr->getLabelIndex()); sel.pop(); - // FIXME just for the correct endif offset. - // JMPI still has 2 instruction. - sel.block->endifOffset -= 2; } } @@ -3262,6 +3262,7 @@ namespace gbe const Function &fn = sel.ctx.getFunction(); const BasicBlock &bb = fn.getBlock(src); const LabelIndex jip = sel.ctx.getLabelIndex(&insn); + const LabelIndex label = bb.getLabelIndex(); const uint32_t simdWidth = sel.ctx.getSimdWidth(); GBE_ASSERT(bb.getNextBlock() != NULL); @@ -3281,6 +3282,7 @@ namespace gbe sel.CMP(GEN_CONDITIONAL_NEQ, sel.selReg(pred, TYPE_U16), GenRegister::immuw(0)); sel.curr.predicate = GEN_PREDICATE_NORMAL; sel.MOV(ip, GenRegister::immuw(uint16_t(dst))); + sel.block->endifOffset = -1; sel.curr.predicate = GEN_PREDICATE_NONE; if (!sel.block->hasBarrier) sel.ENDIF(GenRegister::immd(0), next); @@ -3290,13 +3292,13 @@ namespace gbe else sel.curr.predicate = GEN_PREDICATE_ALIGN1_ANY8H; sel.curr.noMask = 1; - sel.JMPI(GenRegister::immd(0), jip); - sel.block->endifOffset = -3; + sel.block->endifOffset -= sel.JMPI(GenRegister::immd(0), jip, label); sel.pop(); } else { const LabelIndex next = bb.getNextBlock()->getLabelIndex(); // Update the PcIPs sel.MOV(ip, GenRegister::immuw(uint16_t(dst))); + sel.block->endifOffset = -1; if (!sel.block->hasBarrier) sel.ENDIF(GenRegister::immd(0), next); // Branch to the jump target @@ -3304,9 +3306,8 @@ namespace gbe sel.curr.execWidth = 1; sel.curr.noMask = 1; sel.curr.predicate = GEN_PREDICATE_NONE; - sel.JMPI(GenRegister::immd(0), jip); + sel.block->endifOffset -= sel.JMPI(GenRegister::immd(0), jip, label); sel.pop(); - sel.block->endifOffset = -3; } } diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp index 8557768..85974f0 100644 --- a/backend/src/backend/gen_insn_selection.hpp +++ b/backend/src/backend/gen_insn_selection.hpp @@ -125,6 +125,7 @@ namespace gbe uint16_t rdmsglen:3; }; uint32_t barrierType; + bool longjmp; } extra; /*! Gen opcode */ uint8_t opcode;