[Beignet] [PATCH 3/3] Use instruction WHILE to manipulate structure.

xionghu.luo at intel.com xionghu.luo at intel.com
Sun Sep 14 17:23:39 PDT 2014


From: Luo Xionghu <xionghu.luo at intel.com>

1. WHILE instruction should be non-schedulable.
2. if this WHILE instruction jumps to an ELSE instruction, the distance
need add 2.

Signed-off-by: Luo Xionghu <xionghu.luo at intel.com>
---
 backend/src/backend/gen_context.cpp         |   10 ++++++++++
 backend/src/backend/gen_encoder.cpp         |   11 +++++++++++
 backend/src/backend/gen_encoder.hpp         |    2 ++
 backend/src/backend/gen_insn_scheduling.cpp |    2 +-
 backend/src/backend/gen_insn_selection.cpp  |   20 ++++++++++++++++++++
 backend/src/backend/gen_insn_selection.hxx  |    1 +
 backend/src/ir/structural_analysis.cpp      |    2 +-
 7 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/backend/src/backend/gen_context.cpp b/backend/src/backend/gen_context.cpp
index ba4a8f8..6cbfa43 100644
--- a/backend/src/backend/gen_context.cpp
+++ b/backend/src/backend/gen_context.cpp
@@ -254,6 +254,16 @@ namespace gbe
           p->ELSE(src);
         }
         break;
+      case SEL_OP_WHILE:
+        {
+          /*const ir::LabelIndex label0(insn.index), label1(insn.index1);
+          const LabelPair labelPair(label0, label1);
+          const GenRegister src = ra->genReg(insn.src(0));
+          this->branchPos3.push_back(std::make_pair(labelPair, p->store.size()));*/
+          insertJumpPos(insn);
+          p->WHILE(src);
+        }
+        break;
       default: NOT_IMPLEMENTED;
     }
   }
diff --git a/backend/src/backend/gen_encoder.cpp b/backend/src/backend/gen_encoder.cpp
index c67e85e..295e11d 100644
--- a/backend/src/backend/gen_encoder.cpp
+++ b/backend/src/backend/gen_encoder.cpp
@@ -1026,6 +1026,7 @@ namespace gbe
   ALU2_BRA(IF)
   ALU2_BRA(ELSE)
   ALU2_BRA(ENDIF)
+  ALU2_BRA(WHILE)
   ALU2_BRA(BRD)
   ALU2_BRA(BRC)
 
@@ -1037,8 +1038,18 @@ namespace gbe
                insn.header.opcode == GEN_OPCODE_ENDIF ||
                insn.header.opcode == GEN_OPCODE_IF ||
                insn.header.opcode == GEN_OPCODE_BRC ||
+               insn.header.opcode == GEN_OPCODE_WHILE ||
                insn.header.opcode == GEN_OPCODE_ELSE);
 
