[Beignet] [PATCH 12/18] GBE: Only emit long jump when jump a lot of blocks

Zhigang Gong zhigang.gong at intel.com
Fri Mar 28 00:10:50 PDT 2014


Most of the case, we don't need to emit long jump at all.

Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
 backend/src/backend/gen_context.cpp        |  2 +-
 backend/src/backend/gen_encoder.cpp        |  9 ++++-----
 backend/src/backend/gen_encoder.hpp        |  2 +-
 backend/src/backend/gen_insn_selection.cpp | 27 ++++++++++++++-------------
 backend/src/backend/gen_insn_selection.hpp |  1 +
 5 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index 2bc0e72..2225ff9 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;
-- 
1.8.3.2



More information about the Beignet mailing list