Use instruction WHILE to manipulate structure.
authorLuo Xionghu <xionghu.luo@intel.com>
Mon, 15 Sep 2014 00:23:39 +0000 (08:23 +0800)
committerZhigang Gong <zhigang.gong@intel.com>
Fri, 26 Sep 2014 04:56:53 +0000 (12:56 +0800)
1. WHILE instruction should be non-schedulable.
2. if this WHILE instruction jumps to an ELSE instruction, the distance
need add 2.

v2:
We also need to take care of HSW for while instruction.

Signed-off-by: Luo Xionghu <xionghu.luo@intel.com>
Signed-off-by: Zhigang Gong <zhigang.gong@intel.com>
backend/src/backend/gen75_encoder.cpp
backend/src/backend/gen_context.cpp
backend/src/backend/gen_encoder.cpp
backend/src/backend/gen_encoder.hpp
backend/src/backend/gen_insn_scheduling.cpp
backend/src/backend/gen_insn_selection.cpp
backend/src/backend/gen_insn_selection.hxx
backend/src/ir/structural_analysis.cpp

index 321e07b..724865b 100644 (file)
@@ -254,17 +254,25 @@ 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_IF) {
-      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
-      return;
+    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;
+      }
     }
-    else if (insn.header.opcode == GEN_OPCODE_JMPI) {
-      //jumpDistance'unit is Qword, and the HSW's offset of jmpi is in byte, so multi 8
+
+    if (insn.header.opcode != GEN_OPCODE_JMPI)
+      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+    else {
+      //jumpDistance'unit is Qword, and the HSW's JMPI offset of jmpi is in byte, so multi 8
       jumpDistance = (jumpDistance - 2) * 8;
+      this->setSrc1(&insn, GenRegister::immd(jumpDistance));
     }
-
-    this->setSrc1(&insn, GenRegister::immd(jumpDistance));
+    return;
   }
 } /* End of the name space. */
index 175878d..8844233 100644 (file)
@@ -255,6 +255,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;
     }
   }
index c67e85e..295e11d 100644 (file)
@@ -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));
index 9844eb8..2c999ce 100644 (file)
@@ -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 */
index ead3e26..58ab69f 100644 (file)
@@ -588,7 +588,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_READ_ARF
           || node->insn.opcode == SEL_OP_BARRIER)
         tracker.makeBarrier(insnID, insnNum);
index f284ae1..e3ee35d 100644 (file)
@@ -544,6 +544,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 */
@@ -1063,6 +1065,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;
@@ -4217,6 +4225,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;
 
index 048a844..7511b84 100644 (file)
@@ -86,3 +86,4 @@ DECL_SELECTION_IR(IF, UnaryInstruction)
 DECL_SELECTION_IR(ENDIF, UnaryInstruction)
 DECL_SELECTION_IR(ELSE, UnaryInstruction)
 DECL_SELECTION_IR(READ_ARF, UnaryInstruction)
+DECL_SELECTION_IR(WHILE, UnaryInstruction)
index 1860ee9..040a7e0 100644 (file)
@@ -867,7 +867,7 @@ namespace analysis
       {
         Node* p = new SelfLoopNode(node);
 
-        p->canBeHandled = false;
+        p->canBeHandled = true;
 
         return insertNode(p);
       }