<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2017-01-06 22:40 GMT+08:00  <span dir="ltr"><<a href="mailto:xionghu.luo@intel.com" target="_blank">xionghu.luo@intel.com</a>></span>:<br><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">From: Luo Xionghu <<a href="mailto:xionghu.luo@intel.com" target="_blank">xionghu.luo@intel.com</a>><br>
<br>
the if opt could be a independent pass like function by checking the<br>
instruction state changes and special instructions like I64, mixed bit<br>
etc. this could reduce the code complexit of structure code.<br>
<br>
v2: as the GenInstructionState flag/subFlag default value is 0.0, so<br>
isSimpleBlock function return false if the insn state uses 0.1 as flag.<br>
This rule could make function more straight forward, no need to enum<br>
the special instructions except SEL_OP_SEL_CMP(no predication per spec).<br>
<br>
Signed-off-by: Luo Xionghu <<a href="mailto:xionghu.luo@intel.com" target="_blank">xionghu.luo@intel.com</a>><br>
---<br>
 backend/src/CMakeLists.txt                        |   1 +<br>
 backend/src/backend/gen_conte<wbr>xt.cpp               |   8 +-<br>
 backend/src/backend/gen_insn_<wbr>selection.hpp        |   2 +<br>
 backend/src/backend/gen_insn_<wbr>selection_if_opt.cpp | 119 ++++++++++++++++++++++<br>
 4 files changed, 129 insertions(+), 1 deletion(-)<br>
 create mode 100644 backend/src/backend/gen_insn_s<wbr>election_if_opt.cpp<br>
<br>
diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt<br>
index 6ff25e7..c98ab3d 100644<br>
--- a/backend/src/CMakeLists.txt<br>
+++ b/backend/src/CMakeLists.txt<br>
@@ -104,6 +104,7 @@ set (GBE_SRC<br>
     backend/gen_insn_selection.<wbr>cpp<br>
     backend/gen_insn_selection.<wbr>hpp<br>
     backend/gen_insn_selection_op<wbr>timize.cpp<br>
+    backend/gen_insn_selection_if_<wbr>opt.cpp<br>
     backend/gen_insn_scheduling.c<wbr>pp<br>
     backend/gen_insn_scheduling.h<wbr>pp<br>
     backend/gen_insn_selection_ou<wbr>tput.cpp<br>
diff --git a/backend/src/backend/gen_cont<wbr>ext.cpp b/backend/src/backend/gen_cont<wbr>ext.cpp<br>
index 10e2c9e..769cd86 100644<br>
--- a/backend/src/backend/gen_cont<wbr>ext.cpp<br>
+++ b/backend/src/backend/gen_cont<wbr>ext.cpp<br>
@@ -3617,14 +3617,20 @@ namespace gbe<br>
     kernel->curbeSize = ALIGN(kernel->curbeSize, GEN_REG_SIZE);<br>
   }<br>
<br>
+  BVAR(OCL_OUTPUT_BEFORE_OPT, false);<br>
   BVAR(OCL_OUTPUT_SEL_IR, false);<br>
   BVAR(OCL_OPTIMIZE_SEL_IR, true);<br>
