<!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>[214408] trunk/Source</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/214408">214408</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2017-03-26 14:39:27 -0700 (Sun, 26 Mar 2017)</dd>
</dl>
<h3>Log Message</h3>
<pre>Air should use RegisterSet for RegLiveness
https://bugs.webkit.org/show_bug.cgi?id=170108
Reviewed by Yusuke Suzuki.
Source/JavaScriptCore:
The biggest change here is the introduction of the new RegLiveness class. This is a
drop-in replacement for the old RegLiveness, which was a specialization of
AbstractLiveness<>, but it's about 30% faster. It gets its speed boost from just using
sets everywhere, which is efficient for registers since RegisterSet is just two (on
x86-64) or three 32-bit (on ARM64) statically allocated words. This looks like a 1%
compile time progression on WasmBench.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/B3TimingScope.cpp: Records phase timing totals.
(JSC::B3::TimingScope::TimingScope):
(JSC::B3::TimingScope::~TimingScope):
* b3/B3TimingScope.h:
* b3/air/AirAllocateRegistersByGraphColoring.cpp:
(JSC::B3::Air::allocateRegistersByGraphColoring):
* b3/air/AirLiveness.h: Move code around and rename a bit to make it more like RegLiveness; in particular we want the `iterator` to be called `iterator` not `Iterator`, and we want it to be internal to its iterable. Also rename this template to Liveness, to match the header filename.
(JSC::B3::Air::Liveness::Liveness):
(JSC::B3::Air::Liveness::LocalCalc::LocalCalc):
(JSC::B3::Air::Liveness::LocalCalc::Iterable::Iterable):
(JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::iterator):
(JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::operator++):
(JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::operator*):
(JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::operator==):
(JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::operator!=):
(JSC::B3::Air::Liveness::LocalCalc::Iterable::begin):
(JSC::B3::Air::Liveness::LocalCalc::Iterable::end):
(JSC::B3::Air::Liveness::Iterable::Iterable):
(JSC::B3::Air::Liveness::Iterable::iterator::iterator):
(JSC::B3::Air::RegLivenessAdapter::RegLivenessAdapter): Deleted.
(JSC::B3::Air::RegLivenessAdapter::numIndices): Deleted.
(JSC::B3::Air::RegLivenessAdapter::acceptsBank): Deleted.
(JSC::B3::Air::RegLivenessAdapter::acceptsRole): Deleted.
(JSC::B3::Air::RegLivenessAdapter::valueToIndex): Deleted.
(JSC::B3::Air::RegLivenessAdapter::indexToValue): Deleted.
(JSC::B3::Air::AbstractLiveness::AbstractLiveness): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::LocalCalc): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::Iterator): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::operator++): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::operator*): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::operator==): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::operator!=): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterable::Iterable): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterable::begin): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterable::end): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::Iterable::contains): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::live): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::isLive): Deleted.
(JSC::B3::Air::AbstractLiveness::LocalCalc::execute): Deleted.
(JSC::B3::Air::AbstractLiveness::rawLiveAtHead): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::Iterable): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::iterator::iterator): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::iterator::operator*): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::iterator::operator++): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::iterator::operator==): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::iterator::operator!=): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::begin): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::end): Deleted.
(JSC::B3::Air::AbstractLiveness::Iterable::contains): Deleted.
(JSC::B3::Air::AbstractLiveness::liveAtHead): Deleted.
(JSC::B3::Air::AbstractLiveness::liveAtTail): Deleted.
(JSC::B3::Air::AbstractLiveness::workset): Deleted.
* b3/air/AirLogRegisterPressure.cpp:
* b3/air/AirLowerAfterRegAlloc.cpp:
* b3/air/AirRegLiveness.cpp: Added.
(JSC::B3::Air::RegLiveness::RegLiveness):
(JSC::B3::Air::RegLiveness::~RegLiveness):
(JSC::B3::Air::RegLiveness::LocalCalc::execute):
* b3/air/AirRegLiveness.h: Added.
(JSC::B3::Air::RegLiveness::LocalCalc::LocalCalc):
(JSC::B3::Air::RegLiveness::LocalCalc::live):
(JSC::B3::Air::RegLiveness::LocalCalc::isLive):
(JSC::B3::Air::RegLiveness::liveAtHead):
(JSC::B3::Air::RegLiveness::liveAtTail):
* b3/air/AirReportUsedRegisters.cpp:
* jit/RegisterSet.h:
(JSC::RegisterSet::add):
(JSC::RegisterSet::remove):
(JSC::RegisterSet::contains):
(JSC::RegisterSet::subsumes):
(JSC::RegisterSet::iterator::iterator):
(JSC::RegisterSet::iterator::operator*):
(JSC::RegisterSet::iterator::operator++):
(JSC::RegisterSet::iterator::operator==):
(JSC::RegisterSet::iterator::operator!=):
(JSC::RegisterSet::begin):
(JSC::RegisterSet::end):
Source/WTF:
* wtf/Atomics.h:
(WTF::ensurePointer): This is a useful replacement for std::once, which requires less fencing.
* wtf/Bitmap.h: Add more utilities.
(WTF::Bitmap::iterator::iterator): An iterator for set bits.
(WTF::Bitmap::iterator::operator*):
(WTF::Bitmap::iterator::operator++):
(WTF::Bitmap::iterator::operator==):
(WTF::Bitmap::iterator::operator!=):
(WTF::Bitmap::begin):
(WTF::Bitmap::end):
(WTF::WordType>::subsumes): a.subsumes(b) if all of b's set bits are set in a.
(WTF::WordType>::findBit): find next set or clear bit.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3TimingScopecpp">trunk/Source/JavaScriptCore/b3/B3TimingScope.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3TimingScopeh">trunk/Source/JavaScriptCore/b3/B3TimingScope.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirAllocateRegistersByGraphColoringcpp">trunk/Source/JavaScriptCore/b3/air/AirAllocateRegistersByGraphColoring.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLivenessh">trunk/Source/JavaScriptCore/b3/air/AirLiveness.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLogRegisterPressurecpp">trunk/Source/JavaScriptCore/b3/air/AirLogRegisterPressure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloccpp">trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirReportUsedRegisterscpp">trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRegisterSeth">trunk/Source/JavaScriptCore/jit/RegisterSet.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfAtomicsh">trunk/Source/WTF/wtf/Atomics.h</a></li>
<li><a href="#trunkSourceWTFwtfBitmaph">trunk/Source/WTF/wtf/Bitmap.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3airAirRegLivenesscpp">trunk/Source/JavaScriptCore/b3/air/AirRegLiveness.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirRegLivenessh">trunk/Source/JavaScriptCore/b3/air/AirRegLiveness.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -101,6 +101,7 @@
</span><span class="cx"> b3/air/AirOptimizeBlockOrder.cpp
</span><span class="cx"> b3/air/AirPadInterference.cpp
</span><span class="cx"> b3/air/AirPhaseScope.cpp
</span><ins>+ b3/air/AirRegLiveness.cpp
</ins><span class="cx"> b3/air/AirReportUsedRegisters.cpp
</span><span class="cx"> b3/air/AirSimplifyCFG.cpp
</span><span class="cx"> b3/air/AirSpecial.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -1,3 +1,97 @@
</span><ins>+2017-03-26 Filip Pizlo <fpizlo@apple.com>
+
+ Air should use RegisterSet for RegLiveness
+ https://bugs.webkit.org/show_bug.cgi?id=170108
+
+ Reviewed by Yusuke Suzuki.
+
+ The biggest change here is the introduction of the new RegLiveness class. This is a
+ drop-in replacement for the old RegLiveness, which was a specialization of
+ AbstractLiveness<>, but it's about 30% faster. It gets its speed boost from just using
+ sets everywhere, which is efficient for registers since RegisterSet is just two (on
+ x86-64) or three 32-bit (on ARM64) statically allocated words. This looks like a 1%
+ compile time progression on WasmBench.
+
+ * CMakeLists.txt:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * b3/B3TimingScope.cpp: Records phase timing totals.
+ (JSC::B3::TimingScope::TimingScope):
+ (JSC::B3::TimingScope::~TimingScope):
+ * b3/B3TimingScope.h:
+ * b3/air/AirAllocateRegistersByGraphColoring.cpp:
+ (JSC::B3::Air::allocateRegistersByGraphColoring):
+ * b3/air/AirLiveness.h: Move code around and rename a bit to make it more like RegLiveness; in particular we want the `iterator` to be called `iterator` not `Iterator`, and we want it to be internal to its iterable. Also rename this template to Liveness, to match the header filename.
+ (JSC::B3::Air::Liveness::Liveness):
+ (JSC::B3::Air::Liveness::LocalCalc::LocalCalc):
+ (JSC::B3::Air::Liveness::LocalCalc::Iterable::Iterable):
+ (JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::iterator):
+ (JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::operator++):
+ (JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::operator*):
+ (JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::operator==):
+ (JSC::B3::Air::Liveness::LocalCalc::Iterable::iterator::operator!=):
+ (JSC::B3::Air::Liveness::LocalCalc::Iterable::begin):
+ (JSC::B3::Air::Liveness::LocalCalc::Iterable::end):
+ (JSC::B3::Air::Liveness::Iterable::Iterable):
+ (JSC::B3::Air::Liveness::Iterable::iterator::iterator):
+ (JSC::B3::Air::RegLivenessAdapter::RegLivenessAdapter): Deleted.
+ (JSC::B3::Air::RegLivenessAdapter::numIndices): Deleted.
+ (JSC::B3::Air::RegLivenessAdapter::acceptsBank): Deleted.
+ (JSC::B3::Air::RegLivenessAdapter::acceptsRole): Deleted.
+ (JSC::B3::Air::RegLivenessAdapter::valueToIndex): Deleted.
+ (JSC::B3::Air::RegLivenessAdapter::indexToValue): Deleted.
+ (JSC::B3::Air::AbstractLiveness::AbstractLiveness): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::LocalCalc): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::Iterator): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::operator++): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::operator*): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::operator==): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterator::operator!=): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterable::Iterable): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterable::begin): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterable::end): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::Iterable::contains): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::live): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::isLive): Deleted.
+ (JSC::B3::Air::AbstractLiveness::LocalCalc::execute): Deleted.
+ (JSC::B3::Air::AbstractLiveness::rawLiveAtHead): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::Iterable): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::iterator::iterator): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::iterator::operator*): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::iterator::operator++): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::iterator::operator==): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::iterator::operator!=): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::begin): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::end): Deleted.
+ (JSC::B3::Air::AbstractLiveness::Iterable::contains): Deleted.
+ (JSC::B3::Air::AbstractLiveness::liveAtHead): Deleted.
+ (JSC::B3::Air::AbstractLiveness::liveAtTail): Deleted.
+ (JSC::B3::Air::AbstractLiveness::workset): Deleted.
+ * b3/air/AirLogRegisterPressure.cpp:
+ * b3/air/AirLowerAfterRegAlloc.cpp:
+ * b3/air/AirRegLiveness.cpp: Added.
+ (JSC::B3::Air::RegLiveness::RegLiveness):
+ (JSC::B3::Air::RegLiveness::~RegLiveness):
+ (JSC::B3::Air::RegLiveness::LocalCalc::execute):
+ * b3/air/AirRegLiveness.h: Added.
+ (JSC::B3::Air::RegLiveness::LocalCalc::LocalCalc):
+ (JSC::B3::Air::RegLiveness::LocalCalc::live):
+ (JSC::B3::Air::RegLiveness::LocalCalc::isLive):
+ (JSC::B3::Air::RegLiveness::liveAtHead):
+ (JSC::B3::Air::RegLiveness::liveAtTail):
+ * b3/air/AirReportUsedRegisters.cpp:
+ * jit/RegisterSet.h:
+ (JSC::RegisterSet::add):
+ (JSC::RegisterSet::remove):
+ (JSC::RegisterSet::contains):
+ (JSC::RegisterSet::subsumes):
+ (JSC::RegisterSet::iterator::iterator):
+ (JSC::RegisterSet::iterator::operator*):
+ (JSC::RegisterSet::iterator::operator++):
+ (JSC::RegisterSet::iterator::operator==):
+ (JSC::RegisterSet::iterator::operator!=):
+ (JSC::RegisterSet::begin):
+ (JSC::RegisterSet::end):
+
</ins><span class="cx"> 2017-03-25 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> Fix wasm by returning after we do TLS.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -1005,6 +1005,8 @@
</span><span class="cx">                 0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4275615914A20004CB9FF /* LinkBuffer.cpp */; };
</span><span class="cx">                 0FF427641591A1CC004CB9FF /* DFGDisassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */; };
</span><span class="cx">                 0FF427651591A1CE004CB9FF /* DFGDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */; };
</span><ins>+                0FF4B4BC1E88449700DBBE86 /* AirRegLiveness.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF4B4BA1E88449500DBBE86 /* AirRegLiveness.cpp */; };
+                0FF4B4BD1E88449A00DBBE86 /* AirRegLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4B4BB1E88449500DBBE86 /* AirRegLiveness.h */; };
</ins><span class="cx">                 0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF60AC016740F8100029779 /* ReduceWhitespace.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0FF60AC316740F8800029779 /* ReduceWhitespace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF60ABF16740F8100029779 /* ReduceWhitespace.cpp */; };
</span><span class="cx">                 0FF7168C15A3B235008F5DAA /* PropertyOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF7168A15A3B231008F5DAA /* PropertyOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -3520,6 +3522,8 @@
</span><span class="cx">                 0FF4275615914A20004CB9FF /* LinkBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LinkBuffer.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDisassembler.cpp; path = dfg/DFGDisassembler.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDisassembler.h; path = dfg/DFGDisassembler.h; sourceTree = "<group>"; };
</span><ins>+                0FF4B4BA1E88449500DBBE86 /* AirRegLiveness.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirRegLiveness.cpp; path = b3/air/AirRegLiveness.cpp; sourceTree = "<group>"; };
+                0FF4B4BB1E88449500DBBE86 /* AirRegLiveness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirRegLiveness.h; path = b3/air/AirRegLiveness.h; sourceTree = "<group>"; };
</ins><span class="cx">                 0FF60ABF16740F8100029779 /* ReduceWhitespace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReduceWhitespace.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0FF60AC016740F8100029779 /* ReduceWhitespace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReduceWhitespace.h; sourceTree = "<group>"; };
</span><span class="cx">                 0FF7168A15A3B231008F5DAA /* PropertyOffset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyOffset.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -5578,6 +5582,8 @@
</span><span class="cx">                                 0F9CABC71DB54A760008E83B /* AirPadInterference.h */,
</span><span class="cx">                                 0FEC855E1BDACDC70080FF74 /* AirPhaseScope.cpp */,
</span><span class="cx">                                 0FEC855F1BDACDC70080FF74 /* AirPhaseScope.h */,
</span><ins>+                                0FF4B4BA1E88449500DBBE86 /* AirRegLiveness.cpp */,
+                                0FF4B4BB1E88449500DBBE86 /* AirRegLiveness.h */,
</ins><span class="cx">                                 0F45703A1BE45F0A0062A629 /* AirReportUsedRegisters.cpp */,
</span><span class="cx">                                 0F45703B1BE45F0A0062A629 /* AirReportUsedRegisters.h */,
</span><span class="cx">                                 0F338DFB1BED51270013C88F /* AirSimplifyCFG.cpp */,
</span><span class="lines">@@ -8236,6 +8242,7 @@
</span><span class="cx">                                 0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */,
</span><span class="cx">                                 1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
</span><span class="cx">                                 62EC9BB71B7EB07C00303AD1 /* CallFrameShuffleData.h in Headers */,
</span><ins>+                                0FF4B4BD1E88449A00DBBE86 /* AirRegLiveness.h in Headers */,
</ins><span class="cx">                                 62D755D71B84FB4A001801FA /* CallFrameShuffler.h in Headers */,
</span><span class="cx">                                 0F0B83B114BCF71800885B4F /* CallLinkInfo.h in Headers */,
</span><span class="cx">                                 0F93329E14CA7DC50085F3C6 /* CallLinkStatus.h in Headers */,
</span><span class="lines">@@ -10625,6 +10632,7 @@
</span><span class="cx">                                 A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */,
</span><span class="cx">                                 14469DE8107EC7E700650446 /* PropertySlot.cpp in Sources */,
</span><span class="cx">                                 ADE39FFF16DD144B0003CD4A /* PropertyTable.cpp in Sources */,
</span><ins>+                                0FF4B4BC1E88449700DBBE86 /* AirRegLiveness.cpp in Sources */,
</ins><span class="cx">                                 65FB5117184EEE7000C12B70 /* ProtoCallFrame.cpp in Sources */,
</span><span class="cx">                                 1474C33C16AA2D9B0062F01D /* PrototypeMap.cpp in Sources */,
</span><span class="cx">                                 79B00CBC1C6AB07E0088C65D /* ProxyConstructor.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3TimingScopecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3TimingScope.cpp (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3TimingScope.cpp        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/b3/B3TimingScope.cpp        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,23 +29,53 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx">
</span><span class="cx"> #include "B3Common.h"
</span><del>-#include <wtf/CurrentTime.h>
</del><span class="cx"> #include <wtf/DataLog.h>
</span><ins>+#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
</ins><span class="cx">
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx">
</span><ins>+namespace {
+
+class State {
+ WTF_MAKE_NONCOPYABLE(State);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ State() { }
+
+ Seconds addToTotal(const char* name, Seconds duration)
+ {
+ auto locker = holdLock(lock);
+ return totals.add(name, Seconds(0)).iterator->value += duration;
+ }
+
+private:
+ HashMap<const char*, Seconds> totals;
+ Lock lock;
+};
+
+State& state()
+{
+ static Atomic<State*> s_state;
+ return ensurePointer(s_state, [] { return new State(); });
+}
+
+} // anonymous namespace
+
</ins><span class="cx"> TimingScope::TimingScope(const char* name)
</span><span class="cx"> : m_name(name)
</span><span class="cx"> {
</span><span class="cx"> if (shouldMeasurePhaseTiming())
</span><del>- m_before = monotonicallyIncreasingTimeMS();
</del><ins>+ m_before = MonotonicTime::now();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> TimingScope::~TimingScope()
</span><span class="cx"> {
</span><span class="cx"> if (shouldMeasurePhaseTiming()) {
</span><del>- double after = monotonicallyIncreasingTimeMS();
- dataLog("[B3] ", m_name, " took: ", after - m_before, " ms.\n");
</del><ins>+ Seconds duration = MonotonicTime::now() - m_before;
+ dataLog(
+ "[B3] ", m_name, " took: ", duration.milliseconds(), " ms ",
+ "(total: ", state().addToTotal(m_name, duration).milliseconds(), " ms).\n");
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3TimingScopeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3TimingScope.h (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3TimingScope.h        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/b3/B3TimingScope.h        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx">
</span><ins>+#include <wtf/MonotonicTime.h>
</ins><span class="cx"> #include <wtf/Noncopyable.h>
</span><span class="cx">
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="lines">@@ -39,7 +40,7 @@
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> const char* m_name;
</span><del>- double m_before;
</del><ins>+ MonotonicTime m_before;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::B3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirAllocateRegistersByGraphColoringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirAllocateRegistersByGraphColoring.cpp (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirAllocateRegistersByGraphColoring.cpp        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/b3/air/AirAllocateRegistersByGraphColoring.cpp        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -2257,7 +2257,7 @@
</span><span class="cx">
</span><span class="cx"> void allocateRegistersByGraphColoring(Code& code)
</span><span class="cx"> {
</span><del>- PhaseScope phaseScope(code, "Air::allocateRegistersByGraphColoring");
</del><ins>+ PhaseScope phaseScope(code, "allocateRegistersByGraphColoring");
</ins><span class="cx">
</span><span class="cx"> if (false)
</span><span class="cx"> dataLog("Code before graph coloring:\n", code);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLivenessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirLiveness.h (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLiveness.h        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/b3/air/AirLiveness.h        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -79,30 +79,14 @@
</span><span class="cx"> Code& m_code;
</span><span class="cx"> };
</span><span class="cx">
</span><del>-struct RegLivenessAdapter {
- typedef Reg Thing;
- typedef BitVector IndexSet;
-
- RegLivenessAdapter(Code&) { }
-
- static unsigned numIndices(Code&)
- {
- return Reg::maxIndex() + 1;
- }
-
- static bool acceptsBank(Bank) { return true; }
- static bool acceptsRole(Arg::Role) { return true; }
- static unsigned valueToIndex(Reg reg) { return reg.index(); }
- Reg indexToValue(unsigned index) { return Reg::fromIndex(index); }
-};
-
</del><ins>+// HEADS UP: The algorithm here is duplicated in AirRegLiveness.h.
</ins><span class="cx"> template<typename Adapter>
</span><del>-class AbstractLiveness : public Adapter {
</del><ins>+class Liveness : public Adapter {
</ins><span class="cx"> struct Workset;
</span><span class="cx"> public:
</span><span class="cx"> typedef typename Adapter::Thing Thing;
</span><span class="cx">
</span><del>- AbstractLiveness(Code& code)
</del><ins>+ Liveness(Code& code)
</ins><span class="cx"> : Adapter(code)
</span><span class="cx"> , m_workset(Adapter::numIndices(code))
</span><span class="cx"> , m_liveAtHead(code.size())
</span><span class="lines">@@ -131,7 +115,7 @@
</span><span class="cx"> changed = false;
</span><span class="cx">
</span><span class="cx"> for (size_t blockIndex = code.size(); blockIndex--;) {
</span><del>- BasicBlock* block = code.at(blockIndex);
</del><ins>+ BasicBlock* block = code[blockIndex];
</ins><span class="cx"> if (!block)
</span><span class="cx"> continue;
</span><span class="cx">
</span><span class="lines">@@ -187,7 +171,7 @@
</span><span class="cx"> // This calculator has to be run in reverse.
</span><span class="cx"> class LocalCalc {
</span><span class="cx"> public:
</span><del>- LocalCalc(AbstractLiveness& liveness, BasicBlock* block)
</del><ins>+ LocalCalc(Liveness& liveness, BasicBlock* block)
</ins><span class="cx"> : m_liveness(liveness)
</span><span class="cx"> , m_block(block)
</span><span class="cx"> {
</span><span class="lines">@@ -198,40 +182,42 @@
</span><span class="cx"> workset.add(index);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- struct Iterator {
- Iterator(Adapter& adapter, IndexSparseSet<UnsafeVectorOverflow>::const_iterator sparceSetIterator)
- : m_adapter(adapter)
- , m_sparceSetIterator(sparceSetIterator)
</del><ins>+ class Iterable {
+ public:
+ Iterable(Liveness& liveness)
+ : m_liveness(liveness)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>- Iterator& operator++()
- {
- ++m_sparceSetIterator;
- return *this;
- }
</del><ins>+ class iterator {
+ public:
+ iterator(Adapter& adapter, IndexSparseSet<UnsafeVectorOverflow>::const_iterator sparceSetIterator)
+ : m_adapter(adapter)
+ , m_sparceSetIterator(sparceSetIterator)
+ {
+ }
</ins><span class="cx">
</span><del>- typename Adapter::Thing operator*() const
- {
- return m_adapter.indexToValue(*m_sparceSetIterator);
- }
</del><ins>+ iterator& operator++()
+ {
+ ++m_sparceSetIterator;
+ return *this;
+ }
</ins><span class="cx">
</span><del>- bool operator==(const Iterator& other) { return m_sparceSetIterator == other.m_sparceSetIterator; }
- bool operator!=(const Iterator& other) { return m_sparceSetIterator != other.m_sparceSetIterator; }
</del><ins>+ typename Adapter::Thing operator*() const
+ {
+ return m_adapter.indexToValue(*m_sparceSetIterator);
+ }
</ins><span class="cx">
</span><del>- private:
- Adapter& m_adapter;
- IndexSparseSet<UnsafeVectorOverflow>::const_iterator m_sparceSetIterator;
- };
</del><ins>+ bool operator==(const iterator& other) { return m_sparceSetIterator == other.m_sparceSetIterator; }
+ bool operator!=(const iterator& other) { return m_sparceSetIterator != other.m_sparceSetIterator; }
</ins><span class="cx">
</span><del>- struct Iterable {
- Iterable(AbstractLiveness& liveness)
- : m_liveness(liveness)
- {
- }
</del><ins>+ private:
+ Adapter& m_adapter;
+ IndexSparseSet<UnsafeVectorOverflow>::const_iterator m_sparceSetIterator;
+ };
</ins><span class="cx">
</span><del>- Iterator begin() const { return Iterator(m_liveness, m_liveness.m_workset.begin()); }
- Iterator end() const { return Iterator(m_liveness, m_liveness.m_workset.end()); }
</del><ins>+ iterator begin() const { return iterator(m_liveness, m_liveness.m_workset.begin()); }
+ iterator end() const { return iterator(m_liveness, m_liveness.m_workset.end()); }
</ins><span class="cx">
</span><span class="cx"> bool contains(const typename Adapter::Thing& thing) const
</span><span class="cx"> {
</span><span class="lines">@@ -239,7 +225,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- AbstractLiveness& m_liveness;
</del><ins>+ Liveness& m_liveness;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> Iterable live() const
</span><span class="lines">@@ -301,7 +287,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- AbstractLiveness& m_liveness;
</del><ins>+ Liveness& m_liveness;
</ins><span class="cx"> BasicBlock* m_block;
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -313,7 +299,7 @@
</span><span class="cx"> template<typename UnderlyingIterable>
</span><span class="cx"> class Iterable {
</span><span class="cx"> public:
</span><del>- Iterable(AbstractLiveness& liveness, const UnderlyingIterable& iterable)
</del><ins>+ Iterable(Liveness& liveness, const UnderlyingIterable& iterable)
</ins><span class="cx"> : m_liveness(liveness)
</span><span class="cx"> , m_iterable(iterable)
</span><span class="cx"> {
</span><span class="lines">@@ -327,7 +313,7 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>- iterator(AbstractLiveness& liveness, typename UnderlyingIterable::const_iterator iter)
</del><ins>+ iterator(Liveness& liveness, typename UnderlyingIterable::const_iterator iter)
</ins><span class="cx"> : m_liveness(&liveness)
</span><span class="cx"> , m_iter(iter)
</span><span class="cx"> {
</span><span class="lines">@@ -356,7 +342,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- AbstractLiveness* m_liveness;
</del><ins>+ Liveness* m_liveness;
</ins><span class="cx"> typename UnderlyingIterable::const_iterator m_iter;
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -369,7 +355,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- AbstractLiveness& m_liveness;
</del><ins>+ Liveness& m_liveness;
</ins><span class="cx"> const UnderlyingIterable& m_iterable;
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -387,7 +373,7 @@
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> friend class LocalCalc;
</span><del>- friend struct LocalCalc::Iterable;
</del><ins>+ friend class LocalCalc::Iterable;
</ins><span class="cx">
</span><span class="cx"> IndexSparseSet<UnsafeVectorOverflow> m_workset;
</span><span class="cx"> IndexMap<BasicBlock, Vector<unsigned>> m_liveAtHead;
</span><span class="lines">@@ -395,12 +381,11 @@
</span><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> template<Bank bank, Arg::Temperature minimumTemperature = Arg::Cold>
</span><del>-using TmpLiveness = AbstractLiveness<TmpLivenessAdapter<bank, minimumTemperature>>;
</del><ins>+using TmpLiveness = Liveness<TmpLivenessAdapter<bank, minimumTemperature>>;
</ins><span class="cx">
</span><del>-typedef AbstractLiveness<TmpLivenessAdapter<GP>> GPLiveness;
-typedef AbstractLiveness<TmpLivenessAdapter<FP>> FPLiveness;
-typedef AbstractLiveness<StackSlotLivenessAdapter> StackSlotLiveness;
-typedef AbstractLiveness<RegLivenessAdapter> RegLiveness;
</del><ins>+typedef Liveness<TmpLivenessAdapter<GP>> GPLiveness;
+typedef Liveness<TmpLivenessAdapter<FP>> FPLiveness;
+typedef Liveness<StackSlotLivenessAdapter> StackSlotLiveness;
</ins><span class="cx">
</span><span class="cx"> } } } // namespace JSC::B3::Air
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLogRegisterPressurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirLogRegisterPressure.cpp (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLogRegisterPressure.cpp        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/b3/air/AirLogRegisterPressure.cpp        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> #include "AirArgInlines.h"
</span><span class="cx"> #include "AirCode.h"
</span><span class="cx"> #include "AirInstInlines.h"
</span><del>-#include "AirLiveness.h"
</del><ins>+#include "AirRegLiveness.h"
</ins><span class="cx">
</span><span class="cx"> namespace JSC { namespace B3 { namespace Air {
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -34,7 +34,7 @@
</span><span class="cx"> #include "AirEmitShuffle.h"
</span><span class="cx"> #include "AirInsertionSet.h"
</span><span class="cx"> #include "AirInstInlines.h"
</span><del>-#include "AirLiveness.h"
</del><ins>+#include "AirRegLiveness.h"
</ins><span class="cx"> #include "AirPhaseScope.h"
</span><span class="cx"> #include "B3CCallValue.h"
</span><span class="cx"> #include "B3ValueInlines.h"
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirRegLivenesscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/air/AirRegLiveness.cpp (0 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirRegLiveness.cpp         (rev 0)
+++ trunk/Source/JavaScriptCore/b3/air/AirRegLiveness.cpp        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -0,0 +1,143 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AirRegLiveness.h"
+
+#if ENABLE(B3_JIT)
+
+#include "AirArgInlines.h"
+#include "AirInstInlines.h"
+
+namespace JSC { namespace B3 { namespace Air {
+
+RegLiveness::RegLiveness(Code& code)
+ : m_liveAtHead(code.size())
+ , m_liveAtTail(code.size())
+{
+ // The liveAtTail of each block automatically contains the LateUse's of the terminal.
+ for (BasicBlock* block : code) {
+ RegisterSet& liveAtTail = m_liveAtTail[block];
+
+ block->last().forEach<Reg>(
+ [&] (Reg& reg, Arg::Role role, Bank, Width) {
+ if (Arg::isLateUse(role))
+ liveAtTail.add(reg);
+ });
+ }
+
+ BitVector dirtyBlocks;
+ for (size_t blockIndex = code.size(); blockIndex--;)
+ dirtyBlocks.set(blockIndex);
+
+ bool changed;
+ do {
+ changed = false;
+
+ for (size_t blockIndex = code.size(); blockIndex--;) {
+ BasicBlock* block = code[blockIndex];
+ if (!block)
+ continue;
+
+ if (!dirtyBlocks.quickClear(blockIndex))
+ continue;
+
+ LocalCalc localCalc(*this, block);
+ for (size_t instIndex = block->size(); instIndex--;)
+ localCalc.execute(instIndex);
+
+ // Handle the early def's of the first instruction.
+ block->at(0).forEach<Reg>(
+ [&] (Reg& reg, Arg::Role role, Bank, Width) {
+ if (Arg::isEarlyDef(role))
+ localCalc.m_workset.remove(reg);
+ });
+
+ RegisterSet& liveAtHead = m_liveAtHead[block];
+ if (liveAtHead.subsumes(localCalc.m_workset))
+ continue;
+
+ liveAtHead.merge(localCalc.m_workset);
+
+ for (BasicBlock* predecessor : block->predecessors()) {
+ RegisterSet& liveAtTail = m_liveAtTail[predecessor];
+ if (liveAtTail.subsumes(localCalc.m_workset))
+ continue;
+
+ liveAtTail.merge(localCalc.m_workset);
+ dirtyBlocks.quickSet(predecessor->index());
+ changed = true;
+ }
+ }
+ } while (changed);
+}
+
+RegLiveness::~RegLiveness()
+{
+}
+
+void RegLiveness::LocalCalc::execute(unsigned instIndex)
+{
+ Inst& inst = m_block->at(instIndex);
+
+ // First handle the early def's of the next instruction.
+ if (instIndex + 1 < m_block->size()) {
+ Inst& nextInst = m_block->at(instIndex + 1);
+ nextInst.forEach<Reg>(
+ [&] (Reg& reg, Arg::Role role, Bank, Width) {
+ if (Arg::isEarlyDef(role))
+ m_workset.remove(reg);
+ });
+ }
+
+ // Then handle def's.
+ inst.forEach<Reg>(
+ [&] (Reg& reg, Arg::Role role, Bank, Width) {
+ if (Arg::isLateDef(role))
+ m_workset.remove(reg);
+ });
+
+ // Then handle use's.
+ inst.forEach<Reg>(
+ [&] (Reg& reg, Arg::Role role, Bank, Width) {
+ if (Arg::isEarlyUse(role))
+ m_workset.add(reg);
+ });
+
+ // And finally, handle the late use's of the previous instruction.
+ if (instIndex) {
+ Inst& prevInst = m_block->at(instIndex - 1);
+ prevInst.forEach<Reg>(
+ [&] (Reg& reg, Arg::Role role, Bank, Width) {
+ if (Arg::isLateUse(role))
+ m_workset.add(reg);
+ });
+ }
+}
+
+} } } // namespace JSC::B3::Air
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirRegLivenessh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/air/AirRegLiveness.h (0 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirRegLiveness.h         (rev 0)
+++ trunk/Source/JavaScriptCore/b3/air/AirRegLiveness.h        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(B3_JIT)
+
+#include "AirBasicBlock.h"
+#include "AirCode.h"
+#include "AirInst.h"
+#include "RegisterSet.h"
+
+namespace JSC { namespace B3 { namespace Air {
+
+// Although we could trivially adapt Air::Liveness<> to work with Reg, this would not be so
+// efficient. There is a small number of registers, so it's much better to use bitvectors for
+// register liveness. This is a specialization of Liveness<> that uses bitvectors directly.
+// This makes the code sufficiently different that it didn't make sense to try to share code.
+class RegLiveness {
+public:
+ typedef Reg Thing;
+
+ RegLiveness(Code& code);
+ ~RegLiveness();
+
+ // This calculator has to be run in reverse.
+ class LocalCalc {
+ public:
+ LocalCalc(RegLiveness& liveness, BasicBlock* block)
+ : m_block(block)
+ , m_workset(liveness.m_liveAtTail[block])
+ {
+ }
+
+ const RegisterSet& live() const
+ {
+ return m_workset;
+ }
+
+ bool isLive(Reg reg) const
+ {
+ return m_workset.contains(reg);
+ }
+
+ void execute(unsigned instIndex);
+
+ private:
+ friend class RegLiveness;
+
+ BasicBlock* m_block;
+ RegisterSet m_workset;
+ };
+
+ const RegisterSet& liveAtHead(BasicBlock* block) const
+ {
+ return m_liveAtHead[block];
+ }
+
+ const RegisterSet& liveAtTail(BasicBlock* block) const
+ {
+ return m_liveAtTail[block];
+ }
+
+private:
+ IndexMap<BasicBlock, RegisterSet> m_liveAtHead;
+ IndexMap<BasicBlock, RegisterSet> m_liveAtTail;
+};
+
+} } } // namespace JSC::B3::Air
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirReportUsedRegisterscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -31,7 +31,7 @@
</span><span class="cx"> #include "AirArgInlines.h"
</span><span class="cx"> #include "AirCode.h"
</span><span class="cx"> #include "AirInstInlines.h"
</span><del>-#include "AirLiveness.h"
</del><ins>+#include "AirRegLiveness.h"
</ins><span class="cx"> #include "AirPhaseScope.h"
</span><span class="cx">
</span><span class="cx"> namespace JSC { namespace B3 { namespace Air {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRegisterSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/RegisterSet.h (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/RegisterSet.h        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/JavaScriptCore/jit/RegisterSet.h        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * Redistribution and use in source and binary forms, with or without
</span><span class="cx"> * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -36,6 +36,8 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><ins>+typedef Bitmap<MacroAssembler::numGPRs + MacroAssembler::numFPRs + 1> RegisterBitmap;
+
</ins><span class="cx"> class RegisterSet {
</span><span class="cx"> public:
</span><span class="cx"> template<typename... Regs>
</span><span class="lines">@@ -99,10 +101,17 @@
</span><span class="cx"> set(reg);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ // Also allow add/remove/contains terminology, which means the same thing as set/clear/get.
+ void add(Reg reg) { set(reg); }
+ void remove(Reg reg) { clear(reg); }
+ bool contains(Reg reg) const { return get(reg); }
+
</ins><span class="cx"> void merge(const RegisterSet& other) { m_bits.merge(other.m_bits); }
</span><span class="cx"> void filter(const RegisterSet& other) { m_bits.filter(other.m_bits); }
</span><span class="cx"> void exclude(const RegisterSet& other) { m_bits.exclude(other.m_bits); }
</span><span class="cx">
</span><ins>+ bool subsumes(const RegisterSet& other) const { return m_bits.subsumes(other.m_bits); }
+
</ins><span class="cx"> size_t numberOfSetGPRs() const;
</span><span class="cx"> size_t numberOfSetFPRs() const;
</span><span class="cx"> size_t numberOfSetRegisters() const { return m_bits.count(); }
</span><span class="lines">@@ -149,6 +158,42 @@
</span><span class="cx"> });
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ class iterator {
+ public:
+ iterator()
+ {
+ }
+
+ iterator(const RegisterBitmap::iterator& iter)
+ : m_iter(iter)
+ {
+ }
+
+ Reg operator*() const { return Reg::fromIndex(*m_iter); }
+
+ iterator& operator++()
+ {
+ ++m_iter;
+ return *this;
+ }
+
+ bool operator==(const iterator& other)
+ {
+ return m_iter == other.m_iter;
+ }
+
+ bool operator!=(const iterator& other)
+ {
+ return !(*this == other);
+ }
+
+ private:
+ RegisterBitmap::iterator m_iter;
+ };
+
+ iterator begin() const { return iterator(m_bits.begin()); }
+ iterator end() const { return iterator(m_bits.end()); }
+
</ins><span class="cx"> private:
</span><span class="cx"> void setAny(Reg reg) { set(reg); }
</span><span class="cx"> void setAny(const RegisterSet& set) { merge(set); }
</span><span class="lines">@@ -166,7 +211,7 @@
</span><span class="cx"> static const unsigned hashSpecialBitIndex = fprOffset + MacroAssembler::numFPRs;
</span><span class="cx"> static const unsigned deletedBitIndex = 0;
</span><span class="cx">
</span><del>- Bitmap<MacroAssembler::numGPRs + MacroAssembler::numFPRs + 1> m_bits;
</del><ins>+ RegisterBitmap m_bits;
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> struct RegisterSetHash {
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/WTF/ChangeLog        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2017-03-26 Filip Pizlo <fpizlo@apple.com>
+
+ Air should use RegisterSet for RegLiveness
+ https://bugs.webkit.org/show_bug.cgi?id=170108
+
+ Reviewed by Yusuke Suzuki.
+
+ * wtf/Atomics.h:
+ (WTF::ensurePointer): This is a useful replacement for std::once, which requires less fencing.
+ * wtf/Bitmap.h: Add more utilities.
+ (WTF::Bitmap::iterator::iterator): An iterator for set bits.
+ (WTF::Bitmap::iterator::operator*):
+ (WTF::Bitmap::iterator::operator++):
+ (WTF::Bitmap::iterator::operator==):
+ (WTF::Bitmap::iterator::operator!=):
+ (WTF::Bitmap::begin):
+ (WTF::Bitmap::end):
+ (WTF::WordType>::subsumes): a.subsumes(b) if all of b's set bits are set in a.
+ (WTF::WordType>::findBit): find next set or clear bit.
+
</ins><span class="cx"> 2017-03-24 JF Bastien <jfbastien@apple.com>
</span><span class="cx">
</span><span class="cx"> WebAssembly: store state in TLS instead of on VM
</span></span></pre></div>
<a id="trunkSourceWTFwtfAtomicsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Atomics.h (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Atomics.h        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/WTF/wtf/Atomics.h        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -519,6 +519,23 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+template<typename T, typename Func>
+ALWAYS_INLINE T& ensurePointer(Atomic<T*>& pointer, const Func& func)
+{
+ for (;;) {
+ T* oldValue = pointer.load(std::memory_order_relaxed);
+ if (oldValue) {
+ // On all sensible CPUs, we get an implicit dependency-based load-load barrier when
+ // loading this.
+ return *oldValue;
+ }
+ T* newValue = func();
+ if (pointer.compareExchangeWeak(oldValue, newValue))
+ return *newValue;
+ delete newValue;
+ }
+}
+
</ins><span class="cx"> } // namespace WTF
</span><span class="cx">
</span><span class="cx"> using WTF::Atomic;
</span><span class="lines">@@ -528,6 +545,7 @@
</span><span class="cx"> using WTF::consume;
</span><span class="cx"> using WTF::dependency;
</span><span class="cx"> using WTF::dependencyWith;
</span><ins>+using WTF::ensurePointer;
</ins><span class="cx"> using WTF::nullDependency;
</span><span class="cx">
</span><span class="cx"> #endif // Atomics_h
</span></span></pre></div>
<a id="trunkSourceWTFwtfBitmaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Bitmap.h (214407 => 214408)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Bitmap.h        2017-03-26 03:52:40 UTC (rev 214407)
+++ trunk/Source/WTF/wtf/Bitmap.h        2017-03-26 21:39:27 UTC (rev 214408)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * This library is free software; you can redistribute it and/or
</span><span class="cx"> * modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -59,9 +59,54 @@
</span><span class="cx"> void filter(const Bitmap&);
</span><span class="cx"> void exclude(const Bitmap&);
</span><span class="cx">
</span><ins>+ bool subsumes(const Bitmap&) const;
+
</ins><span class="cx"> template<typename Func>
</span><span class="cx"> void forEachSetBit(const Func&) const;
</span><span class="cx">
</span><ins>+ size_t findBit(size_t startIndex, bool value) const;
+
+ class iterator {
+ public:
+ iterator()
+ : m_bitmap(nullptr)
+ , m_index(0)
+ {
+ }
+
+ iterator(const Bitmap& bitmap, size_t index)
+ : m_bitmap(&bitmap)
+ , m_index(index)
+ {
+ }
+
+ size_t operator*() const { return m_index; }
+
+ iterator& operator++()
+ {
+ m_index = m_bitmap->findBit(m_index + 1, true);
+ return *this;
+ }
+
+ bool operator==(const iterator& other) const
+ {
+ return m_index == other.m_index;
+ }
+
+ bool operator!=(const iterator& other) const
+ {
+ return !(*this == other);
+ }
+
+ private:
+ const Bitmap* m_bitmap;
+ size_t m_index;
+ };
+
+ // Use this to iterate over set bits.
+ iterator begin() const { return iterator(*this, findBit(0, true)); }
+ iterator end() const { return iterator(*this, bitmapSize); }
+
</ins><span class="cx"> void mergeAndClear(Bitmap&);
</span><span class="cx"> void setAndClear(Bitmap&);
</span><span class="cx">
</span><span class="lines">@@ -258,6 +303,18 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template<size_t bitmapSize, typename WordType>
</span><ins>+inline bool Bitmap<bitmapSize, WordType>::subsumes(const Bitmap& other) const
+{
+ for (size_t i = 0; i < words; ++i) {
+ WordType myBits = bits[i];
+ WordType otherBits = other.bits[i];
+ if ((myBits | otherBits) != myBits)
+ return false;
+ }
+ return true;
+}
+
+template<size_t bitmapSize, typename WordType>
</ins><span class="cx"> template<typename Func>
</span><span class="cx"> inline void Bitmap<bitmapSize, WordType>::forEachSetBit(const Func& func) const
</span><span class="cx"> {
</span><span class="lines">@@ -275,6 +332,28 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template<size_t bitmapSize, typename WordType>
</span><ins>+inline size_t Bitmap<bitmapSize, WordType>::findBit(size_t startIndex, bool value) const
+{
+ WordType skipValue = -(static_cast<WordType>(value) ^ 1);
+ size_t wordIndex = startIndex / wordSize;
+ size_t startIndexInWord = startIndex - wordIndex * wordSize;
+
+ while (wordIndex < words) {
+ WordType word = bits[wordIndex];
+ if (word != skipValue) {
+ size_t index = startIndexInWord;
+ if (findBitInWord(word, index, wordSize, value))
+ return wordIndex * wordSize + index;
+ }
+
+ wordIndex++;
+ startIndexInWord = 0;
+ }
+
+ return bitmapSize;
+}
+
+template<size_t bitmapSize, typename WordType>
</ins><span class="cx"> inline void Bitmap<bitmapSize, WordType>::mergeAndClear(Bitmap& other)
</span><span class="cx"> {
</span><span class="cx"> for (size_t i = 0; i < words; ++i) {
</span></span></pre>
</div>
</div>
</body>
</html>