[Beignet] [PATCH] use global flag 0.0 to control unstructured simple block.

xionghu.luo at intel.com xionghu.luo at intel.com
Mon Sep 29 13:14:11 PDT 2014


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

filter the simple block out and replace the if/endif with global flag to
control.

Signed-off-by: Luo Xionghu <xionghu.luo at intel.com>
---
 backend/src/backend/gen_insn_selection.cpp |   50 ++++++++++++++++++++++++----
 backend/src/backend/gen_insn_selection.hpp |    1 +
 backend/src/backend/gen_reg_allocation.cpp |    3 +-
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/backend/src/backend/gen_insn_selection.cpp b/backend/src/backend/gen_insn_selection.cpp
index f284ae1..e3547c6 100644
--- a/backend/src/backend/gen_insn_selection.cpp
+++ b/backend/src/backend/gen_insn_selection.cpp
@@ -217,7 +217,7 @@ namespace gbe
   // SelectionBlock
   ///////////////////////////////////////////////////////////////////////////
 
-  SelectionBlock::SelectionBlock(const ir::BasicBlock *bb) : bb(bb), isLargeBlock(false), endifLabel( (ir::LabelIndex) 0){}
+  SelectionBlock::SelectionBlock(const ir::BasicBlock *bb) : bb(bb), isLargeBlock(false), endifLabel( (ir::LabelIndex) 0), removeSimpleIfEndif(false){}
 
   void SelectionBlock::append(ir::Register reg) { tmp.push_back(reg); }
 
@@ -403,6 +403,8 @@ namespace gbe
     uint32_t buildBasicBlockDAG(const ir::BasicBlock &bb);
     /*! Perform the selection on the basic block */
     void matchBasicBlock(const ir::BasicBlock &bb, uint32_t insnNum);
+    /*! a simple block can use predication instead of if/endif*/
+    bool isSimpleBlock(const ir::BasicBlock &bb, uint32_t insnNum);
     /*! A root instruction needs to be generated */
     bool isRoot(const ir::Instruction &insn) const;
 
@@ -1471,6 +1473,26 @@ namespace gbe
     return false;
   }
 