+    if( insn.header.opcode == GEN_OPCODE_WHILE ){
+      // if this WHILE instruction jump back to an ELSE instruction,
+      // need add distance to go to the next instruction.
+      GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jumpDistance];
+      if(insn_else.header.opcode == GEN_OPCODE_ELSE){
+        jumpDistance += 2;
+      }
+    }
+
     if (insn.header.opcode != GEN_OPCODE_JMPI || (jumpDistance > -32769 && jumpDistance < 32768))  {
            if (insn.header.opcode == GEN_OPCODE_IF) {
              this->setSrc1(&insn, GenRegister::immd(jumpDistance));
diff --git a/backend/src/backend/gen_encoder.hpp b/backend/src/backend/gen_encoder.hpp
index 9844eb8..2c999ce 100644
--- a/backend/src/backend/gen_encoder.hpp
+++ b/backend/src/backend/gen_encoder.hpp
@@ -154,6 +154,8 @@ namespace gbe
     void ELSE(GenRegister src);
     /*! ENDIF indexed instruction */
     void ENDIF(GenRegister src);
+    /*! WHILE indexed instruction */
+    void WHILE(GenRegister src);
     /*! BRC indexed instruction */
     void BRC(GenRegister src);
     /*! BRD indexed instruction */
diff --git a/backend/src/backend/gen_insn_scheduling.cpp b/backend/src/backend/gen_insn_scheduling.cpp
index 4324206..035a021 100644
--- a/backend/src/backend/gen_insn_scheduling.cpp
+++ b/backend/src/backend/gen_insn_scheduling.cpp
@@ -590,7 +590,7 @@ namespace gbe
     for (int32_t insnID = 0; insnID < insnNum; ++insnID) {
       ScheduleDAGNode *node = tracker.insnNodes[insnID];
       if (node->insn.isBranch() || node->insn.isLabel()
-          || node->insn.opcode == SEL_OP_EOT || node->insn.opcode == SEL_OP_IF
+          || node->insn.opcode == SEL_OP_EOT || node->insn.opcode == SEL_OP_IF || node->insn.opcode == SEL_OP_WHILE
           || node->insn.opcode == SEL_OP_BARRIER)
         tracker.makeBarrier(insnID, insnNum);
     }
diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index 170a9d8..4509072 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -543,6 +543,8 @@ namespace gbe
     void ELSE(Reg src, ir::LabelIndex jip, ir::LabelIndex elseLabel);
     /*! ENDIF indexed instruction */
     void ENDIF(Reg src, ir::LabelIndex jip, ir::LabelIndex endifLabel = ir::LabelIndex(0));
+    /*! WHILE indexed instruction */
+    void WHILE(Reg src, ir::LabelIndex jip);
     /*! BRD indexed instruction */
     void BRD(Reg src, ir::LabelIndex jip);
     /*! BRC indexed instruction */
@@ -1062,6 +1064,12 @@ namespace gbe
     insn->index = uint16_t(this->block->endifLabel);
   }
 
+  void Selection::Opaque::WHILE(Reg src, ir::LabelIndex jip) {
+    SelectionInstruction *insn = this->appendInsn(SEL_OP_WHILE, 0, 1);
+    insn->src(0) = src;
+    insn->index = uint16_t(jip);
+  }
+
   void Selection::Opaque::CMP(uint32_t conditional, Reg src0, Reg src1, Reg dst) {
     SelectionInstruction *insn = this->appendInsn(SEL_OP_CMP, 1, 2);
     insn->src(0) = src0;
@@ -4033,6 +4041,18 @@ namespace gbe
       } else if(opcode == OP_ELSE) {
         const LabelIndex label = insn.getLabelIndex();
         sel.ELSE(GenRegister::immd(0), label, insn.getParent()->thisElseLabel);
+      } else if(opcode == OP_WHILE) {
+        const Register pred = insn.getPredicateIndex();
+        const LabelIndex jip = insn.getLabelIndex();
+        sel.push();
+        sel.curr.physicalFlag = 0;
+        sel.curr.flagIndex = (uint64_t)pred;
+        sel.curr.externFlag = 1;
+        sel.curr.inversePredicate = insn.getInversePredicated();
+        sel.curr.predicate = GEN_PREDICATE_NORMAL;
+        sel.WHILE(GenRegister::immd(0), jip);
+        sel.curr.inversePredicate = 0;
+        sel.pop();
       } else
         NOT_IMPLEMENTED;
 
diff --git a/backend/src/backend/gen_insn_selection.hxx b/backend/src/backend/gen_insn_selection.hxx
index 2d70982..0e773f5 100644
--- a/backend/src/backend/gen_insn_selection.hxx
+++ b/backend/src/backend/gen_insn_selection.hxx
@@ -85,3 +85,4 @@ DECL_SELECTION_IR(BRD, UnaryInstruction)
 DECL_SELECTION_IR(IF, UnaryInstruction)
 DECL_SELECTION_IR(ENDIF, UnaryInstruction)
 DECL_SELECTION_IR(ELSE, UnaryInstruction)
+DECL_SELECTION_IR(WHILE, UnaryInstruction)
diff --git a/backend/src/ir/structural_analysis.cpp b/backend/src/ir/structural_analysis.cpp
index 1c4bf40..0b37b61 100644
--- a/backend/src/ir/structural_analysis.cpp
+++ b/backend/src/ir/structural_analysis.cpp
@@ -873,7 +873,7 @@ namespace analysis
       {
         Node* p = new SelfLoopNode(node);
 
-        p->canBeHandled = false;
+        p->canBeHandled = true;
 
         return insertNode(p);
       }
-- 
1.7.9.5



More information about the Beignet mailing list