<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[195654] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/195654">195654</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2016-01-26 22:10:15 -0800 (Tue, 26 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] When lowering B3 to Air, preferRightForResult() should prefer values from the same block
https://bugs.webkit.org/show_bug.cgi?id=153477

Reviewed by Filip Pizlo.

In cases like this:

Block #0
    @1 = something
    @2 = Jump #1
Block #1
    @3 = something else
    @4 = Add(@3, @1)
    ...
    @42 = Branch(@x, #1, #2)

B3LowerToAir would pick @1 for the argument copied
for what goes into the UseDef side of Add.

This created a bunch of moves that could never be coalesced.
In Kraken's imaging-desaturate, there were enough Moves to slow
down the hot loop.

Ideally, we should not use UseCount for lowering. We should use
the real liveness for preferRightForResult(), and a loop-weighted
use-count for effective addresses. The problem is keeping the cost
low for those simple helpers.

In this patch, I went with a simple heuristic: prioritize the value
defined in the same block for UseDef.

There is one other way that would be cheap but a bit invasive:
-Get rid of UseDef.
-Make every ops, 3 operands.
-Tell the register allocator to attempt aliasing of the 2 uses
 with the def.
-If the allocator fails, just add a move as needed.

For now, the simple heuristic seems okay for the cases have.

* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::preferRightForResult):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (195653 => 195654)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-01-27 03:49:35 UTC (rev 195653)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-01-27 06:10:15 UTC (rev 195654)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2016-01-26  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        [JSC] When lowering B3 to Air, preferRightForResult() should prefer values from the same block
+        https://bugs.webkit.org/show_bug.cgi?id=153477
+
+        Reviewed by Filip Pizlo.
+
+        In cases like this:
+
+        Block #0
+            @1 = something
+            @2 = Jump #1
+        Block #1
+            @3 = something else
+            @4 = Add(@3, @1)
+            ...
+            @42 = Branch(@x, #1, #2)
+
+        B3LowerToAir would pick @1 for the argument copied
+        for what goes into the UseDef side of Add.
+
+        This created a bunch of moves that could never be coalesced.
+        In Kraken's imaging-desaturate, there were enough Moves to slow
+        down the hot loop.
+
+        Ideally, we should not use UseCount for lowering. We should use
+        the real liveness for preferRightForResult(), and a loop-weighted
+        use-count for effective addresses. The problem is keeping the cost
+        low for those simple helpers.
+
+        In this patch, I went with a simple heuristic: prioritize the value
+        defined in the same block for UseDef.
+
+        There is one other way that would be cheap but a bit invasive:
+        -Get rid of UseDef.
+        -Make every ops, 3 operands.
+        -Tell the register allocator to attempt aliasing of the 2 uses
+         with the def.
+        -If the allocator fails, just add a move as needed.
+
+        For now, the simple heuristic seems okay for the cases have.
+
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::preferRightForResult):
+
</ins><span class="cx"> 2016-01-26  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Tail duplication should break critical edges first
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (195653 => 195654)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-01-27 03:49:35 UTC (rev 195653)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-01-27 06:10:15 UTC (rev 195654)
</span><span class="lines">@@ -583,18 +583,27 @@
</span><span class="cx">         // - A child might be a candidate for coalescing with this value.
</span><span class="cx">         //
</span><span class="cx">         // Currently, we have machinery in place to recognize super obvious forms of the latter issue.
</span><del>-
-        bool result = m_useCounts.numUsingInstructions(right) == 1;
</del><span class="cx">         
</span><span class="cx">         // We recognize when a child is a Phi that has this value as one of its children. We're very
</span><span class="cx">         // conservative about this; for example we don't even consider transitive Phi children.
</span><span class="cx">         bool leftIsPhiWithThis = m_phiChildren[left].transitivelyUses(m_value);
</span><span class="cx">         bool rightIsPhiWithThis = m_phiChildren[right].transitivelyUses(m_value);
</span><del>-        
</del><ins>+
</ins><span class="cx">         if (leftIsPhiWithThis != rightIsPhiWithThis)
</span><del>-            result = rightIsPhiWithThis;
</del><ins>+            return rightIsPhiWithThis;
</ins><span class="cx"> 
</span><del>-        return result;
</del><ins>+        bool leftResult = m_useCounts.numUsingInstructions(left) == 1;
+        bool rightResult = m_useCounts.numUsingInstructions(right) == 1;
+        if (leftResult &amp;&amp; rightResult) {
+            // If one operand is not in the block, it could be in a block dominating a loop
+            // containing m_value.
+            if (left-&gt;owner == m_value-&gt;owner)
+                return false;
+            if (right-&gt;owner == m_value-&gt;owner)
+                return true;
+        }
+
+        return rightResult;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;Air::Opcode opcode32, Air::Opcode opcode64, Air::Opcode opcodeDouble, Air::Opcode opcodeFloat, Commutativity commutativity = NotCommutative&gt;
</span></span></pre>
</div>
</div>

</body>
</html>