+  bool Selection::Opaque::isSimpleBlock(const ir::BasicBlock &bb, uint32_t insnNum) {
+    for (int32_t insnID = insnNum-1; insnID >= 0; --insnID) {
+      SelectionDAG &dag = *insnDAG[insnID];
+      const ir::Instruction& insn = dag.insn;
+      if(insn.isMemberOf<ir::CompareInstruction>() ||
+         insn.isMemberOf<ir::SelectInstruction>() ||
+         insn.getOpcode() == ir::OP_SIMD_ANY ||
+         insn.getOpcode() == ir::OP_SIMD_ALL ||
+         insn.getOpcode() == ir::OP_ELSE)
+        return false;
+    }
+
+    if(!(insnDAG[insnNum-1]->insn.isMemberOf<ir::BranchInstruction>()) ||
+        insnDAG[insnNum-1]->insn.getOpcode() == ir::OP_ENDIF)
+      return false;
+
+    return true;
+  }
+
+
   uint32_t Selection::Opaque::buildBasicBlockDAG(const ir::BasicBlock &bb)
   {
     using namespace ir;
@@ -1551,7 +1573,9 @@ namespace gbe
     // Bottom up code generation
     bool needEndif = this->block->hasBranch == false && !this->block->hasBarrier;
     needEndif = needEndif && bb.needEndif;
-    if (needEndif) {
+    this->block->removeSimpleIfEndif = insnNum < 5 && isSimpleBlock(bb, insnNum);
+    //this->block->removeSimpleIfEndif = false;//this->block->removeSimpleIfEndif && needEndif;
+    if (needEndif && !this->block->removeSimpleIfEndif) {
       if(!bb.needIf) // this basic block is the exit of a structure
         this->ENDIF(GenRegister::immd(0), bb.endifLabel, bb.endifLabel);
       else {
@@ -1572,6 +1596,12 @@ namespace gbe
 
         // Start a new code fragment
         this->startBackwardGeneration();
+
+        if(this->block->removeSimpleIfEndif){
+          this->curr.predicate = GEN_PREDICATE_NORMAL;
+          this->curr.flag = 0;
+          this->curr.subFlag = 0;
+        }
         // If there is no branch at the end of this block.
 
         // Try all the patterns from best to worst
@@ -1581,6 +1611,12 @@ namespace gbe
           ++it;
         } while (it != end);
         GBE_ASSERT(it != end);
+
+        if(this->block->removeSimpleIfEndif){
+          this->curr.predicate = GEN_PREDICATE_NONE;
+          this->curr.flag = 0;
+          this->curr.subFlag = 0;
+        }
         // If we are in if/endif fix mode, and this block is
         // large enough, we need to insert endif/if pair to eliminate
         // the too long if/endif block.
@@ -3808,7 +3844,8 @@ namespace gbe
             sel.JMPI(GenRegister::immd(0), jip, label);
           sel.pop();
         }
-        sel.push();
+        if(!sel.block->removeSimpleIfEndif){
+          sel.push();
           sel.curr.predicate = GEN_PREDICATE_NORMAL;
           if(!insn.getParent()->needEndif && insn.getParent()->needIf) {
             ir::LabelIndex label = insn.getParent()->endifLabel;
@@ -3816,7 +3853,8 @@ namespace gbe
           }
           else
             sel.IF(GenRegister::immd(0), sel.block->endifLabel, sel.block->endifLabel);
-        sel.pop();
+          sel.pop();
+        }
       }
 
       return true;
@@ -4077,7 +4115,7 @@ namespace gbe
           sel.curr.predicate = GEN_PREDICATE_NORMAL;
           sel.MOV(ip, GenRegister::immuw(uint16_t(dst)));
           sel.curr.predicate = GEN_PREDICATE_NONE;
-          if (!sel.block->hasBarrier)
+          if (!sel.block->hasBarrier && !sel.block->removeSimpleIfEndif)
             sel.ENDIF(GenRegister::immd(0), nextLabel);
           sel.block->endifOffset = -1;
         sel.pop();
@@ -4087,7 +4125,7 @@ namespace gbe
         if(insn.getParent()->needEndif)
           sel.MOV(ip, GenRegister::immuw(uint16_t(dst)));
 
-        if (!sel.block->hasBarrier) {
+        if (!sel.block->hasBarrier && !sel.block->removeSimpleIfEndif) {
           if(insn.getParent()->needEndif && !insn.getParent()->needIf)
             sel.ENDIF(GenRegister::immd(0), insn.getParent()->endifLabel, insn.getParent()->endifLabel);
           else if(insn.getParent()->needEndif)
diff --git a/backend/src/backend/gen_insn_selection.hpp b/backend/src/backend/gen_insn_selection.hpp
index 9bcce6f..974acf3 100644
--- a/backend/src/backend/gen_insn_selection.hpp
+++ b/backend/src/backend/gen_insn_selection.hpp
@@ -233,6 +233,7 @@ namespace gbe
     int endifOffset;
     bool hasBarrier;
     bool hasBranch;
+    bool removeSimpleIfEndif;
   };
 
   /*! Owns the selection engine */
diff --git a/backend/src/backend/gen_reg_allocation.cpp b/backend/src/backend/gen_reg_allocation.cpp
index 067c9ce..3e18c3a 100644
--- a/backend/src/backend/gen_reg_allocation.cpp
+++ b/backend/src/backend/gen_reg_allocation.cpp
@@ -1072,7 +1072,8 @@ namespace gbe
                        insn.opcode == SEL_OP_JMPI ||
                        insn.state.predicate == GEN_PREDICATE_NONE ||
                        (block.hasBarrier && insn.opcode == SEL_OP_MOV) ||
-                       (insn.state.flag == 0 && insn.state.subFlag == 1)));
+                       (insn.state.flag == 0 && insn.state.subFlag == 1) ||
+                       block.removeSimpleIfEndif));
         }
         lastID = insnID;
         insnID++;
-- 
1.7.9.5



More information about the Beignet mailing list