<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:宋体;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@宋体";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman",serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.hoenzb
        {mso-style-name:hoenzb;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.25in 1.0in 1.25in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D">Pushed, thanks.<o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1F497D"><o:p> </o:p></span></a></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><a name="_____replyseparator"></a><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Beignet [mailto:beignet-bounces@lists.freedesktop.org]
<b>On Behalf Of </b>Zhigang Gong<br>
<b>Sent:</b> Monday, June 6, 2016 11:19<br>
<b>To:</b> Song, Ruiling <ruiling.song@intel.com><br>
<b>Cc:</b> beignet@lists.freedesktop.org<br>
<b>Subject:</b> Re: [Beignet] [PATCH] GBE: Optimize extraLiveOut register info.<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">This patch LGTM, thx.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">On Thu, Jun 2, 2016 at 10:21 AM, Ruiling Song <<a href="mailto:ruiling.song@intel.com" target="_blank">ruiling.song@intel.com</a>> wrote:<o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">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 style="color:#888888"><br>
<span class="hoenzb">--</span><br>
<span class="hoenzb">2.4.1</span><br>
<br>
<span class="hoenzb">_______________________________________________</span><br>
<span class="hoenzb">Beignet mailing list</span><br>
<span class="hoenzb"><a href="mailto:Beignet@lists.freedesktop.org">Beignet@lists.freedesktop.org</a></span><br>
<span class="hoenzb"><a href="https://lists.freedesktop.org/mailman/listinfo/beignet" target="_blank">https://lists.freedesktop.org/mailman/listinfo/beignet</a></span></span><o:p></o:p></p>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</body>
</html>