<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>