<div dir="ltr">This patch LGTM, thx.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 2, 2016 at 10:21 AM, Ruiling Song <span dir="ltr"><<a href="mailto:ruiling.song@intel.com" target="_blank">ruiling.song@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">extraLiveout anlysis is used to detect registers defined in loop and<br>
used out-of the loop. Previous logic may also include registers defined<br>
BEFORE loop and live-through loop as extraLiveout, which is not accurate.<br>
As the extraLiveout registers will be forced as non-uniform, which may<br>
waste some register space. Excluding registers that are defined before loop<br>
while used out-of loop will make such registers get correct uniform/non-uniform<br>
information. This would benefit some gemm cl kernel.<br>
<br>
also fix a small issue: do intersection when the exit-block has more<br>
than one predecessors.<br>
<br>
Signed-off-by: Ruiling Song <<a href="mailto:ruiling.song@intel.com">ruiling.song@intel.com</a>><br>
---<br>
backend/src/ir/function.cpp | 4 ++--<br>
backend/src/ir/function.hpp | 7 ++++---<br>
backend/src/ir/liveness.cpp | 25 +++++++++++++++++++++---<br>
backend/src/llvm/llvm_gen_backend.cpp | 36 ++++++-----------------------------<br>
4 files changed, 34 insertions(+), 38 deletions(-)<br>
<br>
diff --git a/backend/src/ir/function.cpp b/backend/src/ir/function.cpp<br>
index 3b7891b..4112f06 100644<br>
--- a/backend/src/ir/function.cpp<br>
+++ b/backend/src/ir/function.cpp<br>
@@ -62,8 +62,8 @@ namespace ir {<br>
return unit.getPointerFamily();<br>
}<br>
<br>
- void Function::addLoop(const vector<LabelIndex> &bbs, const vector<std::pair<LabelIndex, LabelIndex>> &exits) {<br>
- loops.push_back(GBE_NEW(Loop, bbs, exits));<br>
+ void Function::addLoop(LabelIndex preheader, const vector<LabelIndex> &bbs, const vector<std::pair<LabelIndex, LabelIndex>> &exits) {<br>
+ loops.push_back(GBE_NEW(Loop, preheader, bbs, exits));<br>
}<br>
<br>
void Function::checkEmptyLabels(void) {<br>
diff --git a/backend/src/ir/function.hpp b/backend/src/ir/function.hpp<br>
index 5785bee..6a90767 100644<br>
--- a/backend/src/ir/function.hpp<br>
+++ b/backend/src/ir/function.hpp<br>
@@ -273,8 +273,9 @@ namespace ir {<br>
struct Loop : public NonCopyable<br>
{<br>
public:<br>
- Loop(const vector<LabelIndex> &in, const vector<std::pair<LabelIndex, LabelIndex>> &exit) :<br>
- bbs(in), exits(exit) {}<br>
+ Loop(LabelIndex pre, const vector<LabelIndex> &in, const vector<std::pair<LabelIndex, LabelIndex>> &exit) :<br>
+ preheader(pre), bbs(in), exits(exit) {}<br>
+ LabelIndex preheader;<br>
vector<LabelIndex> bbs;<br>
vector<std::pair<LabelIndex, LabelIndex>> exits;<br>
GBE_STRUCT(Loop);<br>
@@ -522,7 +523,7 @@ namespace ir {<br>
/*! Push stack size. */<br>
INLINE void pushStackSize(uint32_t step) { this->stackSize += step; }<br>
/*! add the loop info for later liveness analysis */<br>
- void addLoop(const vector<LabelIndex> &bbs, const vector<std::pair<LabelIndex, LabelIndex>> &exits);<br>
+ void addLoop(LabelIndex preheader, const vector<LabelIndex> &bbs, const vector<std::pair<LabelIndex, LabelIndex>> &exits);<br>
INLINE const vector<Loop * > &getLoops() { return loops; }<br>
vector<BasicBlock *> &getBlocks() { return blocks; }<br>
/*! Get surface starting address register from bti */<br>
diff --git a/backend/src/ir/liveness.cpp b/backend/src/ir/liveness.cpp<br>
index d48f067..4a89a73 100644<br>
--- a/backend/src/ir/liveness.cpp<br>
+++ b/backend/src/ir/liveness.cpp<br>
@@ -217,19 +217,38 @@ namespace ir {<br>
if(loops.size() == 0) return;<br>
<br>
for (auto l : loops) {<br>
+ const BasicBlock &preheader = fn.getBlock(l->preheader);<br>
+ BlockInfo *preheaderInfo = liveness[&preheader];<br>
for (auto x : l->exits) {<br>
const BasicBlock &a = fn.getBlock(x.first);<br>
const BasicBlock &b = fn.getBlock(x.second);<br>
BlockInfo * exiting = liveness[&a];<br>
BlockInfo * exit = liveness[&b];<br>
std::vector<Register> toExtend;<br>
+ std::vector<Register> toExtendCand;<br>
<br>
- if(b.getPredecessorSet().size() > 1) {<br>
+ if(b.getPredecessorSet().size() <= 1) {<br>
+ // the exits only have one predecessor<br>
for (auto p : exit->upwardUsed)<br>
- toExtend.push_back(p);<br>
+ toExtendCand.push_back(p);<br>
} else {<br>
- std::set_intersection(exiting->liveOut.begin(), exiting->liveOut.end(), exit->upwardUsed.begin(), exit->upwardUsed.end(), std::back_inserter(toExtend));<br>
+ // the exits have more than one predecessors<br>
+ std::set_intersection(exiting->liveOut.begin(),<br>
+ exiting->liveOut.end(),<br>
+ exit->upwardUsed.begin(),<br>
+ exit->upwardUsed.end(),<br>
+ std::back_inserter(toExtendCand));<br>
}<br>
+ // toExtendCand may contain some virtual register defined before loop,<br>
+ // which need to be excluded. Because what we need is registers defined<br>
+ // in the loop. Such kind of registers must be in live-out of the loop's<br>
+ // preheader. So we do the subtraction here.<br>
+ std::set_difference(toExtendCand.begin(),<br>
+ toExtendCand.end(),<br>
+ preheaderInfo->liveOut.begin(),<br>
+ preheaderInfo->liveOut.end(),<br>
+ std::back_inserter(toExtend));<br>
+<br>
if (toExtend.size() == 0) continue;<br>
for(auto r : toExtend)<br>
extentRegs.insert(r);<br>
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp<br>
index acad1b2..0b44f24 100644<br>
--- a/backend/src/llvm/llvm_gen_backend.cpp<br>
+++ b/backend/src/llvm/llvm_gen_backend.cpp<br>
@@ -2737,35 +2737,6 @@ namespace gbe<br>
std::vector<std::pair<Loop*, int>> lp;<br>
<br>
findAllLoops(LI, lp);<br>
-#if GBE_DEBUG<br>
- // check two loops' interference<br>
- for(unsigned int i = 0; i < lp.size(); i++) {<br>
- SmallVector<Loop::Edge, 8> exitBBs;<br>
- lp[i].first->getExitEdges(exitBBs);<br>
-<br>
- const std::vector<BasicBlock*> &inBBs = lp[i].first->getBlocks();<br>
- std::vector<ir::LabelIndex> bbs1;<br>
- for(auto x : inBBs) {<br>
- bbs1.push_back(labelMap[x]);<br>
- }<br>
- std::sort(bbs1.begin(), bbs1.end());<br>
- for(unsigned int j = i+1; j < lp.size(); j++) {<br>
- if(! lp[i].first->contains(lp[j].first)) {<br>
- const std::vector<BasicBlock*> &inBBs2 = lp[j].first->getBlocks();<br>
- std::vector<ir::LabelIndex> bbs2;<br>
- std::vector<ir::LabelIndex> bbs3;<br>
-<br>
- for(auto x : inBBs2) {<br>
- bbs2.push_back(labelMap[x]);<br>
- }<br>
-<br>
- std::sort(bbs2.begin(), bbs2.end());<br>
- std::set_intersection(bbs1.begin(), bbs1.end(), bbs2.begin(), bbs2.end(), std::back_inserter(bbs3));<br>
- GBE_ASSERT(bbs3.size() < 1);<br>
- }<br>
- }<br>
- }<br>
-#endif<br>
<br>
for (auto loop : lp) {<br>
loopBBs.clear();<br>
@@ -2776,6 +2747,11 @@ namespace gbe<br>
GBE_ASSERT(labelMap.find(b) != labelMap.end());<br>
loopBBs.push_back(labelMap[b]);<br>
}<br>
+ BasicBlock *preheader = loop.first->getLoopPreheader();<br>
+ ir::LabelIndex preheaderBB(0);<br>
+ if (preheader) {<br>
+ preheaderBB = labelMap[preheader];<br>
+ }<br>
<br>
SmallVector<Loop::Edge, 8> exitBBs;<br>
loop.first->getExitEdges(exitBBs);<br>
@@ -2784,7 +2760,7 @@ namespace gbe<br>
GBE_ASSERT(labelMap.find(b.second) != labelMap.end());<br>
loopExits.push_back(std::make_pair(labelMap[b.first], labelMap[b.second]));<br>
}<br>
- fn.addLoop(loopBBs, loopExits);<br>
+ fn.addLoop(preheaderBB, loopBBs, loopExits);<br>
}<br>
}<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.4.1<br>
<br>
_______________________________________________<br>
Beignet mailing list<br>
<a href="mailto:Beignet@lists.freedesktop.org">Beignet@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/beignet" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/beignet</a><br>
</font></span></blockquote></div><br></div>