<!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>[196035] 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/196035">196035</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-02-02 15:46:52 -0800 (Tue, 02 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>B3 should be able to compile trivial self-loops
https://bugs.webkit.org/show_bug.cgi?id=153802
rdar://problem/24465632

Reviewed by Michael Saboff.

Tail-duplicating a self-loop would mean doing a kind of loop unrolling. It wouldn't be
profitable even if it did work. It turns out that it doesn't work, because we edit the target
block before reading the source block, which breaks if the target and source block are the
same.

This disables tail duplication of self-loops, adds a test, and adds better validation for this
issue.

* b3/B3DuplicateTails.cpp:
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::resetReachability):
* b3/testb3.cpp:
(JSC::B3::testComputeDivisionMagic):
(JSC::B3::testTrivialInfiniteLoop):
(JSC::B3::zero):
(JSC::B3::run):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3DuplicateTailscpp">trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedurecpp">trunk/Source/JavaScriptCore/b3/B3Procedure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (196034 => 196035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-02-02 23:42:40 UTC (rev 196034)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-02-02 23:46:52 UTC (rev 196035)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2016-02-02  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        B3 should be able to compile trivial self-loops
+        https://bugs.webkit.org/show_bug.cgi?id=153802
+        rdar://problem/24465632
+
+        Reviewed by Michael Saboff.
+
+        Tail-duplicating a self-loop would mean doing a kind of loop unrolling. It wouldn't be
+        profitable even if it did work. It turns out that it doesn't work, because we edit the target
+        block before reading the source block, which breaks if the target and source block are the
+        same.
+
+        This disables tail duplication of self-loops, adds a test, and adds better validation for this
+        issue.
+
+        * b3/B3DuplicateTails.cpp:
+        * b3/B3Procedure.cpp:
+        (JSC::B3::Procedure::resetReachability):
+        * b3/testb3.cpp:
+        (JSC::B3::testComputeDivisionMagic):
+        (JSC::B3::testTrivialInfiniteLoop):
+        (JSC::B3::zero):
+        (JSC::B3::run):
+
</ins><span class="cx"> 2016-02-02  Saam barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [ES6] bound functions .name property should be &quot;bound &quot; + the target function's name
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3DuplicateTailscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp (196034 => 196035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp        2016-02-02 23:42:40 UTC (rev 196034)
+++ trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp        2016-02-02 23:46:52 UTC (rev 196035)
</span><span class="lines">@@ -105,6 +105,11 @@
</span><span class="cx">             if (!candidates.contains(tail))
</span><span class="cx">                 continue;
</span><span class="cx"> 
</span><ins>+            // Don't tail duplicate a trivial self-loop, because the code below can't handle block and
+            // tail being the same block.
+            if (block == tail)
+                continue;
+
</ins><span class="cx">             // We're about to change 'block'. Make sure that nobody duplicates block after this
</span><span class="cx">             // point.
</span><span class="cx">             candidates.remove(block);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.cpp (196034 => 196035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2016-02-02 23:42:40 UTC (rev 196034)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2016-02-02 23:46:52 UTC (rev 196035)
</span><span class="lines">@@ -147,6 +147,31 @@
</span><span class="cx"> 
</span><span class="cx"> void Procedure::resetReachability()
</span><span class="cx"> {
</span><ins>+    if (shouldValidateIR()) {
+        // Validate the basic properties that we need for resetting reachability. We often reset
+        // reachability before IR validation, so without this mini-validation, you would crash inside
+        // B3::resetReachability() without getting any IR dump.
+
+        BasicBlock* badBlock = nullptr;
+        for (BasicBlock* block : *this) {
+            if (!block-&gt;size()) {
+                badBlock = block;
+                break;
+            }
+
+            if (!block-&gt;last()-&gt;as&lt;ControlValue&gt;()) {
+                badBlock = block;
+                break;
+            }
+        }
+
+        if (badBlock) {
+            dataLog(&quot;FATAL: Invalid basic block &quot;, *badBlock, &quot; while running Procedure::resetReachability().\n&quot;);
+            dataLog(*this);
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    }
+    
</ins><span class="cx">     B3::resetReachability(
</span><span class="cx">         m_blocks,
</span><span class="cx">         [&amp;] (BasicBlock* deleted) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (196034 => 196035)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-02-02 23:42:40 UTC (rev 196034)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-02-02 23:46:52 UTC (rev 196035)
</span><span class="lines">@@ -10026,6 +10026,17 @@
</span><span class="cx">     CHECK(magic.shift == shift);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testTrivialInfiniteLoop()
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+    BasicBlock* loop = proc.addBlock();
+    root-&gt;appendNew&lt;ControlValue&gt;(proc, Jump, Origin(), FrequentedBlock(loop));
+    loop-&gt;appendNew&lt;ControlValue&gt;(proc, Jump, Origin(), FrequentedBlock(loop));
+
+    compile(proc);
+}
+
</ins><span class="cx"> // Make sure the compiler does not try to optimize anything out.
</span><span class="cx"> NEVER_INLINE double zero()
</span><span class="cx"> {
</span><span class="lines">@@ -11427,6 +11438,8 @@
</span><span class="cx"> 
</span><span class="cx">     RUN(testComputeDivisionMagic&lt;int32_t&gt;(2, -2147483647, 0));
</span><span class="cx"> 
</span><ins>+    RUN(testTrivialInfiniteLoop());
+
</ins><span class="cx">     if (tasks.isEmpty())
</span><span class="cx">         usage();
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>