<!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>[206640] trunk</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/206640">206640</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-09-30 09:59:24 -0700 (Fri, 30 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Air should have a way of expressing additional instruction flags
https://bugs.webkit.org/show_bug.cgi?id=162699

Reviewed by Mark Lam.
Source/JavaScriptCore:

        
This follows a similar change in B3 (<a href="http://trac.webkit.org/projects/webkit/changeset/206595">r206595</a>) and replaces Air::Opcode with Air::Kind,
which holds onto the opcode and some additional flags. Because Air is an orthogonal ISA
(the opcode tells you what the operation does but each operand is allowed to also contain
effectively instructions for what to do to read or write that operand), the flags are
meant to be orthogonal to opcode. This allows us to say things like Add32&lt;Trap&gt;, which
makes sense if any of the operands to the Add32 are addresses.
        
To demonstrate the flags facility this partly adds a trap flag to Air. B3 doesn't use it
yet, but I made sure that Air respects it. Basically that means blocking DCE when the flag
is set, by making it imply hasNonArgNonControlEffects.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/B3CheckSpecial.cpp:
(JSC::B3::Air::numB3Args):
(JSC::B3::CheckSpecial::Key::Key):
(JSC::B3::CheckSpecial::Key::dump):
(JSC::B3::CheckSpecial::CheckSpecial):
(JSC::B3::CheckSpecial::hiddenBranch):
(JSC::B3::CheckSpecial::forEachArg):
(JSC::B3::CheckSpecial::generate):
(JSC::B3::CheckSpecial::dumpImpl):
(JSC::B3::CheckSpecial::deepDumpImpl):
* b3/B3CheckSpecial.h:
(JSC::B3::CheckSpecial::Key::Key):
(JSC::B3::CheckSpecial::Key::operator==):
(JSC::B3::CheckSpecial::Key::kind):
(JSC::B3::CheckSpecial::Key::hash):
(JSC::B3::CheckSpecial::Key::opcode): Deleted.
* b3/B3Kind.cpp:
(JSC::B3::Kind::dump):
* b3/air/AirDumpAsJS.cpp:
(JSC::B3::Air::dumpAsJS):
* b3/air/AirFixObviousSpills.cpp:
* b3/air/AirFixPartialRegisterStalls.cpp:
* b3/air/AirGenerate.cpp:
(JSC::B3::Air::generate):
* b3/air/AirHandleCalleeSaves.cpp:
(JSC::B3::Air::handleCalleeSaves):
* b3/air/AirInst.cpp:
(JSC::B3::Air::Inst::jsHash):
(JSC::B3::Air::Inst::dump):
* b3/air/AirInst.h:
(JSC::B3::Air::Inst::Inst):
(JSC::B3::Air::Inst::kind):
(JSC::B3::Air::Inst::operator bool):
(JSC::B3::Air::Inst::opcode): Deleted.
* b3/air/AirInstInlines.h:
(JSC::B3::Air::Inst::extraClobberedRegs):
(JSC::B3::Air::Inst::extraEarlyClobberedRegs):
(JSC::B3::Air::Inst::forEachDefWithExtraClobberedRegs):
(JSC::B3::Air::Inst::reportUsedRegisters):
(JSC::B3::Air::Inst::shouldTryAliasingDef):
* b3/air/AirIteratedRegisterCoalescing.cpp:
* b3/air/AirKind.cpp: Added.
(JSC::B3::Air::Kind::dump):
* b3/air/AirKind.h: Added.
(JSC::B3::Air::Kind::Kind):
(JSC::B3::Air::Kind::operator==):
(JSC::B3::Air::Kind::operator!=):
(JSC::B3::Air::Kind::hash):
(JSC::B3::Air::Kind::operator bool):
* b3/air/AirLowerAfterRegAlloc.cpp:
(JSC::B3::Air::lowerAfterRegAlloc):
* b3/air/AirLowerEntrySwitch.cpp:
(JSC::B3::Air::lowerEntrySwitch):
* b3/air/AirLowerMacros.cpp:
(JSC::B3::Air::lowerMacros):
* b3/air/AirOptimizeBlockOrder.cpp:
(JSC::B3::Air::optimizeBlockOrder):
* b3/air/AirReportUsedRegisters.cpp:
(JSC::B3::Air::reportUsedRegisters):
* b3/air/AirSimplifyCFG.cpp:
(JSC::B3::Air::simplifyCFG):
* b3/air/AirTmpWidth.cpp:
(JSC::B3::Air::TmpWidth::recompute):
* b3/air/AirUseCounts.h:
(JSC::B3::Air::UseCounts::UseCounts):
* b3/air/AirValidate.cpp:
* b3/air/opcode_generator.rb:
* b3/testb3.cpp:
(JSC::B3::testTernarySubInstructionSelection):
(JSC::B3::testBranchBitAndImmFusion):

Source/WTF:


* wtf/CommaPrinter.h:
(WTF::CommaPrinter::CommaPrinter):
(WTF::CommaPrinter::dump):
(WTF::CommaPrinter::didPrint):

Websites/webkit.org:


* docs/b3/assembly-intermediate-representation.html:</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="#trunkSourceJavaScriptCoreb3B3CheckSpecialcpp">trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CheckSpecialh">trunk/Source/JavaScriptCore/b3/B3CheckSpecial.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Kindcpp">trunk/Source/JavaScriptCore/b3/B3Kind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirDumpAsJScpp">trunk/Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirFixObviousSpillscpp">trunk/Source/JavaScriptCore/b3/air/AirFixObviousSpills.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirFixPartialRegisterStallscpp">trunk/Source/JavaScriptCore/b3/air/AirFixPartialRegisterStalls.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirGeneratecpp">trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirHandleCalleeSavescpp">trunk/Source/JavaScriptCore/b3/air/AirHandleCalleeSaves.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirInstcpp">trunk/Source/JavaScriptCore/b3/air/AirInst.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirInsth">trunk/Source/JavaScriptCore/b3/air/AirInst.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirInstInlinesh">trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirIteratedRegisterCoalescingcpp">trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloccpp">trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerEntrySwitchcpp">trunk/Source/JavaScriptCore/b3/air/AirLowerEntrySwitch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerMacroscpp">trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirOptimizeBlockOrdercpp">trunk/Source/JavaScriptCore/b3/air/AirOptimizeBlockOrder.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirReportUsedRegisterscpp">trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirSimplifyCFGcpp">trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirTmpWidthcpp">trunk/Source/JavaScriptCore/b3/air/AirTmpWidth.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirUseCountsh">trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirValidatecpp">trunk/Source/JavaScriptCore/b3/air/AirValidate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airopcode_generatorrb">trunk/Source/JavaScriptCore/b3/air/opcode_generator.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfCommaPrinterh">trunk/Source/WTF/wtf/CommaPrinter.h</a></li>
<li><a href="#trunkWebsiteswebkitorgChangeLog">trunk/Websites/webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsiteswebkitorgdocsb3assemblyintermediaterepresentationhtml">trunk/Websites/webkit.org/docs/b3/assembly-intermediate-representation.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3airAirKindcpp">trunk/Source/JavaScriptCore/b3/air/AirKind.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirKindh">trunk/Source/JavaScriptCore/b3/air/AirKind.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 (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -88,6 +88,7 @@
</span><span class="cx">     b3/air/AirInsertionSet.cpp
</span><span class="cx">     b3/air/AirInst.cpp
</span><span class="cx">     b3/air/AirIteratedRegisterCoalescing.cpp
</span><ins>+    b3/air/AirKind.cpp
</ins><span class="cx">     b3/air/AirLogRegisterPressure.cpp
</span><span class="cx">     b3/air/AirLowerAfterRegAlloc.cpp
</span><span class="cx">     b3/air/AirLowerEntrySwitch.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -1,5 +1,96 @@
</span><span class="cx"> 2016-09-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Air should have a way of expressing additional instruction flags
+        https://bugs.webkit.org/show_bug.cgi?id=162699
+
+        Reviewed by Mark Lam.
+        
+        This follows a similar change in B3 (r206595) and replaces Air::Opcode with Air::Kind,
+        which holds onto the opcode and some additional flags. Because Air is an orthogonal ISA
+        (the opcode tells you what the operation does but each operand is allowed to also contain
+        effectively instructions for what to do to read or write that operand), the flags are
+        meant to be orthogonal to opcode. This allows us to say things like Add32&lt;Trap&gt;, which
+        makes sense if any of the operands to the Add32 are addresses.
+        
+        To demonstrate the flags facility this partly adds a trap flag to Air. B3 doesn't use it
+        yet, but I made sure that Air respects it. Basically that means blocking DCE when the flag
+        is set, by making it imply hasNonArgNonControlEffects.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * b3/B3CheckSpecial.cpp:
+        (JSC::B3::Air::numB3Args):
+        (JSC::B3::CheckSpecial::Key::Key):
+        (JSC::B3::CheckSpecial::Key::dump):
+        (JSC::B3::CheckSpecial::CheckSpecial):
+        (JSC::B3::CheckSpecial::hiddenBranch):
+        (JSC::B3::CheckSpecial::forEachArg):
+        (JSC::B3::CheckSpecial::generate):
+        (JSC::B3::CheckSpecial::dumpImpl):
+        (JSC::B3::CheckSpecial::deepDumpImpl):
+        * b3/B3CheckSpecial.h:
+        (JSC::B3::CheckSpecial::Key::Key):
+        (JSC::B3::CheckSpecial::Key::operator==):
+        (JSC::B3::CheckSpecial::Key::kind):
+        (JSC::B3::CheckSpecial::Key::hash):
+        (JSC::B3::CheckSpecial::Key::opcode): Deleted.
+        * b3/B3Kind.cpp:
+        (JSC::B3::Kind::dump):
+        * b3/air/AirDumpAsJS.cpp:
+        (JSC::B3::Air::dumpAsJS):
+        * b3/air/AirFixObviousSpills.cpp:
+        * b3/air/AirFixPartialRegisterStalls.cpp:
+        * b3/air/AirGenerate.cpp:
+        (JSC::B3::Air::generate):
+        * b3/air/AirHandleCalleeSaves.cpp:
+        (JSC::B3::Air::handleCalleeSaves):
+        * b3/air/AirInst.cpp:
+        (JSC::B3::Air::Inst::jsHash):
+        (JSC::B3::Air::Inst::dump):
+        * b3/air/AirInst.h:
+        (JSC::B3::Air::Inst::Inst):
+        (JSC::B3::Air::Inst::kind):
+        (JSC::B3::Air::Inst::operator bool):
+        (JSC::B3::Air::Inst::opcode): Deleted.
+        * b3/air/AirInstInlines.h:
+        (JSC::B3::Air::Inst::extraClobberedRegs):
+        (JSC::B3::Air::Inst::extraEarlyClobberedRegs):
+        (JSC::B3::Air::Inst::forEachDefWithExtraClobberedRegs):
+        (JSC::B3::Air::Inst::reportUsedRegisters):
+        (JSC::B3::Air::Inst::shouldTryAliasingDef):
+        * b3/air/AirIteratedRegisterCoalescing.cpp:
+        * b3/air/AirKind.cpp: Added.
+        (JSC::B3::Air::Kind::dump):
+        * b3/air/AirKind.h: Added.
+        (JSC::B3::Air::Kind::Kind):
+        (JSC::B3::Air::Kind::operator==):
+        (JSC::B3::Air::Kind::operator!=):
+        (JSC::B3::Air::Kind::hash):
+        (JSC::B3::Air::Kind::operator bool):
+        * b3/air/AirLowerAfterRegAlloc.cpp:
+        (JSC::B3::Air::lowerAfterRegAlloc):
+        * b3/air/AirLowerEntrySwitch.cpp:
+        (JSC::B3::Air::lowerEntrySwitch):
+        * b3/air/AirLowerMacros.cpp:
+        (JSC::B3::Air::lowerMacros):
+        * b3/air/AirOptimizeBlockOrder.cpp:
+        (JSC::B3::Air::optimizeBlockOrder):
+        * b3/air/AirReportUsedRegisters.cpp:
+        (JSC::B3::Air::reportUsedRegisters):
+        * b3/air/AirSimplifyCFG.cpp:
+        (JSC::B3::Air::simplifyCFG):
+        * b3/air/AirTmpWidth.cpp:
+        (JSC::B3::Air::TmpWidth::recompute):
+        * b3/air/AirUseCounts.h:
+        (JSC::B3::Air::UseCounts::UseCounts):
+        * b3/air/AirValidate.cpp:
+        * b3/air/opcode_generator.rb:
+        * b3/testb3.cpp:
+        (JSC::B3::testTernarySubInstructionSelection):
+        (JSC::B3::testBranchBitAndImmFusion):
+
+2016-09-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         REGRESSION(r206555): It made Dromaeo/jslib-style-jquery.html crash
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=162721
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -728,6 +728,8 @@
</span><span class="cx">                 0FDDBFB61666EEDA00C55FEF /* DFGVariableAccessDataDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */; };
</span><span class="cx">                 0FDF67D21D9C6D27001B9825 /* B3Kind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDF67D11D9C6086001B9825 /* B3Kind.h */; };
</span><span class="cx">                 0FDF67D31D9C6D2A001B9825 /* B3Kind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF67D01D9C6086001B9825 /* B3Kind.cpp */; };
</span><ins>+                0FDF67D61D9DC440001B9825 /* AirKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF67D41D9DC43E001B9825 /* AirKind.cpp */; };
+                0FDF67D71D9DC442001B9825 /* AirKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDF67D51D9DC43E001B9825 /* AirKind.h */; };
</ins><span class="cx">                 0FDF70851D3F2C2200927449 /* AirLowerEntrySwitch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF70831D3F2C1F00927449 /* AirLowerEntrySwitch.cpp */; };
</span><span class="cx">                 0FDF70861D3F2C2500927449 /* AirLowerEntrySwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FDF70841D3F2C1F00927449 /* AirLowerEntrySwitch.h */; };
</span><span class="cx">                 0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2987,6 +2989,8 @@
</span><span class="cx">                 0FDDBFB31666EED500C55FEF /* DFGVariableAccessDataDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessDataDump.h; path = dfg/DFGVariableAccessDataDump.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FDF67D01D9C6086001B9825 /* B3Kind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3Kind.cpp; path = b3/B3Kind.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FDF67D11D9C6086001B9825 /* B3Kind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3Kind.h; path = b3/B3Kind.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0FDF67D41D9DC43E001B9825 /* AirKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirKind.cpp; path = b3/air/AirKind.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0FDF67D51D9DC43E001B9825 /* AirKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirKind.h; path = b3/air/AirKind.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0FDF70831D3F2C1F00927449 /* AirLowerEntrySwitch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirLowerEntrySwitch.cpp; path = b3/air/AirLowerEntrySwitch.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FDF70841D3F2C1F00927449 /* AirLowerEntrySwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirLowerEntrySwitch.h; path = b3/air/AirLowerEntrySwitch.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArgumentsMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5013,6 +5017,8 @@
</span><span class="cx">                                 0FEC855C1BDACDC70080FF74 /* AirInstInlines.h */,
</span><span class="cx">                                 26718BA21BE99F780052017B /* AirIteratedRegisterCoalescing.cpp */,
</span><span class="cx">                                 26718BA31BE99F780052017B /* AirIteratedRegisterCoalescing.h */,
</span><ins>+                                0FDF67D41D9DC43E001B9825 /* AirKind.cpp */,
+                                0FDF67D51D9DC43E001B9825 /* AirKind.h */,
</ins><span class="cx">                                 2684D4371C00161C0081D663 /* AirLiveness.h */,
</span><span class="cx">                                 0FE34C171C4B39AE0003A512 /* AirLogRegisterPressure.cpp */,
</span><span class="cx">                                 0FE34C181C4B39AE0003A512 /* AirLogRegisterPressure.h */,
</span><span class="lines">@@ -7559,6 +7565,7 @@
</span><span class="cx">                                 A7D89CFE17A0B8CC00773AD8 /* DFGOSRAvailabilityAnalysisPhase.h in Headers */,
</span><span class="cx">                                 0FD82E57141DAF1000179C94 /* DFGOSREntry.h in Headers */,
</span><span class="cx">                                 0F40E4A71C497F7400A577FA /* AirOpcode.h in Headers */,
</span><ins>+                                0FDF67D71D9DC442001B9825 /* AirKind.h in Headers */,
</ins><span class="cx">                                 0FD8A32617D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.h in Headers */,
</span><span class="cx">                                 0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */,
</span><span class="cx">                                 0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */,
</span><span class="lines">@@ -8928,6 +8935,7 @@
</span><span class="cx">                                 0F4570381BE44C910062A629 /* AirEliminateDeadCode.cpp in Sources */,
</span><span class="cx">                                 43AB26C71C1A535C00D82AE6 /* B3MathExtras.cpp in Sources */,
</span><span class="cx">                                 0FEC85781BDACDC70080FF74 /* AirGenerate.cpp in Sources */,
</span><ins>+                                0FDF67D61D9DC440001B9825 /* AirKind.cpp in Sources */,
</ins><span class="cx">                                 0FEC85931BDB1E100080FF74 /* AirGenerated.cpp in Sources */,
</span><span class="cx">                                 53486BBB1C18E84500F6F3AF /* JSTypedArray.cpp in Sources */,
</span><span class="cx">                                 0FEC857B1BDACDC70080FF74 /* AirHandleCalleeSaves.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckSpecialcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -40,9 +40,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace {
</span><span class="cx"> 
</span><del>-unsigned numB3Args(B3::Opcode opcode)
</del><ins>+unsigned numB3Args(B3::Kind kind)
</ins><span class="cx"> {
</span><del>-    switch (opcode) {
</del><ins>+    switch (kind.opcode()) {
</ins><span class="cx">     case CheckAdd:
</span><span class="cx">     case CheckSub:
</span><span class="cx">     case CheckMul:
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx"> 
</span><span class="cx"> unsigned numB3Args(Value* value)
</span><span class="cx"> {
</span><del>-    return numB3Args(value-&gt;opcode());
</del><ins>+    return numB3Args(value-&gt;kind());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned numB3Args(Inst&amp; inst)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx"> 
</span><span class="cx"> CheckSpecial::Key::Key(const Inst&amp; inst)
</span><span class="cx"> {
</span><del>-    m_opcode = inst.opcode;
</del><ins>+    m_kind = inst.kind;
</ins><span class="cx">     m_numArgs = inst.args.size();
</span><span class="cx">     m_stackmapRole = SameAsRep;
</span><span class="cx"> }
</span><span class="lines">@@ -76,19 +76,19 @@
</span><span class="cx"> 
</span><span class="cx"> void CheckSpecial::Key::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(m_opcode, &quot;(&quot;, m_numArgs, &quot;,&quot;, m_stackmapRole, &quot;)&quot;);
</del><ins>+    out.print(m_kind, &quot;(&quot;, m_numArgs, &quot;,&quot;, m_stackmapRole, &quot;)&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-CheckSpecial::CheckSpecial(Air::Opcode opcode, unsigned numArgs, RoleMode stackmapRole)
-    : m_checkOpcode(opcode)
</del><ins>+CheckSpecial::CheckSpecial(Air::Kind kind, unsigned numArgs, RoleMode stackmapRole)
+    : m_checkKind(kind)
</ins><span class="cx">     , m_stackmapRole(stackmapRole)
</span><span class="cx">     , m_numCheckArgs(numArgs)
</span><span class="cx"> {
</span><del>-    ASSERT(isDefinitelyTerminal(opcode));
</del><ins>+    ASSERT(isDefinitelyTerminal(kind.opcode));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CheckSpecial::CheckSpecial(const CheckSpecial::Key&amp; key)
</span><del>-    : CheckSpecial(key.opcode(), key.numArgs(), key.stackmapRole())
</del><ins>+    : CheckSpecial(key.kind(), key.numArgs(), key.stackmapRole())
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx"> 
</span><span class="cx"> Inst CheckSpecial::hiddenBranch(const Inst&amp; inst) const
</span><span class="cx"> {
</span><del>-    Inst hiddenBranch(m_checkOpcode, inst.origin);
</del><ins>+    Inst hiddenBranch(m_checkKind, inst.origin);
</ins><span class="cx">     hiddenBranch.args.reserveInitialCapacity(m_numCheckArgs);
</span><span class="cx">     for (unsigned i = 0; i &lt; m_numCheckArgs; ++i)
</span><span class="cx">         hiddenBranch.args.append(inst.args[i + 1]);
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">         });
</span><span class="cx"> 
</span><span class="cx">     Optional&lt;unsigned&gt; firstRecoverableIndex;
</span><del>-    if (m_checkOpcode == BranchAdd32 || m_checkOpcode == BranchAdd64)
</del><ins>+    if (m_checkKind.opcode == BranchAdd32 || m_checkKind.opcode == BranchAdd64)
</ins><span class="cx">         firstRecoverableIndex = 1;
</span><span class="cx">     forEachArgImpl(numB3Args(inst), m_numCheckArgs + 1, inst, m_stackmapRole, firstRecoverableIndex, callback);
</span><span class="cx"> }
</span><span class="lines">@@ -164,7 +164,7 @@
</span><span class="cx">                 fail.link(&amp;jit);
</span><span class="cx"> 
</span><span class="cx">                 // If necessary, undo the operation.
</span><del>-                switch (m_checkOpcode) {
</del><ins>+                switch (m_checkKind.opcode) {
</ins><span class="cx">                 case BranchAdd32:
</span><span class="cx">                     if ((m_numCheckArgs == 4 &amp;&amp; args[1] == args[2] &amp;&amp; args[2] == args[3])
</span><span class="cx">                         || (m_numCheckArgs == 3 &amp;&amp; args[1] == args[2])) {
</span><span class="lines">@@ -235,12 +235,12 @@
</span><span class="cx"> 
</span><span class="cx"> void CheckSpecial::dumpImpl(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(m_checkOpcode, &quot;(&quot;, m_numCheckArgs, &quot;,&quot;, m_stackmapRole, &quot;)&quot;);
</del><ins>+    out.print(m_checkKind, &quot;(&quot;, m_numCheckArgs, &quot;,&quot;, m_stackmapRole, &quot;)&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CheckSpecial::deepDumpImpl(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(&quot;B3::CheckValue lowered to &quot;, m_checkOpcode, &quot; with &quot;, m_numCheckArgs, &quot; args.&quot;);
</del><ins>+    out.print(&quot;B3::CheckValue lowered to &quot;, m_checkKind, &quot; with &quot;, m_numCheckArgs, &quot; args.&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::B3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckSpecialh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckSpecial.h (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckSpecial.h        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/B3CheckSpecial.h        2016-09-30 16:59:24 UTC (rev 206640)
</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-2016 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">@@ -28,7 +28,7 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AirArg.h&quot;
</span><del>-#include &quot;AirOpcode.h&quot;
</del><ins>+#include &quot;AirKind.h&quot;
</ins><span class="cx"> #include &quot;B3StackmapSpecial.h&quot;
</span><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -55,14 +55,13 @@
</span><span class="cx">     class Key {
</span><span class="cx">     public:
</span><span class="cx">         Key()
</span><del>-            : m_opcode(Air::Nop)
-            , m_stackmapRole(SameAsRep)
</del><ins>+            : m_stackmapRole(SameAsRep)
</ins><span class="cx">             , m_numArgs(0)
</span><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        Key(Air::Opcode opcode, unsigned numArgs, RoleMode stackmapRole = SameAsRep)
-            : m_opcode(opcode)
</del><ins>+        Key(Air::Kind kind, unsigned numArgs, RoleMode stackmapRole = SameAsRep)
+            : m_kind(kind)
</ins><span class="cx">             , m_stackmapRole(stackmapRole)
</span><span class="cx">             , m_numArgs(numArgs)
</span><span class="cx">         {
</span><span class="lines">@@ -72,7 +71,7 @@
</span><span class="cx"> 
</span><span class="cx">         bool operator==(const Key&amp; other) const
</span><span class="cx">         {
</span><del>-            return m_opcode == other.m_opcode
</del><ins>+            return m_kind == other.m_kind
</ins><span class="cx">                 &amp;&amp; m_numArgs == other.m_numArgs
</span><span class="cx">                 &amp;&amp; m_stackmapRole == other.m_stackmapRole;
</span><span class="cx">         }
</span><span class="lines">@@ -84,7 +83,7 @@
</span><span class="cx"> 
</span><span class="cx">         explicit operator bool() const { return *this != Key(); }
</span><span class="cx"> 
</span><del>-        Air::Opcode opcode() const { return m_opcode; }
</del><ins>+        Air::Kind kind() const { return m_kind; }
</ins><span class="cx">         unsigned numArgs() const { return m_numArgs; }
</span><span class="cx">         RoleMode stackmapRole() const { return m_stackmapRole; }
</span><span class="cx"> 
</span><span class="lines">@@ -91,8 +90,7 @@
</span><span class="cx">         void dump(PrintStream&amp; out) const;
</span><span class="cx"> 
</span><span class="cx">         Key(WTF::HashTableDeletedValueType)
</span><del>-            : m_opcode(Air::Nop)
-            , m_stackmapRole(SameAsRep)
</del><ins>+            : m_stackmapRole(SameAsRep)
</ins><span class="cx">             , m_numArgs(1)
</span><span class="cx">         {
</span><span class="cx">         }
</span><span class="lines">@@ -105,16 +103,16 @@
</span><span class="cx">         unsigned hash() const
</span><span class="cx">         {
</span><span class="cx">             // Seriously, we don't need to be smart here. It just doesn't matter.
</span><del>-            return m_opcode + m_numArgs + m_stackmapRole;
</del><ins>+            return m_kind.hash() + m_numArgs + m_stackmapRole;
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">     private:
</span><del>-        Air::Opcode m_opcode;
</del><ins>+        Air::Kind m_kind;
</ins><span class="cx">         RoleMode m_stackmapRole;
</span><span class="cx">         unsigned m_numArgs;
</span><span class="cx">     };
</span><span class="cx">     
</span><del>-    CheckSpecial(Air::Opcode, unsigned numArgs, RoleMode stackmapRole = SameAsRep);
</del><ins>+    CheckSpecial(Air::Kind, unsigned numArgs, RoleMode stackmapRole = SameAsRep);
</ins><span class="cx">     CheckSpecial(const Key&amp;);
</span><span class="cx">     ~CheckSpecial();
</span><span class="cx"> 
</span><span class="lines">@@ -136,7 +134,7 @@
</span><span class="cx">     void deepDumpImpl(PrintStream&amp;) const override;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    Air::Opcode m_checkOpcode;
</del><ins>+    Air::Kind m_checkKind;
</ins><span class="cx">     RoleMode m_stackmapRole;
</span><span class="cx">     unsigned m_numCheckArgs;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Kindcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Kind.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Kind.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/B3Kind.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -35,14 +35,12 @@
</span><span class="cx"> void Kind::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     out.print(m_opcode);
</span><del>-    if (!hasExtraBits())
-        return;
</del><span class="cx">     
</span><del>-    CommaPrinter comma;
-    out.print(&quot;&lt;&quot;);
</del><ins>+    CommaPrinter comma(&quot;, &quot;, &quot;&lt;&quot;);
</ins><span class="cx">     if (isChill())
</span><span class="cx">         out.print(comma, &quot;Chill&quot;);
</span><del>-    out.print(&quot;&gt;&quot;);
</del><ins>+    if (comma.didPrint())
+        out.print(&quot;&gt;&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::B3
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirDumpAsJScpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirDumpAsJS.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -118,7 +118,9 @@
</span><span class="cx">             out.println(varName(block), &quot;.predecessors.push(&quot;, varName(predecessor), &quot;);&quot;);
</span><span class="cx">         
</span><span class="cx">         for (Inst&amp; inst : *block) {
</span><del>-            out.println(&quot;inst = new Inst(&quot;, inst.opcode, &quot;);&quot;);
</del><ins>+            // FIXME: This should do something for flags.
+            // https://bugs.webkit.org/show_bug.cgi?id=162751
+            out.println(&quot;inst = new Inst(&quot;, inst.kind.opcode, &quot;);&quot;);
</ins><span class="cx">             
</span><span class="cx">             inst.forEachArg(
</span><span class="cx">                 [&amp;] (Arg&amp; arg, Arg::Role, Arg::Type, Arg::Width) {
</span><span class="lines">@@ -197,7 +199,7 @@
</span><span class="cx">                     out.println(&quot;inst.args.push(arg);&quot;);
</span><span class="cx">                 });
</span><span class="cx">             
</span><del>-            if (inst.opcode == Patch) {
</del><ins>+            if (inst.kind.opcode == Patch) {
</ins><span class="cx">                 if (inst.hasNonArgEffects())
</span><span class="cx">                     out.println(&quot;inst.patchHasNonArgEffects = true;&quot;);
</span><span class="cx">                 
</span><span class="lines">@@ -221,7 +223,7 @@
</span><span class="cx">                     });
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            if (inst.opcode == CCall || inst.opcode == ColdCCall) {
</del><ins>+            if (inst.kind.opcode == CCall || inst.kind.opcode == ColdCCall) {
</ins><span class="cx">                 out.println(&quot;inst.cCallType = &quot;, inst.origin-&gt;type());
</span><span class="cx">                 out.println(&quot;inst.cCallArgTypes = [];&quot;);
</span><span class="cx">                 for (unsigned i = 1; i &lt; inst.origin-&gt;numChildren(); ++i)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirFixObviousSpillscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirFixObviousSpills.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirFixObviousSpills.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirFixObviousSpills.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -121,7 +121,7 @@
</span><span class="cx">                 m_state.clobber(arg);
</span><span class="cx">             });
</span><span class="cx"> 
</span><del>-        switch (inst.opcode) {
</del><ins>+        switch (inst.kind.opcode) {
</ins><span class="cx">         case Move:
</span><span class="cx">             if (inst.args[0].isSomeImm()) {
</span><span class="cx">                 if (inst.args[1].isReg())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirFixPartialRegisterStallscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirFixPartialRegisterStalls.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirFixPartialRegisterStalls.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirFixPartialRegisterStalls.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> 
</span><span class="cx"> bool hasPartialXmmRegUpdate(const Inst&amp; inst)
</span><span class="cx"> {
</span><del>-    switch (inst.opcode) {
</del><ins>+    switch (inst.kind.opcode) {
</ins><span class="cx">     case ConvertDoubleToFloat:
</span><span class="cx">     case ConvertFloatToDouble:
</span><span class="cx">     case ConvertInt32ToDouble:
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx"> bool isDependencyBreaking(const Inst&amp; inst)
</span><span class="cx"> {
</span><span class="cx">     // &quot;xorps reg, reg&quot; is used by the frontend to remove the dependency on its argument.
</span><del>-    return inst.opcode == MoveZeroToDouble;
</del><ins>+    return inst.kind.opcode == MoveZeroToDouble;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // FIXME: find a good distance per architecture experimentally.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirGeneratecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -227,13 +227,13 @@
</span><span class="cx"> 
</span><span class="cx">         context.indexInBlock = block-&gt;size() - 1;
</span><span class="cx">         
</span><del>-        if (block-&gt;last().opcode == Jump
</del><ins>+        if (block-&gt;last().kind.opcode == Jump
</ins><span class="cx">             &amp;&amp; block-&gt;successorBlock(0) == code.findNextBlock(block))
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         addItem(block-&gt;last());
</span><span class="cx"> 
</span><del>-        if (isReturn(block-&gt;last().opcode)) {
</del><ins>+        if (isReturn(block-&gt;last().kind.opcode)) {
</ins><span class="cx">             // We currently don't represent the full prologue/epilogue in Air, so we need to
</span><span class="cx">             // have this override.
</span><span class="cx">             if (code.frameSize()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirHandleCalleeSavescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirHandleCalleeSaves.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirHandleCalleeSaves.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirHandleCalleeSaves.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -48,7 +48,7 @@
</span><span class="cx">                     usedCalleeSaves.set(tmp.reg());
</span><span class="cx">                 });
</span><span class="cx"> 
</span><del>-            if (inst.opcode == Patch)
</del><ins>+            if (inst.kind.opcode == Patch)
</ins><span class="cx">                 usedCalleeSaves.merge(inst.extraClobberedRegs());
</span><span class="cx">         }
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirInstcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirInst.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirInst.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirInst.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -47,7 +47,9 @@
</span><span class="cx"> 
</span><span class="cx"> unsigned Inst::jsHash() const
</span><span class="cx"> {
</span><del>-    unsigned result = static_cast&lt;unsigned&gt;(opcode);
</del><ins>+    // FIXME: This should do something for flags.
+    // https://bugs.webkit.org/show_bug.cgi?id=162751
+    unsigned result = static_cast&lt;unsigned&gt;(kind.opcode);
</ins><span class="cx">     
</span><span class="cx">     for (const Arg&amp; arg : args)
</span><span class="cx">         result += arg.jsHash();
</span><span class="lines">@@ -57,7 +59,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Inst::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(opcode, &quot; &quot;, listDump(args));
</del><ins>+    out.print(kind, &quot; &quot;, listDump(args));
</ins><span class="cx">     if (origin) {
</span><span class="cx">         if (args.size())
</span><span class="cx">             out.print(&quot;, &quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirInsth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirInst.h (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirInst.h        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirInst.h        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AirArg.h&quot;
</span><del>-#include &quot;AirOpcode.h&quot;
</del><ins>+#include &quot;AirKind.h&quot;
</ins><span class="cx"> #include &quot;CCallHelpers.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -50,39 +50,38 @@
</span><span class="cx"> 
</span><span class="cx">     Inst()
</span><span class="cx">         : origin(nullptr)
</span><del>-        , opcode(Nop)
</del><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Inst(Opcode opcode, Value* origin)
</del><ins>+    Inst(Kind kind, Value* origin)
</ins><span class="cx">         : origin(origin)
</span><del>-        , opcode(opcode)
</del><ins>+        , kind(kind)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><del>-    Inst(Opcode opcode, Value* origin, Arg arg, Arguments... arguments)
</del><ins>+    Inst(Kind kind, Value* origin, Arg arg, Arguments... arguments)
</ins><span class="cx">         : args{ arg, arguments... }
</span><span class="cx">         , origin(origin)
</span><del>-        , opcode(opcode)
</del><ins>+        , kind(kind)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Inst(Opcode opcode, Value* origin, const ArgList&amp; arguments)
</del><ins>+    Inst(Kind kind, Value* origin, const ArgList&amp; arguments)
</ins><span class="cx">         : args(arguments)
</span><span class="cx">         , origin(origin)
</span><del>-        , opcode(opcode)
</del><ins>+        , kind(kind)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Inst(Opcode opcode, Value* origin, ArgList&amp;&amp; arguments)
</del><ins>+    Inst(Kind kind, Value* origin, ArgList&amp;&amp; arguments)
</ins><span class="cx">         : args(WTFMove(arguments))
</span><span class="cx">         , origin(origin)
</span><del>-        , opcode(opcode)
</del><ins>+        , kind(kind)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    explicit operator bool() const { return origin || opcode != Nop || args.size(); }
</del><ins>+    explicit operator bool() const { return origin || kind || args.size(); }
</ins><span class="cx"> 
</span><span class="cx">     void append() { }
</span><span class="cx">     
</span><span class="lines">@@ -200,7 +199,7 @@
</span><span class="cx"> 
</span><span class="cx">     ArgList args;
</span><span class="cx">     Value* origin; // The B3::Value that this originated from.
</span><del>-    Opcode opcode;
</del><ins>+    Kind kind;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } } // namespace JSC::B3::Air
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirInstInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -46,13 +46,13 @@
</span><span class="cx"> 
</span><span class="cx"> inline const RegisterSet&amp; Inst::extraClobberedRegs()
</span><span class="cx"> {
</span><del>-    ASSERT(opcode == Patch);
</del><ins>+    ASSERT(kind.opcode == Patch);
</ins><span class="cx">     return args[0].special()-&gt;extraClobberedRegs(*this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline const RegisterSet&amp; Inst::extraEarlyClobberedRegs()
</span><span class="cx"> {
</span><del>-    ASSERT(opcode == Patch);
</del><ins>+    ASSERT(kind.opcode == Patch);
</ins><span class="cx">     return args[0].special()-&gt;extraEarlyClobberedRegs(*this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -89,12 +89,12 @@
</span><span class="cx">         functor(Thing(reg), regDefRole, type, Arg::conservativeWidth(type));
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    if (prevInst &amp;&amp; prevInst-&gt;opcode == Patch) {
</del><ins>+    if (prevInst &amp;&amp; prevInst-&gt;kind.opcode == Patch) {
</ins><span class="cx">         regDefRole = Arg::Def;
</span><span class="cx">         prevInst-&gt;extraClobberedRegs().forEach(reportReg);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (nextInst &amp;&amp; nextInst-&gt;opcode == Patch) {
</del><ins>+    if (nextInst &amp;&amp; nextInst-&gt;kind.opcode == Patch) {
</ins><span class="cx">         regDefRole = Arg::EarlyDef;
</span><span class="cx">         nextInst-&gt;extraEarlyClobberedRegs().forEach(reportReg);
</span><span class="cx">     }
</span><span class="lines">@@ -102,7 +102,7 @@
</span><span class="cx"> 
</span><span class="cx"> inline void Inst::reportUsedRegisters(const RegisterSet&amp; usedRegisters)
</span><span class="cx"> {
</span><del>-    ASSERT(opcode == Patch);
</del><ins>+    ASSERT(kind.opcode == Patch);
</ins><span class="cx">     args[0].special()-&gt;reportUsedRegisters(*this, usedRegisters);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">     if (!isX86())
</span><span class="cx">         return Nullopt;
</span><span class="cx"> 
</span><del>-    switch (opcode) {
</del><ins>+    switch (kind.opcode) {
</ins><span class="cx">     case Add32:
</span><span class="cx">     case Add64:
</span><span class="cx">     case And32:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirIteratedRegisterCoalescingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -1040,7 +1040,7 @@
</span><span class="cx">     {
</span><span class="cx">         switch (type) {
</span><span class="cx">         case Arg::GP:
</span><del>-            switch (inst.opcode) {
</del><ins>+            switch (inst.kind.opcode) {
</ins><span class="cx">             case Move:
</span><span class="cx">             case Move32:
</span><span class="cx">                 break;
</span><span class="lines">@@ -1049,7 +1049,7 @@
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="cx">         case Arg::FP:
</span><del>-            switch (inst.opcode) {
</del><ins>+            switch (inst.kind.opcode) {
</ins><span class="cx">             case MoveFloat:
</span><span class="cx">             case MoveDouble:
</span><span class="cx">                 break;
</span><span class="lines">@@ -1074,7 +1074,7 @@
</span><span class="cx">         // Note that the input property requires an analysis over ZDef's, so it's only valid so long
</span><span class="cx">         // as the input gets a register. We don't know if the input gets a register, but we do know
</span><span class="cx">         // that if it doesn't get a register then we will still emit this Move32.
</span><del>-        if (inst.opcode == Move32) {
</del><ins>+        if (inst.kind.opcode == Move32) {
</ins><span class="cx">             if (!tmpWidth)
</span><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="lines">@@ -1382,11 +1382,11 @@
</span><span class="cx">                 // equivalent if the destination's high bits are not observable or if the source's high
</span><span class="cx">                 // bits are all zero. Note that we don't have the opposite optimization for other
</span><span class="cx">                 // architectures, which may prefer Move over Move32, because Move is canonical already.
</span><del>-                if (type == Arg::GP &amp;&amp; inst.opcode == Move
</del><ins>+                if (type == Arg::GP &amp;&amp; inst.kind.opcode == Move
</ins><span class="cx">                     &amp;&amp; inst.args[0].isTmp() &amp;&amp; inst.args[1].isTmp()) {
</span><span class="cx">                     if (m_tmpWidth.useWidth(inst.args[1].tmp()) &lt;= Arg::Width32
</span><span class="cx">                         || m_tmpWidth.defWidth(inst.args[0].tmp()) &lt;= Arg::Width32)
</span><del>-                        inst.opcode = Move32;
</del><ins>+                        inst.kind.opcode = Move32;
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 inst.forEachTmpFast([&amp;] (Tmp&amp; tmp) {
</span><span class="lines">@@ -1453,7 +1453,7 @@
</span><span class="cx">                 // Move is the canonical way to move data between GPRs.
</span><span class="cx">                 bool canUseMove32IfDidSpill = false;
</span><span class="cx">                 bool didSpill = false;
</span><del>-                if (type == Arg::GP &amp;&amp; inst.opcode == Move) {
</del><ins>+                if (type == Arg::GP &amp;&amp; inst.kind.opcode == Move) {
</ins><span class="cx">                     if ((inst.args[0].isTmp() &amp;&amp; m_tmpWidth.width(inst.args[0].tmp()) &lt;= Arg::Width32)
</span><span class="cx">                         || (inst.args[1].isTmp() &amp;&amp; m_tmpWidth.width(inst.args[1].tmp()) &lt;= Arg::Width32))
</span><span class="cx">                         canUseMove32IfDidSpill = true;
</span><span class="lines">@@ -1488,7 +1488,7 @@
</span><span class="cx">                         Arg::Width spillWidth = m_tmpWidth.requiredWidth(arg.tmp());
</span><span class="cx">                         if (Arg::isAnyDef(role) &amp;&amp; width &lt; spillWidth)
</span><span class="cx">                             return;
</span><del>-                        ASSERT(inst.opcode == Move || !(Arg::isAnyUse(role) &amp;&amp; width &gt; spillWidth));
</del><ins>+                        ASSERT(inst.kind.opcode == Move || !(Arg::isAnyUse(role) &amp;&amp; width &gt; spillWidth));
</ins><span class="cx">                         
</span><span class="cx">                         if (spillWidth != Arg::Width32)
</span><span class="cx">                             canUseMove32IfDidSpill = false;
</span><span class="lines">@@ -1500,7 +1500,7 @@
</span><span class="cx">                     });
</span><span class="cx"> 
</span><span class="cx">                 if (didSpill &amp;&amp; canUseMove32IfDidSpill)
</span><del>-                    inst.opcode = Move32;
</del><ins>+                    inst.kind.opcode = Move32;
</ins><span class="cx"> 
</span><span class="cx">                 // For every other case, add Load/Store as needed.
</span><span class="cx">                 inst.forEachTmp([&amp;] (Tmp&amp; tmp, Arg::Role role, Arg::Type argType, Arg::Width) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirKindcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/air/AirKind.cpp (0 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirKind.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/air/AirKind.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 &quot;config.h&quot;
+#include &quot;AirKind.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &lt;wtf/CommaPrinter.h&gt;
+
+namespace JSC { namespace B3 { namespace Air {
+
+void Kind::dump(PrintStream&amp; out) const
+{
+    out.print(opcode);
+    
+    CommaPrinter comma(&quot;, &quot;, &quot;&lt;&quot;);
+    if (traps)
+        out.print(comma, &quot;Traps&quot;);
+    if (comma.didPrint())
+        out.print(&quot;&gt;&quot;);
+}
+
+} } } // namespace JSC::B3::Air
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirKindh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/air/AirKind.h (0 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirKind.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/air/AirKind.h        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+/*
+ * Copyright (C) 2016 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. 
+ */
+
+#ifndef AirKind_h
+#define AirKind_h
+
+#if ENABLE(B3_JIT)
+
+#include &quot;AirOpcode.h&quot;
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC { namespace B3 { namespace Air {
+
+// Air opcodes are always carried around with some flags. These flags are understood as having no
+// meaning if they are set for an opcode to which they do not apply. This makes sense, since Air
+// is a complex instruction set and most of these flags can apply to basically any opcode. In
+// fact, it's recommended to only represent something as a flag if you believe that it is largely
+// opcode-agnostic.
+
+struct Kind {
+    Kind(Opcode opcode)
+        : opcode(opcode)
+        , traps(false)
+    {
+    }
+    
+    Kind()
+        : Kind(Nop)
+    {
+    }
+    
+    bool operator==(const Kind&amp; other) const
+    {
+        return opcode == other.opcode
+            &amp;&amp; traps == other.traps;
+    }
+    
+    bool operator!=(const Kind&amp; other) const
+    {
+        return !(*this == other);
+    }
+    
+    unsigned hash() const
+    {
+        return static_cast&lt;unsigned&gt;(opcode) + (static_cast&lt;unsigned&gt;(traps) &lt;&lt; 16);
+    }
+    
+    explicit operator bool() const
+    {
+        return *this != Kind();
+    }
+    
+    void dump(PrintStream&amp;) const;
+    
+    Opcode opcode;
+    
+    // This is an opcode-agnostic flag that indicates that we expect that this instruction will
+    // trap. This causes the compiler to assume that this side-exits and therefore has non-control
+    // non-arg effects. This also causes the compiler to tell you about all of these instructions.
+    // Note that this is just one of several ways of supporting trapping in Air, and it's the less
+    // precise variant because it's origin-based. This means that if an instruction was fused out
+    // of B3 values that had different origins, then the origin at which you'll appear to trap
+    // will be somewhat random. The upside of this approach is that it imposes by far the least
+    // overhead on the compiler.
+    // FIXME: Make this completely work.
+    // https://bugs.webkit.org/show_bug.cgi?id=162689
+    bool traps : 1;
+};
+
+} } } // namespace JSC::B3::Air
+
+#endif // ENABLE(B3_JIT)
+
+#endif // AirKind_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -68,7 +68,7 @@
</span><span class="cx">             
</span><span class="cx">             RegisterSet set;
</span><span class="cx"> 
</span><del>-            bool isRelevant = inst.opcode == Shuffle || inst.opcode == ColdCCall;
</del><ins>+            bool isRelevant = inst.kind.opcode == Shuffle || inst.kind.opcode == ColdCCall;
</ins><span class="cx">             
</span><span class="cx">             if (isRelevant) {
</span><span class="cx">                 for (Reg reg : localCalc.live())
</span><span class="lines">@@ -110,7 +110,7 @@
</span><span class="cx">         for (unsigned instIndex = 0; instIndex &lt; block-&gt;size(); ++instIndex) {
</span><span class="cx">             Inst&amp; inst = block-&gt;at(instIndex);
</span><span class="cx"> 
</span><del>-            switch (inst.opcode) {
</del><ins>+            switch (inst.kind.opcode) {
</ins><span class="cx">             case Shuffle: {
</span><span class="cx">                 RegisterSet set = usedRegisters.get(&amp;inst);
</span><span class="cx">                 Vector&lt;ShufflePair&gt; pairs;
</span><span class="lines">@@ -141,6 +141,7 @@
</span><span class="cx"> 
</span><span class="cx">             case ColdCCall: {
</span><span class="cx">                 CCallValue* value = inst.origin-&gt;as&lt;CCallValue&gt;();
</span><ins>+                Kind oldKind = inst.kind;
</ins><span class="cx"> 
</span><span class="cx">                 RegisterSet liveRegs = usedRegisters.get(&amp;inst);
</span><span class="cx">                 RegisterSet regsToSave = liveRegs;
</span><span class="lines">@@ -195,6 +196,8 @@
</span><span class="cx">                     instIndex, emitShuffle(pairs, gpScratch, fpScratch, inst.origin));
</span><span class="cx"> 
</span><span class="cx">                 inst = buildCCall(code, inst.origin, destinations);
</span><ins>+                if (oldKind.traps)
+                    inst.kind.traps = true;
</ins><span class="cx"> 
</span><span class="cx">                 // Now we need to emit code to restore registers.
</span><span class="cx">                 pairs.resize(0);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerEntrySwitchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirLowerEntrySwitch.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerEntrySwitch.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerEntrySwitch.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx">     // Figure out the set of blocks that should be duplicated.
</span><span class="cx">     BlockWorklist worklist;
</span><span class="cx">     for (BasicBlock* block : code) {
</span><del>-        if (block-&gt;last().opcode == EntrySwitch)
</del><ins>+        if (block-&gt;last().kind.opcode == EntrySwitch)
</ins><span class="cx">             worklist.push(block);
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx">     
</span><span class="cx">     Vector&lt;FrequencyClass&gt; entrypointFrequencies(code.proc().numEntrypoints(), FrequencyClass::Rare);
</span><span class="cx">     for (BasicBlock* block : code) {
</span><del>-        if (block-&gt;last().opcode != EntrySwitch)
</del><ins>+        if (block-&gt;last().kind.opcode != EntrySwitch)
</ins><span class="cx">             continue;
</span><span class="cx">         for (unsigned entrypointIndex = code.proc().numEntrypoints(); entrypointIndex--;) {
</span><span class="cx">             entrypointFrequencies[entrypointIndex] = maxFrequency(
</span><span class="lines">@@ -71,10 +71,10 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     auto fixEntrySwitch = [&amp;] (BasicBlock* block, unsigned entrypointIndex) {
</span><del>-        if (block-&gt;last().opcode != EntrySwitch)
</del><ins>+        if (block-&gt;last().kind.opcode != EntrySwitch)
</ins><span class="cx">             return;
</span><span class="cx">         FrequentedBlock target = block-&gt;successor(entrypointIndex);
</span><del>-        block-&gt;last().opcode = Jump;
</del><ins>+        block-&gt;last().kind.opcode = Jump;
</ins><span class="cx">         block-&gt;successors().resize(1);
</span><span class="cx">         block-&gt;successor(0) = target;
</span><span class="cx">     };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerMacroscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -47,9 +47,10 @@
</span><span class="cx">         for (unsigned instIndex = 0; instIndex &lt; block-&gt;size(); ++instIndex) {
</span><span class="cx">             Inst&amp; inst = block-&gt;at(instIndex);
</span><span class="cx"> 
</span><del>-            switch (inst.opcode) {
</del><ins>+            switch (inst.kind.opcode) {
</ins><span class="cx">             case CCall: {
</span><span class="cx">                 CCallValue* value = inst.origin-&gt;as&lt;CCallValue&gt;();
</span><ins>+                Kind oldKind = inst.kind;
</ins><span class="cx"> 
</span><span class="cx">                 Vector&lt;Arg&gt; destinations = computeCCallingConvention(code, value);
</span><span class="cx"> 
</span><span class="lines">@@ -70,6 +71,8 @@
</span><span class="cx">                 Arg resultDst = value-&gt;type() == Void ? Arg() : inst.args[1];
</span><span class="cx">                 
</span><span class="cx">                 inst = buildCCall(code, inst.origin, destinations);
</span><ins>+                if (oldKind.traps)
+                    inst.kind.traps = true;
</ins><span class="cx"> 
</span><span class="cx">                 Tmp result = cCallResult(value-&gt;type());
</span><span class="cx">                 switch (value-&gt;type()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirOptimizeBlockOrdercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirOptimizeBlockOrder.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirOptimizeBlockOrder.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirOptimizeBlockOrder.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -160,7 +160,7 @@
</span><span class="cx">         // optimization.  You'll probably realize that as soon as you look at the disassembly, and it
</span><span class="cx">         // certainly won't cause any correctness issues.
</span><span class="cx">         
</span><del>-        switch (branch.opcode) {
</del><ins>+        switch (branch.kind.opcode) {
</ins><span class="cx">         case Branch8:
</span><span class="cx">         case Branch32:
</span><span class="cx">         case Branch64:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirReportUsedRegisterscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirReportUsedRegisters.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -73,7 +73,7 @@
</span><span class="cx">                     inst = Inst();
</span><span class="cx">             }
</span><span class="cx">             
</span><del>-            if (inst.opcode == Patch) {
</del><ins>+            if (inst.kind.opcode == Patch) {
</ins><span class="cx">                 RegisterSet registerSet;
</span><span class="cx">                 for (Reg reg : localCalc.live())
</span><span class="cx">                     registerSet.set(reg);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirSimplifyCFGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -78,7 +78,7 @@
</span><span class="cx">             for (BasicBlock*&amp; successor : block-&gt;successorBlocks()) {
</span><span class="cx">                 if (successor != block
</span><span class="cx">                     &amp;&amp; successor-&gt;size() == 1
</span><del>-                    &amp;&amp; successor-&gt;last().opcode == Jump) {
</del><ins>+                    &amp;&amp; successor-&gt;last().kind.opcode == Jump) {
</ins><span class="cx">                     BasicBlock* newSuccessor = successor-&gt;successorBlock(0);
</span><span class="cx">                     if (newSuccessor != successor) {
</span><span class="cx">                         if (verbose) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirTmpWidthcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirTmpWidth.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirTmpWidth.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirTmpWidth.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx">     Vector&lt;Inst*&gt; moves;
</span><span class="cx">     for (BasicBlock* block : code) {
</span><span class="cx">         for (Inst&amp; inst : *block) {
</span><del>-            if (inst.opcode == Move &amp;&amp; inst.args[1].isTmp()) {
</del><ins>+            if (inst.kind.opcode == Move &amp;&amp; inst.args[1].isTmp()) {
</ins><span class="cx">                 if (inst.args[0].isTmp()) {
</span><span class="cx">                     // Make sure that both sides of the Move have a width already initialized. The
</span><span class="cx">                     // fixpoint below assumes that it never has to add things to the HashMap.
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx">     while (changed) {
</span><span class="cx">         changed = false;
</span><span class="cx">         for (Inst* move : moves) {
</span><del>-            ASSERT(move-&gt;opcode == Move);
</del><ins>+            ASSERT(move-&gt;kind.opcode == Move);
</ins><span class="cx">             ASSERT(move-&gt;args[0].isTmp());
</span><span class="cx">             ASSERT(move-&gt;args[1].isTmp());
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirUseCountsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -88,7 +88,7 @@
</span><span class="cx">                             counts.numDefs += frequency;
</span><span class="cx">                     });
</span><span class="cx"> 
</span><del>-                if ((inst.opcode == Move || inst.opcode == Move32)
</del><ins>+                if ((inst.kind.opcode == Move || inst.kind.opcode == Move32)
</ins><span class="cx">                     &amp;&amp; inst.args[0].isSomeImm()
</span><span class="cx">                     &amp;&amp; inst.args[1].is&lt;Thing&gt;())
</span><span class="cx">                     m_counts.add(inst.args[1].as&lt;Thing&gt;(), Counts()).iterator-&gt;value.numConstDefs++;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirValidatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirValidate.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirValidate.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/AirValidate.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -95,10 +95,15 @@
</span><span class="cx">                         VALIDATE(&amp;arg &lt;= &amp;inst.args.last(), (&quot;At &quot;, arg, &quot; in &quot;, inst, &quot; in &quot;, *block));
</span><span class="cx">                     });
</span><span class="cx">                 
</span><del>-                switch (inst.opcode) {
</del><ins>+                switch (inst.kind.opcode) {
</ins><span class="cx">                 case EntrySwitch:
</span><span class="cx">                     VALIDATE(block-&gt;numSuccessors() == m_code.proc().numEntrypoints(), (&quot;At &quot;, inst, &quot; in &quot;, *block));
</span><span class="cx">                     break;
</span><ins>+                case Shuffle:
+                    // We can't handle trapping shuffles because of how we lower them. That could
+                    // be fixed though.
+                    VALIDATE(!inst.kind.traps, (&quot;At &quot;, inst, &quot; in &quot;, *block));
+                    break;
</ins><span class="cx">                 default:
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airopcode_generatorrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/opcode_generator.rb (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/opcode_generator.rb        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/air/opcode_generator.rb        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -545,7 +545,7 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> def matchInstOverload(outp, speed, inst)
</span><del>-    outp.puts &quot;switch (#{inst}-&gt;opcode) {&quot;
</del><ins>+    outp.puts &quot;switch (#{inst}-&gt;kind.opcode) {&quot;
</ins><span class="cx">     $opcodes.values.each {
</span><span class="cx">         | opcode |
</span><span class="cx">         outp.puts &quot;case #{opcode.name}:&quot;
</span><span class="lines">@@ -836,7 +836,7 @@
</span><span class="cx"> 
</span><span class="cx">     outp.puts &quot;bool Inst::admitsStack(unsigned argIndex)&quot;
</span><span class="cx">     outp.puts &quot;{&quot;
</span><del>-    outp.puts &quot;switch (opcode) {&quot;
</del><ins>+    outp.puts &quot;switch (kind.opcode) {&quot;
</ins><span class="cx">     $opcodes.values.each {
</span><span class="cx">         | opcode |
</span><span class="cx">         outp.puts &quot;case #{opcode.name}:&quot;
</span><span class="lines">@@ -978,7 +978,7 @@
</span><span class="cx"> 
</span><span class="cx">     outp.puts &quot;bool Inst::isTerminal()&quot;
</span><span class="cx">     outp.puts &quot;{&quot;
</span><del>-    outp.puts &quot;switch (opcode) {&quot;
</del><ins>+    outp.puts &quot;switch (kind.opcode) {&quot;
</ins><span class="cx">     foundTrue = false
</span><span class="cx">     $opcodes.values.each {
</span><span class="cx">         | opcode |
</span><span class="lines">@@ -1004,7 +1004,9 @@
</span><span class="cx">     
</span><span class="cx">     outp.puts &quot;bool Inst::hasNonArgNonControlEffects()&quot;
</span><span class="cx">     outp.puts &quot;{&quot;
</span><del>-    outp.puts &quot;switch (opcode) {&quot;
</del><ins>+    outp.puts &quot;if (kind.traps)&quot;
+    outp.puts &quot;return true;&quot;
+    outp.puts &quot;switch (kind.opcode) {&quot;
</ins><span class="cx">     foundTrue = false
</span><span class="cx">     $opcodes.values.each {
</span><span class="cx">         | opcode |
</span><span class="lines">@@ -1030,7 +1032,9 @@
</span><span class="cx">     
</span><span class="cx">     outp.puts &quot;bool Inst::hasNonArgEffects()&quot;
</span><span class="cx">     outp.puts &quot;{&quot;
</span><del>-    outp.puts &quot;switch (opcode) {&quot;
</del><ins>+    outp.puts &quot;if (kind.traps)&quot;
+    outp.puts &quot;return true;&quot;
+    outp.puts &quot;switch (kind.opcode) {&quot;
</ins><span class="cx">     foundTrue = false
</span><span class="cx">     $opcodes.values.each {
</span><span class="cx">         | opcode |
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -2217,7 +2217,7 @@
</span><span class="cx">     auto block = proc.code()[0];
</span><span class="cx">     unsigned numberOfSubInstructions = 0;
</span><span class="cx">     for (auto instruction : *block) {
</span><del>-        if (instruction.opcode == expectedOpcode) {
</del><ins>+        if (instruction.kind.opcode == expectedOpcode) {
</ins><span class="cx">             CHECK_EQ(instruction.args.size(), 3ul);
</span><span class="cx">             CHECK_EQ(instruction.args[0].kind(), Air::Arg::Tmp);
</span><span class="cx">             CHECK_EQ(instruction.args[1].kind(), Air::Arg::Tmp);
</span><span class="lines">@@ -12972,7 +12972,7 @@
</span><span class="cx"> 
</span><span class="cx">     // The first basic block must end in a BranchTest64(resCond, tmp, bitImm).
</span><span class="cx">     Air::Inst terminal = proc.code()[0]-&gt;last();
</span><del>-    CHECK_EQ(terminal.opcode, expectedOpcode);
</del><ins>+    CHECK_EQ(terminal.kind.opcode, expectedOpcode);
</ins><span class="cx">     CHECK_EQ(terminal.args[0].kind(), Air::Arg::ResCond);
</span><span class="cx">     CHECK_EQ(terminal.args[1].kind(), firstKind);
</span><span class="cx">     CHECK(terminal.args[2].kind() == Air::Arg::BitImm || terminal.args[2].kind() == Air::Arg::BitImm64);
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/WTF/ChangeLog        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-09-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Air should have a way of expressing additional instruction flags
+        https://bugs.webkit.org/show_bug.cgi?id=162699
+
+        Reviewed by Mark Lam.
+
+        * wtf/CommaPrinter.h:
+        (WTF::CommaPrinter::CommaPrinter):
+        (WTF::CommaPrinter::dump):
+        (WTF::CommaPrinter::didPrint):
+
</ins><span class="cx"> 2016-09-30  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add a way to go from a RefPtr&lt;T&gt; to Ref&lt;const T&gt;
</span></span></pre></div>
<a id="trunkSourceWTFwtfCommaPrinterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/CommaPrinter.h (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/CommaPrinter.h        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Source/WTF/wtf/CommaPrinter.h        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2016 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">@@ -32,16 +32,18 @@
</span><span class="cx"> 
</span><span class="cx"> class CommaPrinter {
</span><span class="cx"> public:
</span><del>-    CommaPrinter(const char* comma = &quot;, &quot;)
</del><ins>+    CommaPrinter(const char* comma = &quot;, &quot;, const char* start = &quot;&quot;)
</ins><span class="cx">         : m_comma(comma)
</span><del>-        , m_isFirst(true)
</del><ins>+        , m_start(start)
+        , m_didPrint(false)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void dump(PrintStream&amp; out) const
</span><span class="cx">     {
</span><del>-        if (m_isFirst) {
-            m_isFirst = false;
</del><ins>+        if (!m_didPrint) {
+            out.print(m_start);
+            m_didPrint = true;
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="lines">@@ -48,9 +50,12 @@
</span><span class="cx">         out.print(m_comma);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool didPrint() const { return m_didPrint; }
+    
</ins><span class="cx"> private:
</span><span class="cx">     const char* m_comma;
</span><del>-    mutable bool m_isFirst;
</del><ins>+    const char* m_start;
+    mutable bool m_didPrint;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/ChangeLog (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/ChangeLog        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Websites/webkit.org/ChangeLog        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2016-09-30  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Air should have a way of expressing additional instruction flags
+        https://bugs.webkit.org/show_bug.cgi?id=162699
+
+        Reviewed by Mark Lam.
+
+        * docs/b3/assembly-intermediate-representation.html:
+
</ins><span class="cx"> 2016-09-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         B3 opcodes should leave room for flags
</span></span></pre></div>
<a id="trunkWebsiteswebkitorgdocsb3assemblyintermediaterepresentationhtml"></a>
<div class="modfile"><h4>Modified: trunk/Websites/webkit.org/docs/b3/assembly-intermediate-representation.html (206639 => 206640)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/webkit.org/docs/b3/assembly-intermediate-representation.html        2016-09-30 16:52:47 UTC (rev 206639)
+++ trunk/Websites/webkit.org/docs/b3/assembly-intermediate-representation.html        2016-09-30 16:59:24 UTC (rev 206640)
</span><span class="lines">@@ -28,10 +28,11 @@
</span><span class="cx">       &lt;a href=&quot;http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/b3/air/AirInst.h&quot;&gt;&lt;code&gt;Inst&lt;/code&gt;&lt;/a&gt;s.
</span><span class="cx">       Air has an explicit control flow graph: each basic block has predecessor and successor blocks.
</span><span class="cx">       Execution always begins at the first basic block (&lt;code&gt;code[0]&lt;/code&gt;). The &lt;code&gt;Inst&lt;/code&gt;s
</span><del>-      in each block are executed in order. Each &lt;code&gt;Inst&lt;/code&gt; has an opcode, an array of
-      arguments
</del><ins>+      in each block are executed in order. Each &lt;code&gt;Inst&lt;/code&gt; has an opcode, some flags, an
+      array of arguments
</ins><span class="cx">       (&lt;a href=&quot;http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/b3/air/AirArg.h&quot;&gt;&lt;code&gt;Arg&lt;/code&gt;&lt;/a&gt;s),
</span><del>-      and an origin. The origin is simply a B3 IR
</del><ins>+      and an origin. The opcode and flags are wrapped in a &lt;code&gt;Kind&lt;/code&gt;, to make it
+      convenient to carry them around together. The origin is simply a B3 IR
</ins><span class="cx">       &lt;a href=&quot;http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/b3/B3Value.h&quot;&gt;&lt;code&gt;Value&lt;/code&gt;&lt;/a&gt;.
</span><span class="cx">       Some opcodes use the origin for additional meta-data. This works because Air code always
</span><span class="cx">       coexists with the B3 procedure from which it was generated.&lt;/p&gt;
</span><span class="lines">@@ -251,6 +252,32 @@
</span><span class="cx">       &lt;li&gt;&lt;code&gt;func(%rcx, UseZDef, GP, Width32)&lt;/code&gt;&lt;/li&gt;
</span><span class="cx">     &lt;/ol&gt;
</span><span class="cx">     
</span><ins>+    &lt;p&gt;It's important to remember that Air's summaries of what instructions do to arguments are
+      not meant to be exhaustive. For example, if an instruction claims to use an address, this
+      tells you that the instruction will perform a load but it tells you nothing about how that
+      load will be performed. This means that unless you know exactly what it means to use/def an
+      argument, you cannot perform this transformation:&lt;/p&gt;
+    
+    &lt;ul&gt;
+      &lt;li&gt;Before:
+        &lt;pre&gt;&lt;code&gt;Foo32 (%rax)&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
+      &lt;li&gt;After:
+        &lt;pre&gt;&lt;code&gt;Move32 (%rax), %tmp
+Foo32 %tmp&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
+    &lt;/ul&gt;
+    
+    &lt;p&gt;Even if you know that Foo32 only uses its argument, you cannot do this because Move32 may
+      not load from the address using exactly the same kind of load that Foo32 would have done.
+      Memory accesses have many dimensions of options: alignment semantics (if you're lucky then
+      misaligned accesses run fast but sometimes they ignore low bits, trap if unaligned, or run
+      super slow when unaligned, and this behavior may depend on the opcode), temporality and
+      memory ordering, determinism of trapping, etc. Just seeing that an instruction uses an
+      address does not tell you what kind of load will happen, and currently Air does not have the
+      ability to answer such questions. Fortunately, Air does not have much need to move memory
+      accesses out of instructions. Uses and defs of temporaries, registers, immediates, and spill
+      slots don't have these caveats and so those arguments can be moved from one instruction to
+      another without worries.&lt;/p&gt;
+    
</ins><span class="cx">     &lt;p&gt;Air's introspection of &lt;code&gt;Inst&lt;/code&gt;s tends to be quite fast thanks to the use of template
</span><span class="cx">       specialization and C++ lambdas. The &lt;code&gt;forEachArg()&lt;/code&gt; template method uses an efficient
</span><span class="cx">       arrangement of switch statements to determine the opcode and overload. If &lt;code&gt;func&lt;/code&gt; is
</span></span></pre>
</div>
</div>

</body>
</html>