+  BVAR(OCL_OPTIMIZE_IF_IR, true);<br></blockquote><div>I think OCL_OPTIMIZE_IF_BLOCK is more easy to understand.</div><div> </div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
   bool GenContext::emitCode(void) {<br>
     GenKernel *genKernel = static_cast<GenKernel*>(this-><wbr>kernel);<br>
     sel->select();<br>
+    sel->addID();<br>
+    if (OCL_OUTPUT_BEFORE_OPT)<br></blockquote><div>OCL_OUTPUT_BEFORE_OPT is not easy to understand, output what?<br></div><div>I think OCL_OUTPUT_SEL_IR_AFTER_SELECT is a little better.</div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
+      outputSelectionIR(*this, this->sel, genKernel->getName());<br>
     if (OCL_OPTIMIZE_SEL_IR)<br>
       sel->optimize();<br>
-    sel->addID();<br>
+    if (OCL_OPTIMIZE_IF_IR)<br>
+      sel->if_opt();<br></blockquote><div>Hi Xiuli,</div><div> </div><div>this addID is only needed by outputSelectionIR(), right?</div><div>if it is only meaningful to outputSelectionIR, I would prefer putting it under  if (OCL_OUTPUT_SEL_IR).</div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
     if (OCL_OUTPUT_SEL_IR)</blockquote><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
       outputSelectionIR(*this, this->sel, genKernel->getName());<br>
     schedulePreRegAllocation(*thi<wbr>s, *this->sel);<br>
diff --git a/backend/src/backend/gen_insn<wbr>_selection.hpp b/backend/src/backend/gen_insn<wbr>_selection.hpp<br>
index f4cc948..88ae44f 100644<br>
--- a/backend/src/backend/gen_insn<wbr>_selection.hpp<br>
+++ b/backend/src/backend/gen_insn<wbr>_selection.hpp<br>
@@ -318,6 +318,8 @@ namespace gbe<br>
     void optimize(void);<br>
     uint32_t opt_features;<br>
<br>
+    void if_opt(void);<br>
+<br>
     /* Add insn ID for sel IR */<br>
     void addID(void);<br>
     const GenContext &getCtx();<br>
diff --git a/backend/src/backend/gen_insn<wbr>_selection_if_opt.cpp b/backend/src/backend/gen_insn<wbr>_selection_if_opt.cpp<br>
new file mode 100644<br>
index 0000000..026f5b9<br>
--- /dev/null<br>
+++ b/backend/src/backend/gen_insn<wbr>_selection_if_opt.cpp<br>
@@ -0,0 +1,119 @@<br>
+<br>
+#include "backend/gen_insn_selection.hp<wbr>p"<br>
+#include "backend/gen_context.hpp"<br>
+#include "ir/function.hpp"<br>
+#include "ir/liveness.hpp"<br>
+#include "ir/profile.hpp"<br>
+#include "sys/cvar.hpp"<br>
+#include "sys/vector.hpp"<br>
+#include <algorithm><br>
+#include <climits><br>
+#include <map><br>
+<br>
+namespace gbe<br>
+{<br>
+  class IfOptimizer<br>
+  {<br>
+  public:<br>
+    IfOptimizer(const GenContext& ctx, SelectionBlock& selblock) : ctx(ctx), selBlock(selblock) {}<br>
+    void run();<br>
+    bool isSimpleBlock();<br>
+    void removeSimpleIfEndif();<br>
+    ~IfOptimizer() {}<br>
+  protected:<br>
+    const GenContext &ctx;      //in case that we need it<br>
+    SelectionBlock &selBlock;<br>
+    bool optimized;<br>
+  };<br>
+<br>
+  bool IfOptimizer::isSimpleBlock() {<br>
+<br>
+      if(selBlock.insnList.size() > 20)<br>
+          return false;<br>
+<br>
+      bool if_exits = false;<br>
+      bool endif_exits = false;<br>
+      for (auto &insn : selBlock.insnList) {<br>
+        if (insn.opcode == SEL_OP_IF) {<br>
+          if_exits = true;<br>
+          continue;<br>
+        }<br>
+        if(if_exits) {<br>
+          GenInstructionState curr = insn.state;<br>
+          if (curr.execWidth == 1 || curr.predicate != GEN_PREDICATE_NONE || curr.flagIndex != 0 || (curr.flag == 0 && curr.subFlag == 1)) {<br>
+            return false;<br>
+          }<br>
+<br>
+          if (insn.opcode == SEL_OP_ELSE) {<br>
+            return false;<br>
+          }<br>
+<br>
+          if (insn.opcode == SEL_OP_SEL_CMP) {<br>
+            return false;<br>
+          }<br>
+        }<br>
+<br>
+        if (insn.opcode == SEL_OP_ENDIF) {<br>
+            endif_exits = true;<br>
+          break;<br>
+        }<br>
+      }<br>
+<br>
+      if (!if_exits || !endif_exits)<br>
+        return false;<br>
+<br>
+      return true;<br>
+  }<br>
+<br>
+  void IfOptimizer::removeSimpleIfEnd<wbr>if() {<br>
+      if(isSimpleBlock()) {<br>
+          GenInstructionState curr;<br>
+          bool if_find = false;<br></blockquote><div>I think you need to re-write your code like below to make it more clean:<br>you need to be careful here to make the logic is the same as before.</div><div><br>auto iter = selBlock.insnList.begin();<br></div><div>while (iter != selBlock.insnList.end()) {<br>              //remove if and endif, change instruction flags.<br>
              SelectionInstruction& insn = *iter;<br>
              if(insn.opcode == SEL_OP_IF && !if_find) {<br>
                iter = selBlock.insnList.erase(&insn)<wbr>;<br>                if_find = true;<br>
              } else if (ENDIF) {<br>                  iter = selBlock.insnList.erase(&insn)<wbr>;<br>
                  optimized = true;<br></div><div>               } else {<br></div><div>                 
if (if_find) {<br></div><div>                    insn.state.predicate = GEN_PREDICATE_NORMAL;<br>
                    insn.state.flag = 0;<br>                    insn.state.subFlag = 1;<br>                  }<br>                  ++iter;<br>                }<br></div><div>}<br><br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote">
+          for (auto iter = selBlock.insnList.begin(); iter != selBlock.insnList.end(); iter++ ) {<br>
+              //remove if and endif, change instruction flags.<br>
+              SelectionInstruction& insn = *iter;<br>
+              if(insn.opcode == SEL_OP_IF && !if_find) {<br>
+                iter = selBlock.insnList.erase(&insn)<wbr>;<br>
+                if (iter == selBlock.insnList.end()) {<br>
+                    break;<br>
+                }<br>
+                SelectionInstruction &next = *iter;<br>
+                next.state.predicate = GEN_PREDICATE_NORMAL;<br>
+                next.state.flag = 0;<br>
+                next.state.subFlag = 1;<br>
+                if_find = true;<br>
+                continue;<br>
+              }<br>
+<br>
+              if(!if_find)<br>
+                  continue;<br>
+<br>
+              insn.state.predicate = GEN_PREDICATE_NORMAL;<br>
+              insn.state.flag = 0;<br>
+              insn.state.subFlag = 1;<br>
+              if (insn.opcode == SEL_OP_ENDIF) {<br>
+                selBlock.insnList.erase(&insn)<wbr>;<br>
+                optimized = true;<br>
+                break;<br>
+              }<br>
+          }<br>
+      }<br>
+  }<br>
+<br>
+  void IfOptimizer::run()<br>
+  {<br>
+      optimized = false;<br>
+      removeSimpleIfEndif();<br>
+  }<br>
+<br>
+  void Selection::if_opt()<br>
+  {<br>
+    //do basic block level optimization<br>
+    for (SelectionBlock &block : *blockList) {<br>
+      IfOptimizer ifopt(getCtx(), block);<br>
+      ifopt.run();<br>
+    }<br>
+<br>
+  }<br>
+} /* namespace gbe */<br>
+<br>
<span class="gmail-m_-2299265412308003533gmail-HOEnZb"><font color="#888888">--<br>
2.5.0<br>
<br>
______________________________<wbr>_________________<br>
Beignet mailing list<br>
<a href="mailto:Beignet@lists.freedesktop.org" target="_blank">Beignet@lists.freedesktop.org</a><br>
<a rel="noreferrer" href="https://lists.freedesktop.org/mailman/listinfo/beignet" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/beignet</a><br>
</font></span></blockquote></div><br></div></div>