<!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>[287203] 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/287203">287203</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2021-12-17 13:05:42 -0800 (Fri, 17 Dec 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Support WasmAddress in B3 CSE
https://bugs.webkit.org/show_bug.cgi?id=234051
<rdar://problem/86552957>

Reviewed by Filip Pizlo and Yusuke Suzuki.

This patch adds support in B3's CSE phase to handle WasmAddressValue computations.
The reason this can't partake in pure CSE is that WasmAddressValue reads pinned.
To support this, we keep track of which blocks write pinned. If we're trying to
replace a value V2 with V1 because it appears there is a redundancy, we check if
any paths from V1 to V2 write pinned. If none do, we proceed with the replacement.

* b3/B3EliminateCommonSubexpressions.cpp:</pre>

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

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (287202 => 287203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2021-12-17 20:55:28 UTC (rev 287202)
+++ trunk/Source/JavaScriptCore/ChangeLog       2021-12-17 21:05:42 UTC (rev 287203)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2021-12-17  Saam Barati  <sbarati@apple.com>
+
+        Support WasmAddress in B3 CSE
+        https://bugs.webkit.org/show_bug.cgi?id=234051
+        <rdar://problem/86552957>
+
+        Reviewed by Filip Pizlo and Yusuke Suzuki.
+
+        This patch adds support in B3's CSE phase to handle WasmAddressValue computations.
+        The reason this can't partake in pure CSE is that WasmAddressValue reads pinned.
+        To support this, we keep track of which blocks write pinned. If we're trying to
+        replace a value V2 with V1 because it appears there is a redundancy, we check if
+        any paths from V1 to V2 write pinned. If none do, we proceed with the replacement.
+
+        * b3/B3EliminateCommonSubexpressions.cpp:
+
</ins><span class="cx"> 2021-12-17  Zan Dobersek  <zdobersek@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         [RISCV64] Implement linking and patching support in RISCV64Assembler
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3EliminateCommonSubexpressionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3EliminateCommonSubexpressions.cpp (287202 => 287203)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3EliminateCommonSubexpressions.cpp       2021-12-17 20:55:28 UTC (rev 287202)
+++ trunk/Source/JavaScriptCore/b3/B3EliminateCommonSubexpressions.cpp  2021-12-17 21:05:42 UTC (rev 287203)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx"> #include <wtf/HashMap.h>
</span><span class="cx"> #include <wtf/ListDump.h>
</span><span class="cx"> #include <wtf/RangeSet.h>
</span><ins>+#include <wtf/Scope.h>
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><span class="lines">@@ -144,10 +145,14 @@
</span><span class="cx"> 
</span><span class="cx">     RangeSet<HeapRange> reads; // This only gets used for forward store elimination.
</span><span class="cx">     RangeSet<HeapRange> writes; // This gets used for both load and store elimination.
</span><del>-    bool fence;
</del><ins>+    bool fence { false };
+    bool writesPinned { false };
</ins><span class="cx"> 
</span><span class="cx">     MemoryValueMap storesAtHead;
</span><span class="cx">     MemoryValueMap memoryValuesAtTail;
</span><ins>+
+    // This Maps x->y in "y = WasmAddress(@x)"
+    HashMap<Value*, Value*> m_candidateWasmAddressesAtTail;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class CSE {
</span><span class="lines">@@ -188,6 +193,14 @@
</span><span class="cx"> 
</span><span class="cx">                 if (memory)
</span><span class="cx">                     data.memoryValuesAtTail.add(memory);
</span><ins>+
+                if (WasmAddressValue* wasmAddress = value->as<WasmAddressValue>())
+                    data.m_candidateWasmAddressesAtTail.add(wasmAddress->child(0), wasmAddress);
+
+                if (effects.writesPinned) {
+                    data.writesPinned = true;
+                    data.m_candidateWasmAddressesAtTail.clear();
+                }
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             if (B3EliminateCommonSubexpressionsInternal::verbose)
</span><span class="lines">@@ -237,15 +250,28 @@
</span><span class="cx"> 
</span><span class="cx">         if (m_pureCSE.process(m_value, m_dominators)) {
</span><span class="cx">             ASSERT(!m_value->effects().writes);
</span><ins>+            ASSERT(!m_value->effects().writesPinned);
</ins><span class="cx">             m_changed = true;
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        if (WasmAddressValue* wasmAddress = m_value->as<WasmAddressValue>()) {
+            processWasmAddressValue(wasmAddress);
+            return;
+        }
+
+        Effects effects = m_value->effects();
+
+        if (effects.writesPinned) {
+            m_data.writesPinned = true;
+            m_data.m_candidateWasmAddressesAtTail.clear();
+        }
+
</ins><span class="cx">         MemoryValue* memory = m_value->as<MemoryValue>();
</span><span class="cx">         if (memory && processMemoryBeforeClobber(memory))
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        if (HeapRange writes = m_value->effects().writes)
</del><ins>+        if (HeapRange writes = effects.writes)
</ins><span class="cx">             clobber(m_data, writes);
</span><span class="cx">         
</span><span class="cx">         if (memory)
</span><span class="lines">@@ -694,6 +720,59 @@
</span><span class="cx">         return matches;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void processWasmAddressValue(WasmAddressValue* wasmAddress)
+    {
+        Value* ptr = wasmAddress->child(0);
+
+        if (Value* replacement = m_data.m_candidateWasmAddressesAtTail.get(ptr)) {
+            wasmAddress->replaceWithIdentity(replacement);
+            m_changed = true;
+            return;
+        }
+
+        auto addPtrOnScopeExit = makeScopeExit([&] {
+            m_data.m_candidateWasmAddressesAtTail.add(ptr, wasmAddress);
+        });
+
+        if (m_data.writesPinned) {
+            // Someone before us in this block wrote to pinned. So we have no
+            // hope of finding a match if the above search failed.
+            return;
+        }
+
+        Value* candidateReplacement = nullptr;
+        BasicBlock* dominator = nullptr;
+        m_dominators.forAllStrictDominatorsOf(m_block, [&] (BasicBlock* block) {
+            if (candidateReplacement)
+                return;
+
+            if (Value* replacement = m_impureBlockData[block].m_candidateWasmAddressesAtTail.get(ptr)) {
+                candidateReplacement = replacement;
+                dominator = block;
+            }
+        });
+
+        if (!candidateReplacement)
+            return;
+
+        BlockWorklist worklist;
+        worklist.pushAll(m_block->predecessors());
+        while (BasicBlock* block = worklist.pop()) {
+            if (block == dominator)
+                break;
+            if (m_impureBlockData[block].writesPinned) {
+                candidateReplacement = nullptr;
+                break;
+            }
+            worklist.pushAll(block->predecessors());
+        }
+
+        if (candidateReplacement) {
+            wasmAddress->replaceWithIdentity(candidateReplacement);
+            m_changed = true;
+        }
+    }
+
</ins><span class="cx">     Procedure& m_proc;
</span><span class="cx"> 
</span><span class="cx">     Dominators& m_dominators;
</span></span></pre>
</div>
</div>

</body>
</html>