<!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>[195133] trunk/Source/JavaScriptCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/195133">195133</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-01-15 09:07:50 -0800 (Fri, 15 Jan 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/195084">r195084</a>.
https://bugs.webkit.org/show_bug.cgi?id=153132
Broke Production build (Requested by ap on #webkit).
Reverted changeset:
"Air needs a Shuffle instruction"
https://bugs.webkit.org/show_bug.cgi?id=152952
http://trac.webkit.org/changeset/195084</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="#trunkSourceJavaScriptCoreassemblerAbstractMacroAssemblerh">trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerX86Commonh">trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerX86_64h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerX86Assemblerh">trunk/Source/JavaScriptCore/assembler/X86Assembler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CCallValueh">trunk/Source/JavaScriptCore/b3/B3CCallValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Compilationcpp">trunk/Source/JavaScriptCore/b3/B3Compilation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Compilationh">trunk/Source/JavaScriptCore/b3/B3Compilation.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3OpaqueByproductsh">trunk/Source/JavaScriptCore/b3/B3OpaqueByproducts.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackmapSpecialcpp">trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirArgcpp">trunk/Source/JavaScriptCore/b3/air/AirArg.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirArgh">trunk/Source/JavaScriptCore/b3/air/AirArg.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirBasicBlockh">trunk/Source/JavaScriptCore/b3/air/AirBasicBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCodeh">trunk/Source/JavaScriptCore/b3/air/AirCode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCustomh">trunk/Source/JavaScriptCore/b3/air/AirCustom.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirGeneratecpp">trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirGenerateh">trunk/Source/JavaScriptCore/b3/air/AirGenerate.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirInsertionSetcpp">trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirInsertionSeth">trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirInsth">trunk/Source/JavaScriptCore/b3/air/AirInst.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirOpcodeopcodes">trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirRegisterPriorityh">trunk/Source/JavaScriptCore/b3/air/AirRegisterPriority.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitcpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitHandlecpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitHandleh">trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.h</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCCallingConventioncpp">trunk/Source/JavaScriptCore/b3/air/AirCCallingConvention.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCCallingConventionh">trunk/Source/JavaScriptCore/b3/air/AirCCallingConvention.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCustomcpp">trunk/Source/JavaScriptCore/b3/air/AirCustom.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirEmitShufflecpp">trunk/Source/JavaScriptCore/b3/air/AirEmitShuffle.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirEmitShuffleh">trunk/Source/JavaScriptCore/b3/air/AirEmitShuffle.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloccpp">trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloch">trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerMacroscpp">trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirLowerMacrosh">trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airtestaircpp">trunk/Source/JavaScriptCore/b3/air/testair.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -73,11 +73,8 @@
</span><span class="cx"> b3/air/AirArg.cpp
</span><span class="cx"> b3/air/AirBasicBlock.cpp
</span><span class="cx"> b3/air/AirCCallSpecial.cpp
</span><del>- b3/air/AirCCallingConvention.cpp
</del><span class="cx"> b3/air/AirCode.cpp
</span><del>- b3/air/AirCustom.cpp
</del><span class="cx"> b3/air/AirEliminateDeadCode.cpp
</span><del>- b3/air/AirEmitShuffle.cpp
</del><span class="cx"> b3/air/AirFixPartialRegisterStalls.cpp
</span><span class="cx"> b3/air/AirGenerate.cpp
</span><span class="cx"> b3/air/AirGenerated.cpp
</span><span class="lines">@@ -85,8 +82,6 @@
</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><del>- b3/air/AirLowerAfterRegAlloc.cpp
- b3/air/AirLowerMacros.cpp
</del><span class="cx"> b3/air/AirOptimizeBlockOrder.cpp
</span><span class="cx"> b3/air/AirPhaseScope.cpp
</span><span class="cx"> b3/air/AirRegisterPriority.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-01-15 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r195084.
+ https://bugs.webkit.org/show_bug.cgi?id=153132
+
+ Broke Production build (Requested by ap on #webkit).
+
+ Reverted changeset:
+
+ "Air needs a Shuffle instruction"
+ https://bugs.webkit.org/show_bug.cgi?id=152952
+ http://trac.webkit.org/changeset/195084
+
</ins><span class="cx"> 2016-01-15 Julien Brianceau <jbriance@cisco.com>
</span><span class="cx">
</span><span class="cx"> [mips] Add countLeadingZeros32 implementation in macro assembler
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -25,7 +25,6 @@
</span><span class="cx">                         buildPhases = (
</span><span class="cx">                         );
</span><span class="cx">                         dependencies = (
</span><del>-                                0F6183471C45F67A0072450B /* PBXTargetDependency */,
</del><span class="cx">                                 0F93275D1C20BF3A00CF6564 /* PBXTargetDependency */,
</span><span class="cx">                                 0FEC85B11BDB5D8F0080FF74 /* PBXTargetDependency */,
</span><span class="cx">                                 5D6B2A4F152B9E23005231DE /* PBXTargetDependency */,
</span><span class="lines">@@ -401,21 +400,6 @@
</span><span class="cx">                 0F5EF91E16878F7A003E5C25 /* JITThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5EF91B16878F78003E5C25 /* JITThunks.cpp */; };
</span><span class="cx">                 0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5EF91C16878F78003E5C25 /* JITThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                0F6183291C45BF070072450B /* AirCCallingConvention.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183201C45BF070072450B /* AirCCallingConvention.cpp */; };
-                0F61832A1C45BF070072450B /* AirCCallingConvention.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183211C45BF070072450B /* AirCCallingConvention.h */; };
-                0F61832B1C45BF070072450B /* AirCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183221C45BF070072450B /* AirCustom.cpp */; };
-                0F61832C1C45BF070072450B /* AirEmitShuffle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183231C45BF070072450B /* AirEmitShuffle.cpp */; };
-                0F61832D1C45BF070072450B /* AirEmitShuffle.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183241C45BF070072450B /* AirEmitShuffle.h */; };
-                0F61832E1C45BF070072450B /* AirLowerAfterRegAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183251C45BF070072450B /* AirLowerAfterRegAlloc.cpp */; };
-                0F61832F1C45BF070072450B /* AirLowerAfterRegAlloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183261C45BF070072450B /* AirLowerAfterRegAlloc.h */; };
-                0F6183301C45BF070072450B /* AirLowerMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183271C45BF070072450B /* AirLowerMacros.cpp */; };
-                0F6183311C45BF070072450B /* AirLowerMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183281C45BF070072450B /* AirLowerMacros.h */; };
-                0F6183331C45F35C0072450B /* AirOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183321C45F35C0072450B /* AirOpcode.h */; };
-                0F6183361C45F3B60072450B /* AirOpcodeGenerated.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183341C45F3B60072450B /* AirOpcodeGenerated.h */; };
-                0F6183371C45F3B60072450B /* AirOpcodeUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6183351C45F3B60072450B /* AirOpcodeUtils.h */; };
-                0F61833C1C45F62A0072450B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
-                0F61833D1C45F62A0072450B /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
-                0F6183451C45F6600072450B /* testair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6183441C45F6600072450B /* testair.cpp */; };
</del><span class="cx">                 0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */; };
</span><span class="cx">                 0F620176143FCD3B0068B77C /* DFGBasicBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620170143FCD2F0068B77C /* DFGBasicBlock.h */; };
</span><span class="cx">                 0F620177143FCD3F0068B77C /* DFGAbstractValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */; };
</span><span class="lines">@@ -2095,13 +2079,6 @@
</span><span class="cx"> /* End PBXBuildFile section */
</span><span class="cx">
</span><span class="cx"> /* Begin PBXContainerItemProxy section */
</span><del>-                0F6183461C45F67A0072450B /* PBXContainerItemProxy */ = {
-                        isa = PBXContainerItemProxy;
-                        containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
-                        proxyType = 1;
-                        remoteGlobalIDString = 0F6183381C45F62A0072450B;
-                        remoteInfo = testair;
-                };
</del><span class="cx">                 0F93275C1C20BF3A00CF6564 /* PBXContainerItemProxy */ = {
</span><span class="cx">                         isa = PBXContainerItemProxy;
</span><span class="cx">                         containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
</span><span class="lines">@@ -2565,20 +2542,6 @@
</span><span class="cx">                 0F5EF91B16878F78003E5C25 /* JITThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITThunks.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 0F5EF91C16878F78003E5C25 /* JITThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITThunks.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnconditionalFinalizer.h; sourceTree = "<group>"; };
</span><del>-                0F6183201C45BF070072450B /* AirCCallingConvention.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirCCallingConvention.cpp; path = b3/air/AirCCallingConvention.cpp; sourceTree = "<group>"; };
-                0F6183211C45BF070072450B /* AirCCallingConvention.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirCCallingConvention.h; path = b3/air/AirCCallingConvention.h; sourceTree = "<group>"; };
-                0F6183221C45BF070072450B /* AirCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirCustom.cpp; path = b3/air/AirCustom.cpp; sourceTree = "<group>"; };
-                0F6183231C45BF070072450B /* AirEmitShuffle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirEmitShuffle.cpp; path = b3/air/AirEmitShuffle.cpp; sourceTree = "<group>"; };
-                0F6183241C45BF070072450B /* AirEmitShuffle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirEmitShuffle.h; path = b3/air/AirEmitShuffle.h; sourceTree = "<group>"; };
-                0F6183251C45BF070072450B /* AirLowerAfterRegAlloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirLowerAfterRegAlloc.cpp; path = b3/air/AirLowerAfterRegAlloc.cpp; sourceTree = "<group>"; };
-                0F6183261C45BF070072450B /* AirLowerAfterRegAlloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirLowerAfterRegAlloc.h; path = b3/air/AirLowerAfterRegAlloc.h; sourceTree = "<group>"; };
-                0F6183271C45BF070072450B /* AirLowerMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirLowerMacros.cpp; path = b3/air/AirLowerMacros.cpp; sourceTree = "<group>"; };
-                0F6183281C45BF070072450B /* AirLowerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirLowerMacros.h; path = b3/air/AirLowerMacros.h; sourceTree = "<group>"; };
-                0F6183321C45F35C0072450B /* AirOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirOpcode.h; sourceTree = "<group>"; };
-                0F6183341C45F3B60072450B /* AirOpcodeGenerated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirOpcodeGenerated.h; sourceTree = "<group>"; };
-                0F6183351C45F3B60072450B /* AirOpcodeUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AirOpcodeUtils.h; sourceTree = "<group>"; };
-                0F6183431C45F62A0072450B /* testair */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testair; sourceTree = BUILT_PRODUCTS_DIR; };
-                0F6183441C45F6600072450B /* testair.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testair.cpp; path = b3/air/testair.cpp; sourceTree = "<group>"; };
</del><span class="cx">                 0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractValue.h; path = dfg/DFGAbstractValue.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F620170143FCD2F0068B77C /* DFGBasicBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBasicBlock.h; path = dfg/DFGBasicBlock.h; sourceTree = "<group>"; };
</span><span class="cx">                 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGVariableAccessData.h; path = dfg/DFGVariableAccessData.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -3409,8 +3372,8 @@
</span><span class="cx">                 7013CA8A1B491A9400CAE613 /* JSJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSJob.h; sourceTree = "<group>"; };
</span><span class="cx">                 7035587C1C418419004BD7BF /* MapPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = MapPrototype.js; sourceTree = "<group>"; };
</span><span class="cx">                 7035587D1C418419004BD7BF /* SetPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = SetPrototype.js; sourceTree = "<group>"; };
</span><del>-                7035587E1C418458004BD7BF /* MapPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapPrototype.lut.h; sourceTree = "<group>"; };
-                7035587F1C418458004BD7BF /* SetPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetPrototype.lut.h; sourceTree = "<group>"; };
</del><ins>+                7035587E1C418458004BD7BF /* MapPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MapPrototype.lut.h; path = MapPrototype.lut.h; sourceTree = "<group>"; };
+                7035587F1C418458004BD7BF /* SetPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SetPrototype.lut.h; path = SetPrototype.lut.h; sourceTree = "<group>"; };
</ins><span class="cx">                 704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; };
</span><span class="cx">                 705B41A31A6E501E00716757 /* Symbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbol.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 705B41A41A6E501E00716757 /* Symbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Symbol.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -4343,15 +4306,6 @@
</span><span class="cx"> /* End PBXFileReference section */
</span><span class="cx">
</span><span class="cx"> /* Begin PBXFrameworksBuildPhase section */
</span><del>-                0F61833B1C45F62A0072450B /* Frameworks */ = {
-                        isa = PBXFrameworksBuildPhase;
-                        buildActionMask = 2147483647;
-                        files = (
-                                0F61833C1C45F62A0072450B /* Foundation.framework in Frameworks */,
-                                0F61833D1C45F62A0072450B /* JavaScriptCore.framework in Frameworks */,
-                        );
-                        runOnlyForDeploymentPostprocessing = 0;
-                };
</del><span class="cx">                 0F9327511C20BCBA00CF6564 /* Frameworks */ = {
</span><span class="cx">                         isa = PBXFrameworksBuildPhase;
</span><span class="cx">                         buildActionMask = 2147483647;
</span><span class="lines">@@ -4449,7 +4403,6 @@
</span><span class="cx">                                 0FEC85AD1BDB5CF10080FF74 /* testb3 */,
</span><span class="cx">                                 6511230514046A4C002B101D /* testRegExp */,
</span><span class="cx">                                 0F9327591C20BCBA00CF6564 /* dynbench */,
</span><del>-                                0F6183431C45F62A0072450B /* testair */,
</del><span class="cx">                         );
</span><span class="cx">                         name = Products;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -4840,18 +4793,13 @@
</span><span class="cx">                                 0FEC854C1BDACDC70080FF74 /* AirBasicBlock.cpp */,
</span><span class="cx">                                 0FEC854D1BDACDC70080FF74 /* AirBasicBlock.h */,
</span><span class="cx">                                 0FB3878B1BFBC44D00E3AB1E /* AirBlockWorklist.h */,
</span><del>-                                0F6183201C45BF070072450B /* AirCCallingConvention.cpp */,
-                                0F6183211C45BF070072450B /* AirCCallingConvention.h */,
</del><span class="cx">                                 0FEC854E1BDACDC70080FF74 /* AirCCallSpecial.cpp */,
</span><span class="cx">                                 0FEC854F1BDACDC70080FF74 /* AirCCallSpecial.h */,
</span><span class="cx">                                 0FEC85501BDACDC70080FF74 /* AirCode.cpp */,
</span><span class="cx">                                 0FEC85511BDACDC70080FF74 /* AirCode.h */,
</span><del>-                                0F6183221C45BF070072450B /* AirCustom.cpp */,
</del><span class="cx">                                 0F10F1A21C420BF0001C07D2 /* AirCustom.h */,
</span><span class="cx">                                 0F4570361BE44C910062A629 /* AirEliminateDeadCode.cpp */,
</span><span class="cx">                                 0F4570371BE44C910062A629 /* AirEliminateDeadCode.h */,
</span><del>-                                0F6183231C45BF070072450B /* AirEmitShuffle.cpp */,
-                                0F6183241C45BF070072450B /* AirEmitShuffle.h */,
</del><span class="cx">                                 262D85B41C0D650F006ACB61 /* AirFixPartialRegisterStalls.cpp */,
</span><span class="cx">                                 262D85B51C0D650F006ACB61 /* AirFixPartialRegisterStalls.h */,
</span><span class="cx">                                 0F4C91671C2B3D68004341A6 /* AirFixSpillSlotZDef.h */,
</span><span class="lines">@@ -4870,10 +4818,6 @@
</span><span class="cx">                                 26718BA21BE99F780052017B /* AirIteratedRegisterCoalescing.cpp */,
</span><span class="cx">                                 26718BA31BE99F780052017B /* AirIteratedRegisterCoalescing.h */,
</span><span class="cx">                                 2684D4371C00161C0081D663 /* AirLiveness.h */,
</span><del>-                                0F6183251C45BF070072450B /* AirLowerAfterRegAlloc.cpp */,
-                                0F6183261C45BF070072450B /* AirLowerAfterRegAlloc.h */,
-                                0F6183271C45BF070072450B /* AirLowerMacros.cpp */,
-                                0F6183281C45BF070072450B /* AirLowerMacros.h */,
</del><span class="cx">                                 264091FA1BE2FD4100684DB2 /* AirOpcode.opcodes */,
</span><span class="cx">                                 0FB3878C1BFBC44D00E3AB1E /* AirOptimizeBlockOrder.cpp */,
</span><span class="cx">                                 0FB3878D1BFBC44D00E3AB1E /* AirOptimizeBlockOrder.h */,
</span><span class="lines">@@ -4899,7 +4843,6 @@
</span><span class="cx">                                 0F3730921C0D67EE00052BFA /* AirUseCounts.h */,
</span><span class="cx">                                 0FEC856B1BDACDC70080FF74 /* AirValidate.cpp */,
</span><span class="cx">                                 0FEC856C1BDACDC70080FF74 /* AirValidate.h */,
</span><del>-                                0F6183441C45F6600072450B /* testair.cpp */,
</del><span class="cx">                         );
</span><span class="cx">                         name = air;
</span><span class="cx">                         sourceTree = "<group>";
</span><span class="lines">@@ -5357,9 +5300,6 @@
</span><span class="cx">                 650FDF8D09D0FCA700769E54 /* Derived Sources */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><del>-                                0F6183321C45F35C0072450B /* AirOpcode.h */,
-                                0F6183341C45F3B60072450B /* AirOpcodeGenerated.h */,
-                                0F6183351C45F3B60072450B /* AirOpcodeUtils.h */,
</del><span class="cx">                                 996B73151BDA05AA00331B84 /* ArrayConstructor.lut.h */,
</span><span class="cx">                                 996B73161BDA05AA00331B84 /* ArrayIteratorPrototype.lut.h */,
</span><span class="cx">                                 996B73071BD9FA2C00331B84 /* BooleanPrototype.lut.h */,
</span><span class="lines">@@ -6959,7 +6899,6 @@
</span><span class="cx">                                 0F4570391BE44C910062A629 /* AirEliminateDeadCode.h in Headers */,
</span><span class="cx">                                 79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */,
</span><span class="cx">                                 79D5CD5B1C1106A900CECA07 /* SamplingProfiler.h in Headers */,
</span><del>-                                0F6183311C45BF070072450B /* AirLowerMacros.h in Headers */,
</del><span class="cx">                                 0FEC85771BDACDC70080FF74 /* AirFrequentedBlock.h in Headers */,
</span><span class="cx">                                 0FEC85791BDACDC70080FF74 /* AirGenerate.h in Headers */,
</span><span class="cx">                                 79DF66B11BF26A570001CF11 /* FTLExceptionHandlerManager.h in Headers */,
</span><span class="lines">@@ -7022,7 +6961,6 @@
</span><span class="cx">                                 0FEC85141BDACDAC0080FF74 /* B3ControlValue.h in Headers */,
</span><span class="cx">                                 0FEC85C11BE167A00080FF74 /* B3Effects.h in Headers */,
</span><span class="cx">                                 0FEC85161BDACDAC0080FF74 /* B3FrequencyClass.h in Headers */,
</span><del>-                                0F61832F1C45BF070072450B /* AirLowerAfterRegAlloc.h in Headers */,
</del><span class="cx">                                 0FEC85171BDACDAC0080FF74 /* B3FrequentedBlock.h in Headers */,
</span><span class="cx">                                 0FEC85191BDACDAC0080FF74 /* B3Generate.h in Headers */,
</span><span class="cx">                                 0FEC851A1BDACDAC0080FF74 /* B3GenericFrequentedBlock.h in Headers */,
</span><span class="lines">@@ -7216,7 +7154,6 @@
</span><span class="cx">                                 A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
</span><span class="cx">                                 0F37308D1C0BD29100052BFA /* B3PhiChildren.h in Headers */,
</span><span class="cx">                                 A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */,
</span><del>-                                0F61832D1C45BF070072450B /* AirEmitShuffle.h in Headers */,
</del><span class="cx">                                 0F3C1F1B1B868E7900ABB08B /* DFGClobbersExitState.h in Headers */,
</span><span class="cx">                                 0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */,
</span><span class="cx">                                 0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */,
</span><span class="lines">@@ -7321,7 +7258,6 @@
</span><span class="cx">                                 0F2B9CED19D0BA7D00B1D1B5 /* DFGPromotedHeapLocation.h in Headers */,
</span><span class="cx">                                 0FFC92161B94FB3E0071DD66 /* DFGPropertyTypeKey.h in Headers */,
</span><span class="cx">                                 0FB17663196B8F9E0091052A /* DFGPureValue.h in Headers */,
</span><del>-                                0F6183361C45F3B60072450B /* AirOpcodeGenerated.h in Headers */,
</del><span class="cx">                                 0F3730911C0CD70C00052BFA /* AllowMacroScratchRegisterUsage.h in Headers */,
</span><span class="cx">                                 0F3A1BFA1A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h in Headers */,
</span><span class="cx">                                 86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */,
</span><span class="lines">@@ -7338,7 +7274,6 @@
</span><span class="cx">                                 0FC20CBA18556A3500C9E954 /* DFGSSALoweringPhase.h in Headers */,
</span><span class="cx">                                 0F9FB4F517FCB91700CB67F8 /* DFGStackLayoutPhase.h in Headers */,
</span><span class="cx">                                 0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */,
</span><del>-                                0F6183371C45F3B60072450B /* AirOpcodeUtils.h in Headers */,
</del><span class="cx">                                 0F9E32641B05AB0400801ED5 /* DFGStoreBarrierInsertionPhase.h in Headers */,
</span><span class="cx">                                 0FC20CB61852E2C600C9E954 /* DFGStrengthReductionPhase.h in Headers */,
</span><span class="cx">                                 0F63947815DCE34B006A597C /* DFGStructureAbstractValue.h in Headers */,
</span><span class="lines">@@ -7693,7 +7628,6 @@
</span><span class="cx">                                 0F2B66F717B6B5AB00A7AE3F /* JSInt8Array.h in Headers */,
</span><span class="cx">                                 A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */,
</span><span class="cx">                                 E33F50811B8429A400413856 /* JSInternalPromise.h in Headers */,
</span><del>-                                0F61832A1C45BF070072450B /* AirCCallingConvention.h in Headers */,
</del><span class="cx">                                 E33F50791B84225700413856 /* JSInternalPromiseConstructor.h in Headers */,
</span><span class="cx">                                 E33F50871B8449EF00413856 /* JSInternalPromiseConstructor.lut.h in Headers */,
</span><span class="cx">                                 E33F50851B8437A000413856 /* JSInternalPromiseDeferred.h in Headers */,
</span><span class="lines">@@ -8084,7 +8018,6 @@
</span><span class="cx">                                 142E313C134FF0A600AFADB5 /* Weak.h in Headers */,
</span><span class="cx">                                 14E84F9F14EE1ACC00D6D5D4 /* WeakBlock.h in Headers */,
</span><span class="cx">                                 14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */,
</span><del>-                                0F6183331C45F35C0072450B /* AirOpcode.h in Headers */,
</del><span class="cx">                                 AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */,
</span><span class="cx">                                 14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */,
</span><span class="cx">                                 14E84FA214EE1ACC00D6D5D4 /* WeakImpl.h in Headers */,
</span><span class="lines">@@ -8117,22 +8050,6 @@
</span><span class="cx"> /* End PBXHeadersBuildPhase section */
</span><span class="cx">
</span><span class="cx"> /* Begin PBXNativeTarget section */
</span><del>-                0F6183381C45F62A0072450B /* testair */ = {
-                        isa = PBXNativeTarget;
-                        buildConfigurationList = 0F61833E1C45F62A0072450B /* Build configuration list for PBXNativeTarget "testair" */;
-                        buildPhases = (
-                                0F6183391C45F62A0072450B /* Sources */,
-                                0F61833B1C45F62A0072450B /* Frameworks */,
-                        );
-                        buildRules = (
-                        );
-                        dependencies = (
-                        );
-                        name = testair;
-                        productName = testapi;
-                        productReference = 0F6183431C45F62A0072450B /* testair */;
-                        productType = "com.apple.product-type.tool";
-                };
</del><span class="cx">                 0F93274E1C20BCBA00CF6564 /* dynbench */ = {
</span><span class="cx">                         isa = PBXNativeTarget;
</span><span class="cx">                         buildConfigurationList = 0F9327541C20BCBA00CF6564 /* Build configuration list for PBXNativeTarget "dynbench" */;
</span><span class="lines">@@ -8340,7 +8257,6 @@
</span><span class="cx">                                 0FEC85941BDB5CF10080FF74 /* testb3 */,
</span><span class="cx">                                 5D6B2A47152B9E17005231DE /* Test Tools */,
</span><span class="cx">                                 0F93274E1C20BCBA00CF6564 /* dynbench */,
</span><del>-                                0F6183381C45F62A0072450B /* testair */,
</del><span class="cx">                         );
</span><span class="cx">                 };
</span><span class="cx"> /* End PBXProject section */
</span><span class="lines">@@ -8577,14 +8493,6 @@
</span><span class="cx"> /* End PBXShellScriptBuildPhase section */
</span><span class="cx">
</span><span class="cx"> /* Begin PBXSourcesBuildPhase section */
</span><del>-                0F6183391C45F62A0072450B /* Sources */ = {
-                        isa = PBXSourcesBuildPhase;
-                        buildActionMask = 2147483647;
-                        files = (
-                                0F6183451C45F6600072450B /* testair.cpp in Sources */,
-                        );
-                        runOnlyForDeploymentPostprocessing = 0;
-                };
</del><span class="cx">                 0F93274F1C20BCBA00CF6564 /* Sources */ = {
</span><span class="cx">                         isa = PBXSourcesBuildPhase;
</span><span class="cx">                         buildActionMask = 2147483647;
</span><span class="lines">@@ -8789,7 +8697,6 @@
</span><span class="cx">                                 52B717B51A0597E1007AF4F3 /* ControlFlowProfiler.cpp in Sources */,
</span><span class="cx">                                 0FBADF541BD1F4B800E073C1 /* CopiedBlock.cpp in Sources */,
</span><span class="cx">                                 C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */,
</span><del>-                                0F6183301C45BF070072450B /* AirLowerMacros.cpp in Sources */,
</del><span class="cx">                                 C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */,
</span><span class="cx">                                 2A111245192FCE79005EE18D /* CustomGetterSetter.cpp in Sources */,
</span><span class="cx">                                 62E3D5F01B8D0B7300B868BB /* DataFormat.cpp in Sources */,
</span><span class="lines">@@ -8838,7 +8745,6 @@
</span><span class="cx">                                 0F0981F71BC5E565004814F8 /* DFGCopyBarrierOptimizationPhase.cpp in Sources */,
</span><span class="cx">                                 0FBE0F7216C1DB030082C5E8 /* DFGCPSRethreadingPhase.cpp in Sources */,
</span><span class="cx">                                 A7D89CF517A0B8CC00773AD8 /* DFGCriticalEdgeBreakingPhase.cpp in Sources */,
</span><del>-                                0F6183291C45BF070072450B /* AirCCallingConvention.cpp in Sources */,
</del><span class="cx">                                 0FFFC95914EF90A600C72532 /* DFGCSEPhase.cpp in Sources */,
</span><span class="cx">                                 0F2FC77216E12F710038D976 /* DFGDCEPhase.cpp in Sources */,
</span><span class="cx">                                 0F338E121BF0276C0013C88F /* B3OpaqueByproducts.cpp in Sources */,
</span><span class="lines">@@ -8855,7 +8761,6 @@
</span><span class="cx">                                 A78A9774179738B8009DF744 /* DFGFailedFinalizer.cpp in Sources */,
</span><span class="cx">                                 A78A9776179738B8009DF744 /* DFGFinalizer.cpp in Sources */,
</span><span class="cx">                                 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */,
</span><del>-                                0F61832C1C45BF070072450B /* AirEmitShuffle.cpp in Sources */,
</del><span class="cx">                                 0F9D339617FFC4E60073C2BC /* DFGFlushedAt.cpp in Sources */,
</span><span class="cx">                                 A7D89CF717A0B8CC00773AD8 /* DFGFlushFormat.cpp in Sources */,
</span><span class="cx">                                 0F69CC88193AC60A0045759E /* DFGFrozenValue.cpp in Sources */,
</span><span class="lines">@@ -9167,7 +9072,6 @@
</span><span class="cx">                                 E33F50841B8437A000413856 /* JSInternalPromiseDeferred.cpp in Sources */,
</span><span class="cx">                                 E33F50741B8421C000413856 /* JSInternalPromisePrototype.cpp in Sources */,
</span><span class="cx">                                 A503FA1B188E0FB000110F14 /* JSJavaScriptCallFrame.cpp in Sources */,
</span><del>-                                0F61832E1C45BF070072450B /* AirLowerAfterRegAlloc.cpp in Sources */,
</del><span class="cx">                                 A503FA1D188E0FB000110F14 /* JSJavaScriptCallFramePrototype.cpp in Sources */,
</span><span class="cx">                                 7013CA8B1B491A9400CAE613 /* JSJob.cpp in Sources */,
</span><span class="cx">                                 140B7D1D0DC69AF7009C42B8 /* JSLexicalEnvironment.cpp in Sources */,
</span><span class="lines">@@ -9310,7 +9214,6 @@
</span><span class="cx">                                 0F9D4C0C1C3E1C11006CD984 /* FTLExceptionTarget.cpp in Sources */,
</span><span class="cx">                                 0FB1058B1675483100F8AB6E /* ProfilerOSRExit.cpp in Sources */,
</span><span class="cx">                                 0FB1058D1675483700F8AB6E /* ProfilerOSRExitSite.cpp in Sources */,
</span><del>-                                0F61832B1C45BF070072450B /* AirCustom.cpp in Sources */,
</del><span class="cx">                                 0F13912B16771C3A009CCB07 /* ProfilerProfiledBytecodes.cpp in Sources */,
</span><span class="cx">                                 0FD3E40D1B618B6600C80E1E /* PropertyCondition.cpp in Sources */,
</span><span class="cx">                                 A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */,
</span><span class="lines">@@ -9463,11 +9366,6 @@
</span><span class="cx"> /* End PBXSourcesBuildPhase section */
</span><span class="cx">
</span><span class="cx"> /* Begin PBXTargetDependency section */
</span><del>-                0F6183471C45F67A0072450B /* PBXTargetDependency */ = {
-                        isa = PBXTargetDependency;
-                        target = 0F6183381C45F62A0072450B /* testair */;
-                        targetProxy = 0F6183461C45F67A0072450B /* PBXContainerItemProxy */;
-                };
</del><span class="cx">                 0F93275D1C20BF3A00CF6564 /* PBXTargetDependency */ = {
</span><span class="cx">                         isa = PBXTargetDependency;
</span><span class="cx">                         target = 0F93274E1C20BCBA00CF6564 /* dynbench */;
</span><span class="lines">@@ -9579,42 +9477,6 @@
</span><span class="cx">                         };
</span><span class="cx">                         name = Production;
</span><span class="cx">                 };
</span><del>-                0F61833F1C45F62A0072450B /* Debug */ = {
-                        isa = XCBuildConfiguration;
-                        baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
-                        buildSettings = {
-                                CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;
-                                PRODUCT_NAME = testair;
-                        };
-                        name = Debug;
-                };
-                0F6183401C45F62A0072450B /* Release */ = {
-                        isa = XCBuildConfiguration;
-                        baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
-                        buildSettings = {
-                                CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;
-                                PRODUCT_NAME = testair;
-                        };
-                        name = Release;
-                };
-                0F6183411C45F62A0072450B /* Profiling */ = {
-                        isa = XCBuildConfiguration;
-                        baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
-                        buildSettings = {
-                                CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;
-                                PRODUCT_NAME = testair;
-                        };
-                        name = Profiling;
-                };
-                0F6183421C45F62A0072450B /* Production */ = {
-                        isa = XCBuildConfiguration;
-                        baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
-                        buildSettings = {
-                                CODE_SIGN_ENTITLEMENTS_ios_testair = entitlements.plist;
-                                PRODUCT_NAME = testair;
-                        };
-                        name = Production;
-                };
</del><span class="cx">                 0F9327551C20BCBA00CF6564 /* Debug */ = {
</span><span class="cx">                         isa = XCBuildConfiguration;
</span><span class="cx">                         baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
</span><span class="lines">@@ -10044,17 +9906,6 @@
</span><span class="cx">                         defaultConfigurationIsVisible = 0;
</span><span class="cx">                         defaultConfigurationName = Production;
</span><span class="cx">                 };
</span><del>-                0F61833E1C45F62A0072450B /* Build configuration list for PBXNativeTarget "testair" */ = {
-                        isa = XCConfigurationList;
-                        buildConfigurations = (
-                                0F61833F1C45F62A0072450B /* Debug */,
-                                0F6183401C45F62A0072450B /* Release */,
-                                0F6183411C45F62A0072450B /* Profiling */,
-                                0F6183421C45F62A0072450B /* Production */,
-                        );
-                        defaultConfigurationIsVisible = 0;
-                        defaultConfigurationName = Production;
-                };
</del><span class="cx">                 0F9327541C20BCBA00CF6564 /* Build configuration list for PBXNativeTarget "dynbench" */ = {
</span><span class="cx">                         isa = XCConfigurationList;
</span><span class="cx">                         buildConfigurations = (
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerAbstractMacroAssemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2012, 2014-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2012, 2014, 2015 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">@@ -76,15 +76,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline bool isIOS()
-{
-#if PLATFORM(IOS)
- return true;
-#else
- return false;
-#endif
-}
-
</del><span class="cx"> inline bool optimizeForARMv7IDIVSupported()
</span><span class="cx"> {
</span><span class="cx"> return isARMv7IDIVSupported() && Options::useArchitectureSpecificOptimizations();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerX86Commonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1411,16 +1411,6 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- void swap32(RegisterID src, RegisterID dest)
- {
- m_assembler.xchgl_rr(src, dest);
- }
-
- void swap32(RegisterID src, Address dest)
- {
- m_assembler.xchgl_rm(src, dest.offset, dest.base);
- }
-
</del><span class="cx"> void moveConditionally32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID src, RegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> m_assembler.cmpl_rr(right, left);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerX86_64h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2012, 2014-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2012, 2014, 2015 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">@@ -655,16 +655,6 @@
</span><span class="cx"> return DataLabel32(this);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void swap64(RegisterID src, RegisterID dest)
- {
- m_assembler.xchgq_rr(src, dest);
- }
-
- void swap64(RegisterID src, Address dest)
- {
- m_assembler.xchgq_rm(src, dest.offset, dest.base);
- }
-
</del><span class="cx"> void move64ToDouble(RegisterID src, FPRegisterID dest)
</span><span class="cx"> {
</span><span class="cx"> m_assembler.movq_rr(src, dest);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerX86Assemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/X86Assembler.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/X86Assembler.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/assembler/X86Assembler.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2012-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2012-2015 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">@@ -1431,11 +1431,6 @@
</span><span class="cx"> m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- void xchgl_rm(RegisterID src, int offset, RegisterID base)
- {
- m_formatter.oneByteOp(OP_XCHG_EvGv, src, base, offset);
- }
-
</del><span class="cx"> #if CPU(X86_64)
</span><span class="cx"> void xchgq_rr(RegisterID src, RegisterID dst)
</span><span class="cx"> {
</span><span class="lines">@@ -1446,11 +1441,6 @@
</span><span class="cx"> else
</span><span class="cx"> m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
</span><span class="cx"> }
</span><del>-
- void xchgq_rm(RegisterID src, int offset, RegisterID base)
- {
- m_formatter.oneByteOp64(OP_XCHG_EvGv, src, base, offset);
- }
</del><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> void movl_rr(RegisterID src, RegisterID dst)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CCallValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CCallValue.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CCallValue.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/B3CCallValue.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -39,7 +39,7 @@
</span><span class="cx">
</span><span class="cx"> ~CCallValue();
</span><span class="cx">
</span><del>- Effects effects { Effects::forCall() };
</del><ins>+ Effects effects;
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> friend class Procedure;
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> template<typename... Arguments>
</span><span class="cx"> CCallValue(unsigned index, Type type, Origin origin, Arguments... arguments)
</span><span class="cx"> : Value(index, CheckedOpcode, CCall, type, origin, arguments...)
</span><ins>+ , effects(Effects::forCall())
</ins><span class="cx"> {
</span><span class="cx"> RELEASE_ASSERT(numChildren() >= 1);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Compilationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Compilation.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Compilation.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/B3Compilation.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -52,12 +52,6 @@
</span><span class="cx"> m_byproducts = proc.releaseByproducts();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-Compilation::Compilation(MacroAssemblerCodeRef codeRef, std::unique_ptr<OpaqueByproducts> byproducts)
- : m_codeRef(codeRef)
- , m_byproducts(WTFMove(byproducts))
-{
-}
-
</del><span class="cx"> Compilation::~Compilation()
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Compilationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Compilation.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Compilation.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/B3Compilation.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -55,11 +55,6 @@
</span><span class="cx">
</span><span class="cx"> public:
</span><span class="cx"> JS_EXPORT_PRIVATE Compilation(VM&, Procedure&, unsigned optLevel = 1);
</span><del>-
- // This constructor allows you to manually create a Compilation. It's currently only used by test
- // code. Probably best to keep it that way.
- JS_EXPORT_PRIVATE Compilation(MacroAssemblerCodeRef, std::unique_ptr<OpaqueByproducts>);
-
</del><span class="cx"> JS_EXPORT_PRIVATE ~Compilation();
</span><span class="cx">
</span><span class="cx"> MacroAssemblerCodePtr code() const { return m_codeRef.code(); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx"> #include "AirStackSlot.h"
</span><span class="cx"> #include "B3ArgumentRegValue.h"
</span><span class="cx"> #include "B3BasicBlockInlines.h"
</span><del>-#include "B3BlockWorklist.h"
</del><span class="cx"> #include "B3CCallValue.h"
</span><span class="cx"> #include "B3CheckSpecial.h"
</span><span class="cx"> #include "B3Commutativity.h"
</span><span class="lines">@@ -100,15 +99,6 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- // Figure out which blocks are not rare.
- m_fastWorklist.push(m_procedure[0]);
- while (B3::BasicBlock* block = m_fastWorklist.pop()) {
- for (B3::FrequentedBlock& successor : block->successors()) {
- if (!successor.isRare())
- m_fastWorklist.push(successor.block());
- }
- }
-
</del><span class="cx"> m_procedure.resetValueOwners(); // Used by crossesInterference().
</span><span class="cx">
</span><span class="cx"> // Lower defs before uses on a global level. This is a good heuristic to lock down a
</span><span class="lines">@@ -118,8 +108,6 @@
</span><span class="cx"> // Reset some state.
</span><span class="cx"> m_insts.resize(0);
</span><span class="cx">
</span><del>- m_isRare = !m_fastWorklist.saw(block);
-
</del><span class="cx"> if (verbose)
</span><span class="cx"> dataLog("Lowering Block ", *block, ":\n");
</span><span class="cx">
</span><span class="lines">@@ -1564,6 +1552,37 @@
</span><span class="cx"> inverted);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ template<typename BankInfo>
+ Arg marshallCCallArgument(unsigned& argumentCount, unsigned& stackOffset, Value* child)
+ {
+ unsigned argumentIndex = argumentCount++;
+ if (argumentIndex < BankInfo::numberOfArgumentRegisters) {
+ Tmp result = Tmp(BankInfo::toArgumentRegister(argumentIndex));
+ append(relaxedMoveForType(child->type()), immOrTmp(child), result);
+ return result;
+ }
+
+#if CPU(ARM64) && PLATFORM(IOS)
+ // iOS does not follow the ARM64 ABI regarding function calls.
+ // Arguments must be packed.
+ unsigned slotSize = sizeofType(child->type());
+ stackOffset = WTF::roundUpToMultipleOf(slotSize, stackOffset);
+#else
+ unsigned slotSize = sizeof(void*);
+#endif
+ Arg result = Arg::callArg(stackOffset);
+ stackOffset += slotSize;
+
+ // Put the code for storing the argument before anything else. This significantly eases the
+ // burden on the register allocator. If we could, we'd hoist these stores as far as
+ // possible.
+ // FIXME: Add a phase to hoist stores as high as possible to relieve register pressure.
+ // https://bugs.webkit.org/show_bug.cgi?id=151063
+ m_insts.last().insert(0, createStore(child, result));
+
+ return result;
+ }
+
</ins><span class="cx"> void lower()
</span><span class="cx"> {
</span><span class="cx"> switch (m_value->opcode()) {
</span><span class="lines">@@ -1915,10 +1934,14 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- case B3::CCall: {
</del><ins>+ case CCall: {
</ins><span class="cx"> CCallValue* cCall = m_value->as<CCallValue>();
</span><ins>+ Inst inst(Patch, cCall, Arg::special(m_code.cCallSpecial()));
</ins><span class="cx">
</span><del>- Inst inst(m_isRare ? Air::ColdCCall : Air::CCall, cCall);
</del><ins>+ // This is a bit weird - we have a super intense contract with Arg::CCallSpecial. It might
+ // be better if we factored Air::CCallSpecial out of the Air namespace and made it a B3
+ // thing.
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=151045
</ins><span class="cx">
</span><span class="cx"> // We have a ton of flexibility regarding the callee argument, but currently, we don't
</span><span class="cx"> // use it yet. It gets weird for reasons:
</span><span class="lines">@@ -1931,13 +1954,48 @@
</span><span class="cx"> // FIXME: https://bugs.webkit.org/show_bug.cgi?id=151052
</span><span class="cx"> inst.args.append(tmp(cCall->child(0)));
</span><span class="cx">
</span><del>- if (cCall->type() != Void)
- inst.args.append(tmp(cCall));
</del><ins>+ // We need to tell Air what registers this defines.
+ inst.args.append(Tmp(GPRInfo::returnValueGPR));
+ inst.args.append(Tmp(GPRInfo::returnValueGPR2));
+ inst.args.append(Tmp(FPRInfo::returnValueFPR));
</ins><span class="cx">
</span><del>- for (unsigned i = 1; i < cCall->numChildren(); ++i)
- inst.args.append(immOrTmp(cCall->child(i)));
</del><ins>+ // Now marshall the arguments. This is where we implement the C calling convention. After
+ // this, Air does not know what the convention is; it just takes our word for it.
+ unsigned gpArgumentCount = 0;
+ unsigned fpArgumentCount = 0;
+ unsigned stackOffset = 0;
+ for (unsigned i = 1; i < cCall->numChildren(); ++i) {
+ Value* argChild = cCall->child(i);
+ Arg arg;
+
+ switch (Arg::typeForB3Type(argChild->type())) {
+ case Arg::GP:
+ arg = marshallCCallArgument<GPRInfo>(gpArgumentCount, stackOffset, argChild);
+ break;
</ins><span class="cx">
</span><ins>+ case Arg::FP:
+ arg = marshallCCallArgument<FPRInfo>(fpArgumentCount, stackOffset, argChild);
+ break;
+ }
+
+ if (arg.isTmp())
+ inst.args.append(arg);
+ }
+
</ins><span class="cx"> m_insts.last().append(WTFMove(inst));
</span><ins>+
+ switch (cCall->type()) {
+ case Void:
+ break;
+ case Int32:
+ case Int64:
+ append(Move, Tmp(GPRInfo::returnValueGPR), tmp(cCall));
+ break;
+ case Float:
+ case Double:
+ append(MoveDouble, Tmp(FPRInfo::returnValueFPR), tmp(cCall));
+ break;
+ }
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -2229,13 +2287,11 @@
</span><span class="cx">
</span><span class="cx"> UseCounts m_useCounts;
</span><span class="cx"> PhiChildren m_phiChildren;
</span><del>- BlockWorklist m_fastWorklist;
</del><span class="cx">
</span><span class="cx"> Vector<Vector<Inst, 4>> m_insts;
</span><span class="cx"> Vector<Inst> m_prologue;
</span><span class="cx">
</span><span class="cx"> B3::BasicBlock* m_block;
</span><del>- bool m_isRare;
</del><span class="cx"> unsigned m_index;
</span><span class="cx"> Value* m_value;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3OpaqueByproductsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3OpaqueByproducts.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3OpaqueByproducts.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/B3OpaqueByproducts.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -39,7 +39,7 @@
</span><span class="cx"> WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx"> OpaqueByproducts();
</span><del>- JS_EXPORT_PRIVATE ~OpaqueByproducts();
</del><ins>+ ~OpaqueByproducts();
</ins><span class="cx">
</span><span class="cx"> size_t count() const { return m_byproducts.size(); }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackmapSpecialcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -200,14 +200,21 @@
</span><span class="cx"> case Arg::Tmp:
</span><span class="cx"> case Arg::Imm:
</span><span class="cx"> case Arg::Imm64:
</span><ins>+ case Arg::Stack:
+ case Arg::CallArg:
+ break; // OK
+ case Arg::Addr:
+ if (arg.base() != Tmp(GPRInfo::callFrameRegister)
+ && arg.base() != Tmp(MacroAssembler::stackPointerRegister))
+ return false;
</ins><span class="cx"> break;
</span><span class="cx"> default:
</span><del>- if (!arg.isStackMemory())
- return false;
- break;
</del><ins>+ return false;
</ins><span class="cx"> }
</span><ins>+
+ Arg::Type type = Arg::typeForB3Type(value->type());
</ins><span class="cx">
</span><del>- return arg.canRepresent(value);
</del><ins>+ return arg.isType(type);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool StackmapSpecial::isArgValidForRep(Air::Code& code, const Air::Arg& arg, const ValueRep& rep)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirArgcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirArg.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirArg.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirArg.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -30,9 +30,6 @@
</span><span class="cx">
</span><span class="cx"> #include "AirSpecial.h"
</span><span class="cx"> #include "AirStackSlot.h"
</span><del>-#include "B3Value.h"
-#include "FPRInfo.h"
-#include "GPRInfo.h"
</del><span class="cx">
</span><span class="cx"> #if COMPILER(GCC) && ASSERT_DISABLED
</span><span class="cx"> #pragma GCC diagnostic push
</span><span class="lines">@@ -41,20 +38,6 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC { namespace B3 { namespace Air {
</span><span class="cx">
</span><del>-bool Arg::isStackMemory() const
-{
- switch (kind()) {
- case Addr:
- return base() == Air::Tmp(GPRInfo::callFrameRegister)
- || base() == Air::Tmp(MacroAssembler::stackPointerRegister);
- case Stack:
- case CallArg:
- return true;
- default:
- return false;
- }
-}
-
</del><span class="cx"> bool Arg::isRepresentableAs(Width width, Signedness signedness) const
</span><span class="cx"> {
</span><span class="cx"> switch (signedness) {
</span><span class="lines">@@ -84,31 +67,6 @@
</span><span class="cx"> ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-bool Arg::usesTmp(Air::Tmp tmp) const
-{
- bool uses = false;
- const_cast<Arg*>(this)->forEachTmpFast(
- [&] (Air::Tmp otherTmp) {
- if (otherTmp == tmp)
- uses = true;
- });
- return uses;
-}
-
-bool Arg::canRepresent(Value* value) const
-{
- return isType(typeForB3Type(value->type()));
-}
-
-bool Arg::isCompatibleType(const Arg& other) const
-{
- if (hasType())
- return other.isType(type());
- if (other.hasType())
- return isType(other.type());
- return true;
-}
-
</del><span class="cx"> void Arg::dump(PrintStream& out) const
</span><span class="cx"> {
</span><span class="cx"> switch (m_kind) {
</span><span class="lines">@@ -159,9 +117,6 @@
</span><span class="cx"> case Special:
</span><span class="cx"> out.print(pointerDump(special()));
</span><span class="cx"> return;
</span><del>- case WidthArg:
- out.print(width());
- return;
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -212,9 +167,6 @@
</span><span class="cx"> case Arg::Special:
</span><span class="cx"> out.print("Special");
</span><span class="cx"> return;
</span><del>- case Arg::WidthArg:
- out.print("WidthArg");
- return;
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -279,16 +231,16 @@
</span><span class="cx"> {
</span><span class="cx"> switch (width) {
</span><span class="cx"> case Arg::Width8:
</span><del>- out.print("8");
</del><ins>+ out.print("Width8");
</ins><span class="cx"> return;
</span><span class="cx"> case Arg::Width16:
</span><del>- out.print("16");
</del><ins>+ out.print("Width16");
</ins><span class="cx"> return;
</span><span class="cx"> case Arg::Width32:
</span><del>- out.print("32");
</del><ins>+ out.print("Width32");
</ins><span class="cx"> return;
</span><span class="cx"> case Arg::Width64:
</span><del>- out.print("64");
</del><ins>+ out.print("Width64");
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirArgh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirArg.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirArg.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirArg.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -38,12 +38,8 @@
</span><span class="cx"> #pragma GCC diagnostic ignored "-Wreturn-type"
</span><span class="cx"> #endif // COMPILER(GCC) && ASSERT_DISABLED
</span><span class="cx">
</span><del>-namespace JSC { namespace B3 {
</del><ins>+namespace JSC { namespace B3 { namespace Air {
</ins><span class="cx">
</span><del>-class Value;
-
-namespace Air {
-
</del><span class="cx"> class Special;
</span><span class="cx"> class StackSlot;
</span><span class="cx">
</span><span class="lines">@@ -78,8 +74,7 @@
</span><span class="cx"> RelCond,
</span><span class="cx"> ResCond,
</span><span class="cx"> DoubleCond,
</span><del>- Special,
- WidthArg
</del><ins>+ Special
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> enum Role : int8_t {
</span><span class="lines">@@ -166,13 +161,6 @@
</span><span class="cx">
</span><span class="cx"> static const unsigned numTypes = 2;
</span><span class="cx">
</span><del>- template<typename Functor>
- static void forEachType(const Functor& functor)
- {
- functor(GP);
- functor(FP);
- }
-
</del><span class="cx"> enum Width : int8_t {
</span><span class="cx"> Width8,
</span><span class="cx"> Width16,
</span><span class="lines">@@ -239,26 +227,6 @@
</span><span class="cx"> return isAnyUse(role) && !isColdUse(role);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- static Role cooled(Role role)
- {
- switch (role) {
- case ColdUse:
- case LateColdUse:
- case UseDef:
- case UseZDef:
- case Def:
- case ZDef:
- case UseAddr:
- case Scratch:
- case EarlyDef:
- return role;
- case Use:
- return ColdUse;
- case LateUse:
- return LateColdUse;
- }
- }
-
</del><span class="cx"> // Returns true if the Role implies that the Inst will Use the Arg before doing anything else.
</span><span class="cx"> static bool isEarlyUse(Role role)
</span><span class="cx"> {
</span><span class="lines">@@ -481,11 +449,6 @@
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- static Arg immPtr(const void* address)
- {
- return imm64(bitwise_cast<intptr_t>(address));
- }
-
</del><span class="cx"> static Arg addr(Air::Tmp base, int32_t offset = 0)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(base.isGP());
</span><span class="lines">@@ -600,14 +563,6 @@
</span><span class="cx"> return result;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- static Arg widthArg(Width width)
- {
- Arg result;
- result.m_kind = WidthArg;
- result.m_offset = width;
- return result;
- }
-
</del><span class="cx"> bool operator==(const Arg& other) const
</span><span class="cx"> {
</span><span class="cx"> return m_offset == other.m_offset
</span><span class="lines">@@ -644,11 +599,6 @@
</span><span class="cx"> return kind() == Imm64;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool isSomeImm() const
- {
- return isImm() || isImm64();
- }
-
</del><span class="cx"> bool isAddr() const
</span><span class="cx"> {
</span><span class="cx"> return kind() == Addr;
</span><span class="lines">@@ -669,21 +619,6 @@
</span><span class="cx"> return kind() == Index;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool isMemory() const
- {
- switch (kind()) {
- case Addr:
- case Stack:
- case CallArg:
- case Index:
- return true;
- default:
- return false;
- }
- }
-
- bool isStackMemory() const;
-
</del><span class="cx"> bool isRelCond() const
</span><span class="cx"> {
</span><span class="cx"> return kind() == RelCond;
</span><span class="lines">@@ -716,11 +651,6 @@
</span><span class="cx"> return kind() == Special;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool isWidthArg() const
- {
- return kind() == WidthArg;
- }
-
</del><span class="cx"> bool isAlive() const
</span><span class="cx"> {
</span><span class="cx"> return isTmp() || isStack();
</span><span class="lines">@@ -764,7 +694,18 @@
</span><span class="cx"> return m_base;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool hasOffset() const { return isMemory(); }
</del><ins>+ bool hasOffset() const
+ {
+ switch (kind()) {
+ case Addr:
+ case Stack:
+ case CallArg:
+ case Index:
+ return true;
+ default:
+ return false;
+ }
+ }
</ins><span class="cx">
</span><span class="cx"> int32_t offset() const
</span><span class="cx"> {
</span><span class="lines">@@ -803,12 +744,6 @@
</span><span class="cx"> return bitwise_cast<Air::Special*>(m_offset);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- Width width() const
- {
- ASSERT(kind() == WidthArg);
- return static_cast<Width>(m_offset);
- }
-
</del><span class="cx"> bool isGPTmp() const
</span><span class="cx"> {
</span><span class="cx"> return isTmp() && tmp().isGP();
</span><span class="lines">@@ -833,7 +768,6 @@
</span><span class="cx"> case ResCond:
</span><span class="cx"> case DoubleCond:
</span><span class="cx"> case Special:
</span><del>- case WidthArg:
</del><span class="cx"> return true;
</span><span class="cx"> case Tmp:
</span><span class="cx"> return isGPTmp();
</span><span class="lines">@@ -852,7 +786,6 @@
</span><span class="cx"> case ResCond:
</span><span class="cx"> case DoubleCond:
</span><span class="cx"> case Special:
</span><del>- case WidthArg:
</del><span class="cx"> case Invalid:
</span><span class="cx"> return false;
</span><span class="cx"> case Addr:
</span><span class="lines">@@ -896,10 +829,6 @@
</span><span class="cx"> ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool canRepresent(Value* value) const;
-
- bool isCompatibleType(const Arg& other) const;
-
</del><span class="cx"> bool isGPR() const
</span><span class="cx"> {
</span><span class="cx"> return isTmp() && tmp().isGPR();
</span><span class="lines">@@ -1041,7 +970,6 @@
</span><span class="cx"> case ResCond:
</span><span class="cx"> case DoubleCond:
</span><span class="cx"> case Special:
</span><del>- case WidthArg:
</del><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx"> ASSERT_NOT_REACHED();
</span><span class="lines">@@ -1064,8 +992,6 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- bool usesTmp(Air::Tmp tmp) const;
-
</del><span class="cx"> // This is smart enough to know that an address arg in a Def or UseDef rule will use its
</span><span class="cx"> // tmps and never def them. For example, this:
</span><span class="cx"> //
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirBasicBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirBasicBlock.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirBasicBlock.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirBasicBlock.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -78,17 +78,15 @@
</span><span class="cx"> InstList& insts() { return m_insts; }
</span><span class="cx">
</span><span class="cx"> template<typename Inst>
</span><del>- Inst& appendInst(Inst&& inst)
</del><ins>+ void appendInst(Inst&& inst)
</ins><span class="cx"> {
</span><span class="cx"> m_insts.append(std::forward<Inst>(inst));
</span><del>- return m_insts.last();
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template<typename... Arguments>
</span><del>- Inst& append(Arguments&&... arguments)
</del><ins>+ void append(Arguments&&... arguments)
</ins><span class="cx"> {
</span><span class="cx"> m_insts.append(Inst(std::forward<Arguments>(arguments)...));
</span><del>- return m_insts.last();
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // The "0" case is the case to which the branch jumps, so the "then" case. The "1" case is the
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCCallingConventioncpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirCCallingConvention.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCCallingConvention.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirCCallingConvention.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,127 +0,0 @@
</span><del>-/*
- * 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 "config.h"
-#include "AirCCallingConvention.h"
-
-#if ENABLE(B3_JIT)
-
-#include "AirCCallSpecial.h"
-#include "AirCode.h"
-#include "B3CCallValue.h"
-#include "B3ValueInlines.h"
-
-namespace JSC { namespace B3 { namespace Air {
-
-namespace {
-
-template<typename BankInfo>
-Arg marshallCCallArgumentImpl(unsigned& argumentCount, unsigned& stackOffset, Value* child)
-{
- unsigned argumentIndex = argumentCount++;
- if (argumentIndex < BankInfo::numberOfArgumentRegisters)
- return Tmp(BankInfo::toArgumentRegister(argumentIndex));
-
- unsigned slotSize;
- if (isARM64() && isIOS()) {
- // Arguments are packed.
- slotSize = sizeofType(child->type());
- } else {
- // Arguments are aligned.
- slotSize = 8;
- }
-
- stackOffset = WTF::roundUpToMultipleOf(slotSize, stackOffset);
- Arg result = Arg::callArg(stackOffset);
- stackOffset += slotSize;
- return result;
-}
-
-Arg marshallCCallArgument(
- unsigned& gpArgumentCount, unsigned& fpArgumentCount, unsigned& stackOffset, Value* child)
-{
- switch (Arg::typeForB3Type(child->type())) {
- case Arg::GP:
- return marshallCCallArgumentImpl<GPRInfo>(gpArgumentCount, stackOffset, child);
- case Arg::FP:
- return marshallCCallArgumentImpl<FPRInfo>(fpArgumentCount, stackOffset, child);
- }
- RELEASE_ASSERT_NOT_REACHED();
- return Arg();
-}
-
-} // anonymous namespace
-
-Vector<Arg> computeCCallingConvention(Code& code, CCallValue* value)
-{
- Vector<Arg> result;
- result.append(Tmp(CCallSpecial::scratchRegister));
- unsigned gpArgumentCount = 0;
- unsigned fpArgumentCount = 0;
- unsigned stackOffset = 0;
- for (unsigned i = 1; i < value->numChildren(); ++i) {
- result.append(
- marshallCCallArgument(gpArgumentCount, fpArgumentCount, stackOffset, value->child(i)));
- }
- code.requestCallArgAreaSize(WTF::roundUpToMultipleOf(stackAlignmentBytes(), stackOffset));
- return result;
-}
-
-Tmp cCallResult(Type type)
-{
- switch (type) {
- case Void:
- return Tmp();
- case Int32:
- case Int64:
- return Tmp(GPRInfo::returnValueGPR);
- case Float:
- case Double:
- return Tmp(FPRInfo::returnValueFPR);
- }
-
- RELEASE_ASSERT_NOT_REACHED();
- return Tmp();
-}
-
-Inst buildCCall(Code& code, Value* origin, const Vector<Arg>& arguments)
-{
- Inst inst(Patch, origin, Arg::special(code.cCallSpecial()));
- inst.args.append(arguments[0]);
- inst.args.append(Tmp(GPRInfo::returnValueGPR));
- inst.args.append(Tmp(GPRInfo::returnValueGPR2));
- inst.args.append(Tmp(FPRInfo::returnValueFPR));
- for (unsigned i = 1; i < arguments.size(); ++i) {
- Arg arg = arguments[i];
- if (arg.isTmp())
- inst.args.append(arg);
- }
- return inst;
-}
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCCallingConventionh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirCCallingConvention.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCCallingConvention.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirCCallingConvention.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,55 +0,0 @@
</span><del>-/*
- * 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 AirCCallingConvention_h
-#define AirCCallingConvention_h
-
-#if ENABLE(B3_JIT)
-
-#include "AirArg.h"
-#include "AirInst.h"
-#include "B3Type.h"
-#include <wtf/Vector.h>
-
-namespace JSC { namespace B3 {
-
-class CCallValue;
-
-namespace Air {
-
-class Code;
-
-Vector<Arg> computeCCallingConvention(Code&, CCallValue*);
-
-Tmp cCallResult(Type);
-
-Inst buildCCall(Code&, Value* origin, const Vector<Arg>&);
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
-#endif // AirCCallingConvention_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirCode.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCode.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirCode.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -60,13 +60,12 @@
</span><span class="cx">
</span><span class="cx"> Procedure& proc() { return m_proc; }
</span><span class="cx">
</span><del>- JS_EXPORT_PRIVATE BasicBlock* addBlock(double frequency = 1);
</del><ins>+ BasicBlock* addBlock(double frequency = 1);
</ins><span class="cx">
</span><span class="cx"> // Note that you can rely on stack slots always getting indices that are larger than the index
</span><span class="cx"> // of any prior stack slot. In fact, all stack slots you create in the future will have an index
</span><span class="cx"> // that is >= stackSlots().size().
</span><del>- JS_EXPORT_PRIVATE StackSlot* addStackSlot(
- unsigned byteSize, StackSlotKind, StackSlotValue* = nullptr);
</del><ins>+ StackSlot* addStackSlot(unsigned byteSize, StackSlotKind, StackSlotValue* = nullptr);
</ins><span class="cx"> StackSlot* addStackSlot(StackSlotValue*);
</span><span class="cx">
</span><span class="cx"> Special* addSpecial(std::unique_ptr<Special>);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCustomcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirCustom.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCustom.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirCustom.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,160 +0,0 @@
</span><del>-/*
- * 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 "config.h"
-#include "AirCustom.h"
-
-#if ENABLE(B3_JIT)
-
-#include "B3CCallValue.h"
-#include "B3ValueInlines.h"
-
-namespace JSC { namespace B3 { namespace Air {
-
-bool CCallCustom::isValidForm(Inst& inst)
-{
- CCallValue* value = inst.origin->as<CCallValue>();
- if (!value)
- return false;
-
- if (inst.args.size() != (value->type() == Void ? 0 : 1) + value->numChildren())
- return false;
-
- // The arguments can only refer to the stack, tmps, or immediates.
- for (Arg& arg : inst.args) {
- if (!arg.isTmp() && !arg.isStackMemory() && !arg.isSomeImm())
- return false;
- }
-
- unsigned offset = 0;
-
- if (!inst.args[0].isGP())
- return false;
-
- // If there is a result then it cannot be an immediate.
- if (value->type() != Void) {
- if (inst.args[1].isSomeImm())
- return false;
- if (!inst.args[1].canRepresent(value))
- return false;
- offset++;
- }
-
- for (unsigned i = value->numChildren(); i-- > 1;) {
- Value* child = value->child(i);
- Arg arg = inst.args[offset + i];
- if (!arg.canRepresent(child))
- return false;
- }
-
- return true;
-}
-
-CCallHelpers::Jump CCallCustom::generate(Inst& inst, CCallHelpers&, GenerationContext&)
-{
- dataLog("FATAL: Unlowered C call: ", inst, "\n");
- UNREACHABLE_FOR_PLATFORM();
- return CCallHelpers::Jump();
-}
-
-bool ShuffleCustom::isValidForm(Inst& inst)
-{
- if (inst.args.size() % 3)
- return false;
-
- // A destination may only appear once. This requirement allows us to avoid the undefined behavior
- // of having a destination that is supposed to get multiple inputs simultaneously. It also
- // imposes some interesting constraints on the "shape" of the shuffle. If we treat a shuffle pair
- // as an edge and the Args as nodes, then the single-destination requirement means that the
- // shuffle graph consists of two kinds of subgraphs:
- //
- // - Spanning trees. We call these shifts. They can be executed as a sequence of Move
- // instructions and don't usually require scratch registers.
- //
- // - Closed loops. These loops consist of nodes that have one successor and one predecessor, so
- // there is no way to "get into" the loop from outside of it. These can be executed using swaps
- // or by saving one of the Args to a scratch register and executing it as a shift.
- HashSet<Arg> dsts;
-
- for (unsigned i = 0; i < inst.args.size(); ++i) {
- Arg arg = inst.args[i];
- unsigned mode = i % 3;
-
- if (mode == 2) {
- // It's the width.
- if (!arg.isWidthArg())
- return false;
- continue;
- }
-
- // The source can be an immediate.
- if (!mode) {
- if (arg.isSomeImm())
- continue;
-
- if (!arg.isCompatibleType(inst.args[i + 1]))
- return false;
- } else {
- ASSERT(mode == 1);
- if (!dsts.add(arg).isNewEntry)
- return false;
- }
-
- if (arg.isTmp() || arg.isMemory())
- continue;
-
- return false;
- }
-
- // No destination register may appear in any address expressions. The lowering can't handle it
- // and it's not useful for the way we end up using Shuffles. Normally, Shuffles only used for
- // stack addresses and non-stack registers.
- for (Arg& arg : inst.args) {
- if (!arg.isMemory())
- continue;
- bool ok = true;
- arg.forEachTmpFast(
- [&] (Tmp tmp) {
- if (dsts.contains(tmp))
- ok = false;
- });
- if (!ok)
- return false;
- }
-
- return true;
-}
-
-CCallHelpers::Jump ShuffleCustom::generate(Inst& inst, CCallHelpers&, GenerationContext&)
-{
- dataLog("FATAL: Unlowered shuffle: ", inst, "\n");
- UNREACHABLE_FOR_PLATFORM();
- return CCallHelpers::Jump();
-}
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCustomh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirCustom.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCustom.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirCustom.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -30,7 +30,6 @@
</span><span class="cx">
</span><span class="cx"> #include "AirInst.h"
</span><span class="cx"> #include "AirSpecial.h"
</span><del>-#include "B3Value.h"
</del><span class="cx">
</span><span class="cx"> namespace JSC { namespace B3 { namespace Air {
</span><span class="cx">
</span><span class="lines">@@ -52,8 +51,6 @@
</span><span class="cx"> // you need to carry extra state around with the instruction. Also, Specials mean that you
</span><span class="cx"> // always have access to Code& even in methods that don't take a GenerationContext.
</span><span class="cx">
</span><del>-// Definition of Patch instruction. Patch is used to delegate the behavior of the instruction to the
-// Special object, which will be the first argument to the instruction.
</del><span class="cx"> struct PatchCustom {
</span><span class="cx"> template<typename Functor>
</span><span class="cx"> static void forEachArg(Inst& inst, const Functor& functor)
</span><span class="lines">@@ -99,114 +96,6 @@
</span><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx">
</span><del>-// Definition of CCall instruction. CCall is used for hot path C function calls. It's lowered to a
-// Patch with an Air CCallSpecial along with code to marshal instructions. The lowering happens
-// before register allocation, so that the register allocator sees the clobbers.
-struct CCallCustom {
- template<typename Functor>
- static void forEachArg(Inst& inst, const Functor& functor)
- {
- Value* value = inst.origin;
-
- unsigned index = 0;
-
- functor(inst.args[index++], Arg::Use, Arg::GP, Arg::pointerWidth()); // callee
-
- if (value->type() != Void) {
- functor(
- inst.args[index++], Arg::Def,
- Arg::typeForB3Type(value->type()),
- Arg::widthForB3Type(value->type()));
- }
-
- for (unsigned i = 1; i < value->numChildren(); ++i) {
- Value* child = value->child(i);
- functor(
- inst.args[index++], Arg::Use,
- Arg::typeForB3Type(child->type()),
- Arg::widthForB3Type(child->type()));
- }
- }
-
- template<typename... Arguments>
- static bool isValidFormStatic(Arguments...)
- {
- return false;
- }
-
- static bool isValidForm(Inst&);
-
- static bool admitsStack(Inst&, unsigned)
- {
- return true;
- }
-
- static bool hasNonArgNonControlEffects(Inst&)
- {
- return true;
- }
-
- // This just crashes, since we expect C calls to be lowered before generation.
- static CCallHelpers::Jump generate(Inst&, CCallHelpers&, GenerationContext&);
-};
-
-struct ColdCCallCustom : CCallCustom {
- template<typename Functor>
- static void forEachArg(Inst& inst, const Functor& functor)
- {
- // This is just like a call, but uses become cold.
- CCallCustom::forEachArg(
- inst,
- [&] (Arg& arg, Arg::Role role, Arg::Type type, Arg::Width width) {
- functor(arg, Arg::cooled(role), type, width);
- });
- }
-};
-
-struct ShuffleCustom {
- template<typename Functor>
- static void forEachArg(Inst& inst, const Functor& functor)
- {
- unsigned limit = inst.args.size() / 3 * 3;
- for (unsigned i = 0; i < limit; i += 3) {
- Arg& src = inst.args[i + 0];
- Arg& dst = inst.args[i + 1];
- Arg& widthArg = inst.args[i + 2];
- Arg::Width width = widthArg.width();
- Arg::Type type = src.isGP() && dst.isGP() ? Arg::GP : Arg::FP;
- functor(src, Arg::Use, type, width);
- functor(dst, Arg::Def, type, width);
- functor(widthArg, Arg::Use, Arg::GP, Arg::Width8);
- }
- }
-
- template<typename... Arguments>
- static bool isValidFormStatic(Arguments...)
- {
- return false;
- }
-
- static bool isValidForm(Inst&);
-
- static bool admitsStack(Inst&, unsigned index)
- {
- switch (index % 3) {
- case 0:
- case 1:
- return true;
- default:
- return false;
- }
- }
-
- static bool hasNonArgNonControlEffects(Inst&)
- {
- return false;
- }
-
- static CCallHelpers::Jump generate(Inst&, CCallHelpers&, GenerationContext&);
-};
-
</del><span class="cx"> } } } // namespace JSC::B3::Air
</span><span class="cx">
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirEmitShufflecpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirEmitShuffle.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirEmitShuffle.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirEmitShuffle.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,520 +0,0 @@
</span><del>-/*
- * 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 "config.h"
-#include "AirEmitShuffle.h"
-
-#if ENABLE(B3_JIT)
-
-#include "AirInstInlines.h"
-#include "AirRegisterPriority.h"
-#include <wtf/GraphNodeWorklist.h>
-#include <wtf/ListDump.h>
-
-namespace JSC { namespace B3 { namespace Air {
-
-namespace {
-
-bool verbose = false;
-
-template<typename Functor>
-Tmp findPossibleScratch(Arg::Type type, const Functor& functor) {
- for (Reg reg : regsInPriorityOrder(type)) {
- Tmp tmp(reg);
- if (functor(tmp))
- return tmp;
- }
- return Tmp();
-}
-
-Tmp findPossibleScratch(Arg::Type type, const Arg& arg1, const Arg& arg2) {
- return findPossibleScratch(
- type,
- [&] (Tmp tmp) -> bool {
- return !arg1.usesTmp(tmp) && !arg2.usesTmp(tmp);
- });
-}
-
-// Example: (a => b, b => a, a => c, b => d)
-struct Rotate {
- Vector<ShufflePair> loop; // in the example, this is the loop: (a => b, b => a)
- Vector<ShufflePair> fringe; // in the example, these are the associated shifts: (a => c, b => d)
-};
-
-} // anonymous namespace
-
-void ShufflePair::dump(PrintStream& out) const
-{
- out.print(width(), ":", src(), "=>", dst());
-}
-
-Vector<Inst> emitShuffle(
- Vector<ShufflePair> pairs, std::array<Arg, 2> scratches, Arg::Type type, Value* origin)
-{
- pairs.removeAllMatching(
- [&] (const ShufflePair& pair) -> bool {
- return pair.src() == pair.dst();
- });
-
- // First validate that this is the kind of shuffle that we know how to deal with.
-#if !ASSERT_DISABLED
- for (const ShufflePair& pair : pairs) {
- ASSERT(pair.src().isType(type));
- ASSERT(pair.dst().isType(type));
- ASSERT(pair.dst().isTmp() || pair.dst().isMemory());
- }
-#endif // !ASSERT_DISABLED
-
- // There are two possible kinds of operations that we will do:
- //
- // - Shift. Example: (a => b, b => c). We emit this as "Move b, c; Move a, b". This only requires
- // scratch registers if there are memory->memory moves. We want to find as many of these as
- // possible because they are cheaper. Note that shifts can involve the same source mentioned
- // multiple times. Example: (a => b, a => c, b => d, b => e).
- //
- // - Rotate. Example: (a => b, b => a). We want to emit this as "Swap a, b", but that instruction
- // may not be available, in which case we may need a scratch register or a scratch memory
- // location. A gnarlier example is (a => b, b => c, c => a). We can emit this as "Swap b, c;
- // Swap a, b". Note that swapping has to be careful about differing widths.
- //
- // Note that a rotate can have "fringe". For example, we might have (a => b, b => a, a =>c,
- // b => d). This has a rotate loop (a => b, b => a) and some fringe (a => c, b => d). We treat
- // the whole thing as a single rotate.
- //
- // We will find multiple disjoint such operations. We can execute them in any order.
-
- // We interpret these as Moves that should be executed backwards. All shifts are keyed by their
- // starting source.
- HashMap<Arg, Vector<ShufflePair>> shifts;
-
- // We interpret these as Swaps over src()'s that should be executed backwards, i.e. for a list
- // of size 3 we would do "Swap list[1].src(), list[2].src(); Swap list[0].src(), list[1].src()".
- // Note that we actually can't do that if the widths don't match or other bad things happen.
- // But, prior to executing all of that, we need to execute the fringe: the shifts comming off the
- // rotate.
- Vector<Rotate> rotates;
-
- {
- HashMap<Arg, Vector<ShufflePair>> mapping;
- for (const ShufflePair& pair : pairs)
- mapping.add(pair.src(), Vector<ShufflePair>()).iterator->value.append(pair);
-
- Vector<ShufflePair> currentPairs;
-
- while (!mapping.isEmpty()) {
- ASSERT(currentPairs.isEmpty());
- Arg originalSrc = mapping.begin()->key;
- ASSERT(!shifts.contains(originalSrc));
- if (verbose)
- dataLog("Processing from ", originalSrc, "\n");
-
- GraphNodeWorklist<Arg> worklist;
- worklist.push(originalSrc);
- while (Arg src = worklist.pop()) {
- HashMap<Arg, Vector<ShufflePair>>::iterator iter = mapping.find(src);
- if (iter == mapping.end()) {
- // With a shift it's possible that we previously built the tail of this shift.
- // See if that's the case now.
- if (verbose)
- dataLog("Trying to append shift at ", src, "\n");
- currentPairs.appendVector(shifts.take(src));
- continue;
- }
- Vector<ShufflePair> pairs = WTFMove(iter->value);
- mapping.remove(iter);
-
- for (const ShufflePair& pair : pairs) {
- currentPairs.append(pair);
- ASSERT(pair.src() == src);
- worklist.push(pair.dst());
- }
- }
-
- ASSERT(currentPairs.size());
- ASSERT(currentPairs[0].src() == originalSrc);
-
- if (verbose)
- dataLog("currentPairs = ", listDump(currentPairs), "\n");
-
- bool isRotate = false;
- for (const ShufflePair& pair : currentPairs) {
- if (pair.dst() == originalSrc) {
- isRotate = true;
- break;
- }
- }
-
- if (isRotate) {
- if (verbose)
- dataLog("It's a rotate.\n");
- Rotate rotate;
-
- // The common case is that the rotate does not have fringe. When this happens, the
- // last destination is the first source.
- if (currentPairs.last().dst() == originalSrc)
- rotate.loop = WTFMove(currentPairs);
- else {
- // This is the slow path. The rotate has fringe.
-
- HashMap<Arg, ShufflePair> dstMapping;
- for (const ShufflePair& pair : currentPairs)
- dstMapping.add(pair.dst(), pair);
-
- ShufflePair pair = dstMapping.take(originalSrc);
- for (;;) {
- rotate.loop.append(pair);
-
- auto iter = dstMapping.find(pair.src());
- if (iter == dstMapping.end())
- break;
- pair = iter->value;
- dstMapping.remove(iter);
- }
-
- rotate.loop.reverse();
-
- // Make sure that the fringe appears in the same order as how it appeared in the
- // currentPairs, since that's the DFS order.
- for (const ShufflePair& pair : currentPairs) {
- // But of course we only include it if it's not in the loop.
- if (dstMapping.contains(pair.dst()))
- rotate.fringe.append(pair);
- }
- }
-
- // If the graph search terminates because we returned to the first source, then the
- // pair list has to have a very particular shape.
- for (unsigned i = rotate.loop.size() - 1; i--;)
- ASSERT(rotate.loop[i].dst() == rotate.loop[i + 1].src());
- rotates.append(WTFMove(rotate));
- currentPairs.resize(0);
- } else {
- if (verbose)
- dataLog("It's a shift.\n");
- shifts.add(originalSrc, WTFMove(currentPairs));
- }
- }
- }
-
- if (verbose) {
- dataLog("Shifts:\n");
- for (auto& entry : shifts)
- dataLog(" ", entry.key, ": ", listDump(entry.value), "\n");
- dataLog("Rotates:\n");
- for (auto& rotate : rotates)
- dataLog(" loop = ", listDump(rotate.loop), ", fringe = ", listDump(rotate.fringe), "\n");
- }
-
- // In the worst case, we need two scratch registers. The way we do this is that the client passes
- // us what scratch registers he happens to have laying around. We will need scratch registers in
- // the following cases:
- //
- // - Shuffle pairs where both src and dst refer to memory.
- // - Rotate when no Swap instruction is available.
- //
- // Lucky for us, we are guaranteed to have extra scratch registers anytime we have a Shift that
- // ends with a register. We search for such a register right now.
-
- auto moveForWidth = [&] (Arg::Width width) -> Opcode {
- switch (width) {
- case Arg::Width32:
- return type == Arg::GP ? Move32 : MoveFloat;
- case Arg::Width64:
- return type == Arg::GP ? Move : MoveDouble;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- };
-
- Opcode conservativeMove = moveForWidth(Arg::conservativeWidth(type));
-
- // We will emit things in reverse. We maintain a list of packs of instructions, and then we emit
- // append them together in reverse (for example the thing at the end of resultPacks is placed
- // first). This is useful because the last thing we emit frees up its destination registers, so
- // it affects how we emit things before it.
- Vector<Vector<Inst>> resultPacks;
- Vector<Inst> result;
-
- auto commitResult = [&] () {
- resultPacks.append(WTFMove(result));
- };
-
- auto getScratch = [&] (unsigned index, Tmp possibleScratch) -> Tmp {
- if (scratches[index].isTmp())
- return scratches[index].tmp();
-
- if (!possibleScratch)
- return Tmp();
- result.append(Inst(conservativeMove, origin, possibleScratch, scratches[index]));
- return possibleScratch;
- };
-
- auto returnScratch = [&] (unsigned index, Tmp tmp) {
- if (Arg(tmp) != scratches[index])
- result.append(Inst(conservativeMove, origin, scratches[index], tmp));
- };
-
- auto handleShiftPair = [&] (const ShufflePair& pair, unsigned scratchIndex) {
- Opcode move = moveForWidth(pair.width());
-
- if (!isValidForm(move, pair.src().kind(), pair.dst().kind())) {
- Tmp scratch =
- getScratch(scratchIndex, findPossibleScratch(type, pair.src(), pair.dst()));
- RELEASE_ASSERT(scratch);
- if (isValidForm(move, pair.src().kind(), Arg::Tmp))
- result.append(Inst(moveForWidth(pair.width()), origin, pair.src(), scratch));
- else {
- ASSERT(pair.src().isSomeImm());
- ASSERT(move == Move32);
- result.append(Inst(Move, origin, Arg::imm64(pair.src().value()), scratch));
- }
- result.append(Inst(moveForWidth(pair.width()), origin, scratch, pair.dst()));
- returnScratch(scratchIndex, scratch);
- return;
- }
-
- result.append(Inst(move, origin, pair.src(), pair.dst()));
- };
-
- auto handleShift = [&] (Vector<ShufflePair>& shift) {
- // FIXME: We could optimize the spill behavior of the shifter by checking if any of the
- // shifts need spills. If they do, then we could try to get a register out here. Note that
- // this may fail where the current strategy succeeds: out here we need a register that does
- // not interfere with any of the shifts, while the current strategy only needs to find a
- // scratch register that does not interfer with a particular shift. So, this optimization
- // will be opportunistic: if it succeeds, then the individual shifts can use that scratch,
- // otherwise they will do what they do now.
-
- for (unsigned i = shift.size(); i--;)
- handleShiftPair(shift[i], 0);
-
- Arg lastDst = shift.last().dst();
- if (lastDst.isTmp()) {
- for (Arg& scratch : scratches) {
- ASSERT(scratch != lastDst);
- if (!scratch.isTmp()) {
- scratch = lastDst;
- break;
- }
- }
- }
- };
-
- // First handle shifts whose last destination is a tmp because these free up scratch registers.
- // These end up last in the final sequence, so the final destination of these shifts will be
- // available as a scratch location for anything emitted prior (so, after, since we're emitting in
- // reverse).
- for (auto& entry : shifts) {
- Vector<ShufflePair>& shift = entry.value;
- if (shift.last().dst().isTmp())
- handleShift(shift);
- commitResult();
- }
-
- // Now handle the rest of the shifts.
- for (auto& entry : shifts) {
- Vector<ShufflePair>& shift = entry.value;
- if (!shift.last().dst().isTmp())
- handleShift(shift);
- commitResult();
- }
-
- for (Rotate& rotate : rotates) {
- if (!rotate.fringe.isEmpty()) {
- // Make sure we do the fringe first! This won't clobber any of the registers that are
- // part of the rotation.
- handleShift(rotate.fringe);
- }
-
- bool canSwap = false;
- Opcode swap = Oops;
- Arg::Width swapWidth = Arg::Width8; // bogus value
-
- // Currently, the swap instruction is not available for floating point on any architecture we
- // support.
- if (type == Arg::GP) {
- // Figure out whether we will be doing 64-bit swaps or 32-bit swaps. If we have a mix of
- // widths we handle that by fixing up the relevant register with zero-extends.
- swap = Swap32;
- swapWidth = Arg::Width32;
- bool hasMemory = false;
- bool hasIndex = false;
- for (ShufflePair& pair : rotate.loop) {
- switch (pair.width()) {
- case Arg::Width32:
- break;
- case Arg::Width64:
- swap = Swap64;
- swapWidth = Arg::Width64;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- break;
- }
-
- hasMemory |= pair.src().isMemory() || pair.dst().isMemory();
- hasIndex |= pair.src().isIndex() || pair.dst().isIndex();
- }
-
- canSwap = isValidForm(swap, Arg::Tmp, Arg::Tmp);
-
- // We can totally use swaps even if there are shuffles involving memory. But, we play it
- // safe in that case. There are corner cases we don't handle, and our ability to do it is
- // contingent upon swap form availability.
-
- if (hasMemory) {
- canSwap &= isValidForm(swap, Arg::Tmp, Arg::Addr);
-
- // We don't take the swapping path if there is a mix of widths and some of the
- // shuffles involve memory. That gets too confusing. We might be able to relax this
- // to only bail if there are subwidth pairs involving memory, but I haven't thought
- // about it very hard. Anyway, this case is not common: rotates involving memory
- // don't arise for function calls, and they will only happen for rotates in user code
- // if some of the variables get spilled. It's hard to imagine a program that rotates
- // data around in variables while also doing a combination of uint32->uint64 and
- // int64->int32 casts.
- for (ShufflePair& pair : rotate.loop)
- canSwap &= pair.width() == swapWidth;
- }
-
- if (hasIndex)
- canSwap &= isValidForm(swap, Arg::Tmp, Arg::Index);
- }
-
- if (canSwap) {
- for (unsigned i = rotate.loop.size() - 1; i--;) {
- Arg left = rotate.loop[i].src();
- Arg right = rotate.loop[i + 1].src();
-
- if (left.isMemory() && right.isMemory()) {
- // Note that this is a super rare outcome. Rotates are rare. Spills are rare.
- // Moving data between two spills is rare. To get here a lot of rare stuff has to
- // all happen at once.
-
- Tmp scratch = getScratch(0, findPossibleScratch(type, left, right));
- RELEASE_ASSERT(scratch);
- result.append(Inst(moveForWidth(swapWidth), origin, left, scratch));
- result.append(Inst(swap, origin, scratch, right));
- result.append(Inst(moveForWidth(swapWidth), origin, scratch, left));
- returnScratch(0, scratch);
- continue;
- }
-
- if (left.isMemory())
- std::swap(left, right);
-
- result.append(Inst(swap, origin, left, right));
- }
-
- for (ShufflePair pair : rotate.loop) {
- if (pair.width() == swapWidth)
- continue;
-
- RELEASE_ASSERT(pair.width() == Arg::Width32);
- RELEASE_ASSERT(swapWidth == Arg::Width64);
- RELEASE_ASSERT(pair.dst().isTmp());
-
- // Need to do an extra zero extension.
- result.append(Inst(Move32, origin, pair.dst(), pair.dst()));
- }
- } else {
- // We can treat this as a shift so long as we take the last destination (i.e. first
- // source) and save it first. Then we handle the first entry in the pair in the rotate
- // specially, after we restore the last destination. This requires some special care to
- // find a scratch register. It's possible that we have a rotate that uses the entire
- // available register file.
-
- Tmp scratch = findPossibleScratch(
- type,
- [&] (Tmp tmp) -> bool {
- for (ShufflePair pair : rotate.loop) {
- if (pair.src().usesTmp(tmp))
- return false;
- if (pair.dst().usesTmp(tmp))
- return false;
- }
- return true;
- });
-
- // NOTE: This is the most likely use of scratch registers.
- scratch = getScratch(0, scratch);
-
- // We may not have found a scratch register. When this happens, we can just use the spill
- // slot directly.
- Arg rotateSave = scratch ? Arg(scratch) : scratches[0];
-
- handleShiftPair(
- ShufflePair(rotate.loop.last().dst(), rotateSave, rotate.loop[0].width()), 1);
-
- for (unsigned i = rotate.loop.size(); i-- > 1;)
- handleShiftPair(rotate.loop[i], 1);
-
- handleShiftPair(
- ShufflePair(rotateSave, rotate.loop[0].dst(), rotate.loop[0].width()), 1);
-
- if (scratch)
- returnScratch(0, scratch);
- }
-
- commitResult();
- }
-
- ASSERT(result.isEmpty());
-
- for (unsigned i = resultPacks.size(); i--;)
- result.appendVector(resultPacks[i]);
-
- return result;
-}
-
-Vector<Inst> emitShuffle(
- const Vector<ShufflePair>& pairs,
- const std::array<Arg, 2>& gpScratch, const std::array<Arg, 2>& fpScratch,
- Value* origin)
-{
- Vector<ShufflePair> gpPairs;
- Vector<ShufflePair> fpPairs;
- for (const ShufflePair& pair : pairs) {
- if (pair.src().isMemory() && pair.dst().isMemory() && pair.width() > Arg::pointerWidth()) {
- // 8-byte memory-to-memory moves on a 32-bit platform are best handled as float moves.
- fpPairs.append(pair);
- } else if (pair.src().isGP() && pair.dst().isGP()) {
- // This means that gpPairs gets memory-to-memory shuffles. The assumption is that we
- // can do that more efficiently using GPRs, except in the special case above.
- gpPairs.append(pair);
- } else
- fpPairs.append(pair);
- }
-
- Vector<Inst> result;
- result.appendVector(emitShuffle(gpPairs, gpScratch, Arg::GP, origin));
- result.appendVector(emitShuffle(fpPairs, fpScratch, Arg::FP, origin));
- return result;
-}
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirEmitShuffleh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirEmitShuffle.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirEmitShuffle.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirEmitShuffle.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,115 +0,0 @@
</span><del>-/*
- * 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 AirEmitShuffle_h
-#define AirEmitShuffle_h
-
-#if ENABLE(B3_JIT)
-
-#include "AirArg.h"
-#include "AirInst.h"
-#include <wtf/Vector.h>
-
-namespace JSC { namespace B3 {
-
-class Value;
-
-namespace Air {
-
-class ShufflePair {
-public:
- ShufflePair()
- {
- }
-
- ShufflePair(const Arg& src, const Arg& dst, Arg::Width width)
- : m_src(src)
- , m_dst(dst)
- , m_width(width)
- {
- }
-
- const Arg& src() const { return m_src; }
- const Arg& dst() const { return m_dst; }
-
- // The width determines the kind of move we do. You can only choose Width32 or Width64 right now.
- // For GP, it picks between Move32 and Move. For FP, it picks between MoveFloat and MoveDouble.
- Arg::Width width() const { return m_width; }
-
- void dump(PrintStream&) const;
-
-private:
- Arg m_src;
- Arg m_dst;
- Arg::Width m_width { Arg::Width8 };
-};
-
-// Perform a shuffle of a given type. The scratch argument is mandatory. You should pass it as
-// follows: If you know that you have scratch registers or temporaries available - that is, they're
-// registers that are not mentioned in the shuffle, have the same type as the shuffle, and are not
-// live at the shuffle - then you can pass them. If you don't have scratch registers available or if
-// you don't feel like looking for them, you can pass memory locations. It's always safe to pass a
-// pair of memory locations, and replacing either memory location with a register can be viewed as an
-// optimization. It's a pretty important optimization. Some more notes:
-//
-// - We define scratch registers as things that are not live before the shuffle and are not one of
-// the destinations of the shuffle. Not being live before the shuffle also means that they cannot
-// be used for any of the sources of the shuffle.
-//
-// - A second scratch location is only needed when you have shuffle pairs where memory is used both
-// as source and destination.
-//
-// - You're guaranteed not to need any scratch locations if there is a Swap instruction available for
-// the type and you don't have any memory locations that are both the source and the destination of
-// some pairs. GP supports Swap on x86 while FP never supports Swap.
-//
-// - Passing memory locations as scratch if are running emitShuffle() before register allocation is
-// silly, since that will cause emitShuffle() to pick some specific registers when it does need
-// scratch. One easy way to avoid that predicament is to ensure that you call emitShuffle() after
-// register allocation. For this reason we could add a Shuffle instruction so that we can defer
-// shufflings until after regalloc.
-//
-// - Shuffles with memory=>memory pairs are not very well tuned. You should avoid them if you want
-// performance. If you need to do them, then making sure that you reserve a temporary is one way to
-// get acceptable performance.
-//
-// NOTE: Use this method (and its friend below) to emit shuffles after register allocation. Before
-// register allocation it is much better to simply use the Shuffle instruction.
-Vector<Inst> emitShuffle(
- Vector<ShufflePair>, std::array<Arg, 2> scratch, Arg::Type, Value* origin);
-
-// Perform a shuffle that involves any number of types. Pass scratch registers or memory locations
-// for each type according to the rules above.
-Vector<Inst> emitShuffle(
- const Vector<ShufflePair>&,
- const std::array<Arg, 2>& gpScratch, const std::array<Arg, 2>& fpScratch,
- Value* origin);
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
-#endif // AirEmitShuffle_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirGeneratecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -35,8 +35,6 @@
</span><span class="cx"> #include "AirGenerationContext.h"
</span><span class="cx"> #include "AirHandleCalleeSaves.h"
</span><span class="cx"> #include "AirIteratedRegisterCoalescing.h"
</span><del>-#include "AirLowerAfterRegAlloc.h"
-#include "AirLowerMacros.h"
</del><span class="cx"> #include "AirOpcodeUtils.h"
</span><span class="cx"> #include "AirOptimizeBlockOrder.h"
</span><span class="cx"> #include "AirReportUsedRegisters.h"
</span><span class="lines">@@ -67,8 +65,6 @@
</span><span class="cx"> dataLog(code);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- lowerMacros(code);
-
</del><span class="cx"> // This is where we run our optimizations and transformations.
</span><span class="cx"> // FIXME: Add Air optimizations.
</span><span class="cx"> // https://bugs.webkit.org/show_bug.cgi?id=150456
</span><span class="lines">@@ -84,8 +80,6 @@
</span><span class="cx"> else
</span><span class="cx"> iteratedRegisterCoalescing(code);
</span><span class="cx">
</span><del>- lowerAfterRegAlloc(code);
-
</del><span class="cx"> // Prior to this point the prologue and epilogue is implicit. This makes it explicit. It also
</span><span class="cx"> // does things like identify which callee-saves we're using and saves them.
</span><span class="cx"> handleCalleeSaves(code);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirGenerateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirGenerate.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirGenerate.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirGenerate.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -38,11 +38,11 @@
</span><span class="cx">
</span><span class="cx"> // This takes an Air::Code that hasn't had any stack allocation and optionally hasn't had any
</span><span class="cx"> // register allocation and does both of those things.
</span><del>-JS_EXPORT_PRIVATE void prepareForGeneration(Code&);
</del><ins>+void prepareForGeneration(Code&);
</ins><span class="cx">
</span><span class="cx"> // This generates the code using the given CCallHelpers instance. Note that this may call callbacks
</span><span class="cx"> // in the supplied code as it is generating.
</span><del>-JS_EXPORT_PRIVATE void generate(Code&, CCallHelpers&);
</del><ins>+void generate(Code&, CCallHelpers&);
</ins><span class="cx">
</span><span class="cx"> } } } // namespace JSC::B3::Air
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirInsertionSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -33,18 +33,6 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC { namespace B3 { namespace Air {
</span><span class="cx">
</span><del>-void InsertionSet::insertInsts(size_t index, const Vector<Inst>& insts)
-{
- for (const Inst& inst : insts)
- insertInst(index, inst);
-}
-
-void InsertionSet::insertInsts(size_t index, Vector<Inst>&& insts)
-{
- for (Inst& inst : insts)
- insertInst(index, WTFMove(inst));
-}
-
</del><span class="cx"> void InsertionSet::execute(BasicBlock* block)
</span><span class="cx"> {
</span><span class="cx"> bubbleSort(m_insertions.begin(), m_insertions.end());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirInsertionSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirInsertionSet.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -59,9 +59,6 @@
</span><span class="cx"> {
</span><span class="cx"> appendInsertion(Insertion(index, std::forward<Inst>(inst)));
</span><span class="cx"> }
</span><del>-
- void insertInsts(size_t index, const Vector<Inst>&);
- void insertInsts(size_t index, Vector<Inst>&&);
</del><span class="cx">
</span><span class="cx"> template<typename... Arguments>
</span><span class="cx"> void insert(size_t index, Arguments&&... arguments)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirInsth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirInst.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirInst.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirInst.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -85,15 +85,6 @@
</span><span class="cx">
</span><span class="cx"> explicit operator bool() const { return origin || opcode != Nop || args.size(); }
</span><span class="cx">
</span><del>- void append() { }
-
- template<typename... Arguments>
- void append(Arg arg, Arguments... arguments)
- {
- args.append(arg);
- append(arguments...);
- }
-
</del><span class="cx"> // Note that these functors all avoid using "const" because we want to use them for things that
</span><span class="cx"> // edit IR. IR is meant to be edited; if you're carrying around a "const Inst&" then you're
</span><span class="cx"> // probably doing it wrong.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloccpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,242 +0,0 @@
</span><del>-/*
- * 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 "config.h"
-#include "AirLowerAfterRegAlloc.h"
-
-#if ENABLE(B3_JIT)
-
-#include "AirCCallingConvention.h"
-#include "AirCode.h"
-#include "AirEmitShuffle.h"
-#include "AirInsertionSet.h"
-#include "AirInstInlines.h"
-#include "AirLiveness.h"
-#include "AirPhaseScope.h"
-#include "AirRegisterPriority.h"
-#include "B3CCallValue.h"
-#include "B3ValueInlines.h"
-#include "RegisterSet.h"
-#include <wtf/HashMap.h>
-
-namespace JSC { namespace B3 { namespace Air {
-
-namespace {
-
-bool verbose = false;
-
-} // anonymous namespace
-
-void lowerAfterRegAlloc(Code& code)
-{
- PhaseScope phaseScope(code, "lowerAfterRegAlloc");
-
- if (verbose)
- dataLog("Code before lowerAfterRegAlloc:\n", code);
-
- HashMap<Inst*, RegisterSet> usedRegisters;
-
- RegLiveness liveness(code);
- for (BasicBlock* block : code) {
- RegLiveness::LocalCalc localCalc(liveness, block);
-
- for (unsigned instIndex = block->size(); instIndex--;) {
- Inst& inst = block->at(instIndex);
-
- RegisterSet set;
-
- bool isRelevant = inst.opcode == Shuffle || inst.opcode == ColdCCall;
-
- if (isRelevant) {
- for (Reg reg : localCalc.live())
- set.set(reg);
- }
-
- localCalc.execute(instIndex);
-
- if (isRelevant)
- usedRegisters.add(&inst, set);
- }
- }
-
- auto getScratches = [&] (RegisterSet set, Arg::Type type) -> std::array<Arg, 2> {
- std::array<Arg, 2> result;
- for (unsigned i = 0; i < 2; ++i) {
- bool found = false;
- for (Reg reg : regsInPriorityOrder(type)) {
- if (!set.get(reg)) {
- result[i] = Tmp(reg);
- set.set(reg);
- found = true;
- break;
- }
- }
- if (!found) {
- result[i] = Arg::stack(
- code.addStackSlot(
- Arg::bytes(Arg::conservativeWidth(type)),
- StackSlotKind::Anonymous));
- }
- }
- return result;
- };
-
- // Now transform the code.
- InsertionSet insertionSet(code);
- for (BasicBlock* block : code) {
- for (unsigned instIndex = 0; instIndex < block->size(); ++instIndex) {
- Inst& inst = block->at(instIndex);
-
- switch (inst.opcode) {
- case Shuffle: {
- RegisterSet set = usedRegisters.get(&inst);
- Vector<ShufflePair> pairs;
- for (unsigned i = 0; i < inst.args.size(); i += 3) {
- Arg src = inst.args[i + 0];
- Arg dst = inst.args[i + 1];
- Arg::Width width = inst.args[i + 2].width();
-
- // The used register set contains things live after the shuffle. But
- // emitShuffle() wants a scratch register that is not just dead but also does not
- // interfere with either sources or destinations.
- auto excludeRegisters = [&] (Tmp tmp) {
- if (tmp.isReg())
- set.set(tmp.reg());
- };
- src.forEachTmpFast(excludeRegisters);
- dst.forEachTmpFast(excludeRegisters);
-
- pairs.append(ShufflePair(src, dst, width));
- }
- std::array<Arg, 2> gpScratch = getScratches(set, Arg::GP);
- std::array<Arg, 2> fpScratch = getScratches(set, Arg::FP);
- insertionSet.insertInsts(
- instIndex, emitShuffle(pairs, gpScratch, fpScratch, inst.origin));
- inst = Inst();
- break;
- }
-
- case ColdCCall: {
- CCallValue* value = inst.origin->as<CCallValue>();
-
- RegisterSet liveRegs = usedRegisters.get(&inst);
- RegisterSet regsToSave = liveRegs;
- regsToSave.exclude(RegisterSet::calleeSaveRegisters());
- regsToSave.exclude(RegisterSet::stackRegisters());
- regsToSave.exclude(RegisterSet::reservedHardwareRegisters());
-
- RegisterSet preUsed = regsToSave;
- Vector<Arg> destinations = computeCCallingConvention(code, value);
- Tmp result = cCallResult(value->type());
- Arg originalResult = result ? inst.args[1] : Arg();
-
- Vector<ShufflePair> pairs;
- for (unsigned i = 0; i < destinations.size(); ++i) {
- Value* child = value->child(i);
- Arg src = inst.args[result ? (i >= 1 ? i + 1 : i) : i ];
- Arg dst = destinations[i];
- Arg::Width width = Arg::widthForB3Type(child->type());
- pairs.append(ShufflePair(src, dst, width));
-
- auto excludeRegisters = [&] (Tmp tmp) {
- if (tmp.isReg())
- preUsed.set(tmp.reg());
- };
- src.forEachTmpFast(excludeRegisters);
- dst.forEachTmpFast(excludeRegisters);
- }
-
- std::array<Arg, 2> gpScratch = getScratches(preUsed, Arg::GP);
- std::array<Arg, 2> fpScratch = getScratches(preUsed, Arg::FP);
-
- // Also need to save all live registers. Don't need to worry about the result
- // register.
- if (originalResult.isReg())
- regsToSave.clear(originalResult.reg());
- Vector<StackSlot*> stackSlots;
- regsToSave.forEach(
- [&] (Reg reg) {
- Tmp tmp(reg);
- Arg arg(tmp);
- Arg::Width width = Arg::conservativeWidth(arg.type());
- StackSlot* stackSlot =
- code.addStackSlot(Arg::bytes(width), StackSlotKind::Anonymous);
- pairs.append(ShufflePair(arg, Arg::stack(stackSlot), width));
- stackSlots.append(stackSlot);
- });
-
- if (verbose)
- dataLog("Pre-call pairs for ", inst, ": ", listDump(pairs), "\n");
-
- insertionSet.insertInsts(
- instIndex, emitShuffle(pairs, gpScratch, fpScratch, inst.origin));
-
- inst = buildCCall(code, inst.origin, destinations);
-
- // Now we need to emit code to restore registers.
- pairs.resize(0);
- unsigned stackSlotIndex = 0;
- regsToSave.forEach(
- [&] (Reg reg) {
- Tmp tmp(reg);
- Arg arg(tmp);
- Arg::Width width = Arg::conservativeWidth(arg.type());
- StackSlot* stackSlot = stackSlots[stackSlotIndex++];
- pairs.append(ShufflePair(Arg::stack(stackSlot), arg, width));
- });
- if (result) {
- ShufflePair pair(result, originalResult, Arg::widthForB3Type(value->type()));
- pairs.append(pair);
- }
-
- gpScratch = getScratches(liveRegs, Arg::GP);
- fpScratch = getScratches(liveRegs, Arg::FP);
-
- insertionSet.insertInsts(
- instIndex + 1, emitShuffle(pairs, gpScratch, fpScratch, inst.origin));
- break;
- }
-
- default:
- break;
- }
- }
-
- insertionSet.execute(block);
-
- block->insts().removeAllMatching(
- [&] (Inst& inst) -> bool {
- return !inst;
- });
- }
-
- if (verbose)
- dataLog("Code after lowerAfterRegAlloc:\n", code);
-}
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerAfterRegAlloch"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerAfterRegAlloc.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,44 +0,0 @@
</span><del>-/*
- * 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 AirLowerAfterRegAlloc_h
-#define AirLowerAfterRegAlloc_h
-
-#if ENABLE(B3_JIT)
-
-namespace JSC { namespace B3 { namespace Air {
-
-class Code;
-
-// This lowers Shuffle and ColdCCall instructions. This phase is designed to be run after register
-// allocation.
-
-void lowerAfterRegAlloc(Code&);
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
-#endif // AirLowerAfterRegAlloc_h
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerMacroscpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,105 +0,0 @@
</span><del>-/*
- * 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 "config.h"
-#include "AirLowerMacros.h"
-
-#if ENABLE(B3_JIT)
-
-#include "AirCCallingConvention.h"
-#include "AirCode.h"
-#include "AirInsertionSet.h"
-#include "AirInstInlines.h"
-#include "AirPhaseScope.h"
-#include "B3CCallValue.h"
-#include "B3ValueInlines.h"
-
-namespace JSC { namespace B3 { namespace Air {
-
-void lowerMacros(Code& code)
-{
- PhaseScope phaseScope(code, "lowerMacros");
-
- InsertionSet insertionSet(code);
- for (BasicBlock* block : code) {
- for (unsigned instIndex = 0; instIndex < block->size(); ++instIndex) {
- Inst& inst = block->at(instIndex);
-
- switch (inst.opcode) {
- case CCall: {
- CCallValue* value = inst.origin->as<CCallValue>();
-
- Vector<Arg> destinations = computeCCallingConvention(code, value);
-
- Inst shuffleArguments(Shuffle, value);
- unsigned offset = value->type() == Void ? 0 : 1;
- for (unsigned i = 1; i < destinations.size(); ++i) {
- Value* child = value->child(i);
- shuffleArguments.args.append(inst.args[offset + i]);
- shuffleArguments.args.append(destinations[i]);
- shuffleArguments.args.append(Arg::widthArg(Arg::widthForB3Type(child->type())));
- }
- insertionSet.insertInst(instIndex, WTFMove(shuffleArguments));
-
- // Indicate that we're using our original callee argument.
- destinations[0] = inst.args[0];
-
- // Save where the original instruction put its result.
- Arg resultDst = value->type() == Void ? Arg() : inst.args[1];
-
- inst = buildCCall(code, inst.origin, destinations);
-
- Tmp result = cCallResult(value->type());
- switch (value->type()) {
- case Void:
- break;
- case Float:
- insertionSet.insert(instIndex + 1, MoveFloat, value, result, resultDst);
- break;
- case Double:
- insertionSet.insert(instIndex + 1, MoveDouble, value, result, resultDst);
- break;
- case Int32:
- insertionSet.insert(instIndex + 1, Move32, value, result, resultDst);
- break;
- case Int64:
- insertionSet.insert(instIndex + 1, Move, value, result, resultDst);
- break;
- }
- break;
- }
-
- default:
- break;
- }
- }
- insertionSet.execute(block);
- }
-}
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirLowerMacrosh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirLowerMacros.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,45 +0,0 @@
</span><del>-/*
- * 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 AirLowerMacros_h
-#define AirLowerMacros_h
-
-#if ENABLE(B3_JIT)
-
-namespace JSC { namespace B3 { namespace Air {
-
-class Code;
-
-// Air has some opcodes that are very high-level and are meant to reduce the amount of low-level
-// knowledge in the B3->Air lowering. The current example is CCall.
-
-void lowerMacros(Code&);
-
-} } } // namespace JSC::B3::Air
-
-#endif // ENABLE(B3_JIT)
-
-#endif // AirLowerMacros_h
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirOpcodeopcodes"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -417,14 +417,6 @@
</span><span class="cx"> Tmp, Index as storePtr
</span><span class="cx"> x86: Imm, Addr as storePtr
</span><span class="cx">
</span><del>-x86: Swap32 UD:G:32, UD:G:32
- Tmp, Tmp
- Tmp, Addr
-
-x86_64: Swap64 UD:G:64, UD:G:64
- Tmp, Tmp
- Tmp, Addr
-
</del><span class="cx"> Move32 U:G:32, ZD:G:32
</span><span class="cx"> Tmp, Tmp as zeroExtend32ToPtr
</span><span class="cx"> Addr, Tmp as load32
</span><span class="lines">@@ -690,19 +682,7 @@
</span><span class="cx">
</span><span class="cx"> Oops /terminal
</span><span class="cx">
</span><del>-# A Shuffle is a multi-source, multi-destination move. It simultaneously does multiple moves at once.
-# The moves are specified as triplets of src, dst, and width. For example you can request a swap this
-# way:
-# Shuffle %tmp1, %tmp2, 64, %tmp2, %tmp1, 64
-custom Shuffle
-
</del><span class="cx"> # Air allows for exotic behavior. A Patch's behavior is determined entirely by the Special operand,
</span><span class="cx"> # which must be the first operand.
</span><span class="cx"> custom Patch
</span><span class="cx">
</span><del>-# Instructions used for lowering C calls. These don't make it to Air generation. They get lowered to
-# something else first. The origin Value must be a CCallValue.
-custom CCall
-custom ColdCCall
-
-
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirRegisterPriorityh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirRegisterPriority.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirRegisterPriority.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/AirRegisterPriority.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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">@@ -52,7 +52,7 @@
</span><span class="cx"> return RegistersInPriorityOrder<Bank>::inPriorityOrder();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-JS_EXPORT_PRIVATE const Vector<Reg>& regsInPriorityOrder(Arg::Type);
</del><ins>+const Vector<Reg>& regsInPriorityOrder(Arg::Type);
</ins><span class="cx">
</span><span class="cx"> } } } // namespace JSC::B3::Air
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airtestaircpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/b3/air/testair.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/testair.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/air/testair.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,1707 +0,0 @@
</span><del>-/*
- * 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 "config.h"
-
-#include "AirCode.h"
-#include "AirGenerate.h"
-#include "AirInstInlines.h"
-#include "AirRegisterPriority.h"
-#include "AllowMacroScratchRegisterUsage.h"
-#include "B3Compilation.h"
-#include "B3Procedure.h"
-#include "CCallHelpers.h"
-#include "InitializeThreading.h"
-#include "JSCInlines.h"
-#include "LinkBuffer.h"
-#include "PureNaN.h"
-#include "VM.h"
-#include <cmath>
-#include <map>
-#include <string>
-#include <wtf/Lock.h>
-#include <wtf/NumberOfCores.h>
-#include <wtf/Threading.h>
-
-// We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
-static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
-
-static void usage()
-{
- dataLog("Usage: testb3 [<filter>]\n");
- if (hiddenTruthBecauseNoReturnIsStupid())
- exit(1);
-}
-
-#if ENABLE(B3_JIT)
-
-using namespace JSC;
-using namespace JSC::B3::Air;
-
-namespace {
-
-StaticLock crashLock;
-
-// Nothing fancy for now; we just use the existing WTF assertion machinery.
-#define CHECK(x) do { \
- if (!!(x)) \
- break; \
- crashLock.lock(); \
- WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
- CRASH(); \
- } while (false)
-
-VM* vm;
-
-std::unique_ptr<B3::Compilation> compile(B3::Procedure& proc)
-{
- prepareForGeneration(proc.code());
- CCallHelpers jit(vm);
- generate(proc.code(), jit);
- LinkBuffer linkBuffer(*vm, jit, nullptr);
-
- return std::make_unique<B3::Compilation>(
- FINALIZE_CODE(linkBuffer, ("testair compilation")), proc.releaseByproducts());
-}
-
-template<typename T, typename... Arguments>
-T invoke(const B3::Compilation& code, Arguments... arguments)
-{
- T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(code.code().executableAddress());
- return function(arguments...);
-}
-
-template<typename T, typename... Arguments>
-T compileAndRun(B3::Procedure& procedure, Arguments... arguments)
-{
- return invoke<T>(*compile(procedure), arguments...);
-}
-
-void testSimple()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- root->append(Move, nullptr, Arg::imm(42), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(compileAndRun<int>(proc) == 42);
-}
-
-// Use this to put a constant into a register without Air being able to see the constant.
-template<typename T>
-void loadConstantImpl(BasicBlock* block, T value, B3::Air::Opcode move, Tmp tmp, Tmp scratch)
-{
- static StaticLock lock;
- static std::map<T, T*>* map; // I'm not messing with HashMap's problems with integers.
-
- LockHolder locker(lock);
- if (!map)
- map = new std::map<T, T*>();
-
- if (!map->count(value))
- (*map)[value] = new T(value);
-
- T* ptr = (*map)[value];
- block->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(ptr)), scratch);
- block->append(move, nullptr, Arg::addr(scratch), tmp);
-}
-
-void loadConstant(BasicBlock* block, intptr_t value, Tmp tmp)
-{
- loadConstantImpl<intptr_t>(block, value, Move, tmp, tmp);
-}
-
-void loadDoubleConstant(BasicBlock* block, double value, Tmp tmp, Tmp scratch)
-{
- loadConstantImpl<double>(block, value, MoveDouble, tmp, scratch);
-}
-
-void testShuffleSimpleSwap()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32));
-
- int32_t things[4];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 2);
- CHECK(things[2] == 4);
- CHECK(things[3] == 3);
-}
-
-void testShuffleSimpleShift()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32));
-
- int32_t things[5];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 2);
- CHECK(things[2] == 3);
- CHECK(things[3] == 3);
- CHECK(things[4] == 4);
-}
-
-void testShuffleLongShift()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- loadConstant(root, 7, Tmp(GPRInfo::regT6));
- loadConstant(root, 8, Tmp(GPRInfo::regT7));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT4), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT5), Tmp(GPRInfo::regT6), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT6), Tmp(GPRInfo::regT7), Arg::widthArg(Arg::Width32));
-
- int32_t things[8];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT6), Arg::addr(base, 6 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT7), Arg::addr(base, 7 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 1);
- CHECK(things[2] == 2);
- CHECK(things[3] == 3);
- CHECK(things[4] == 4);
- CHECK(things[5] == 5);
- CHECK(things[6] == 6);
- CHECK(things[7] == 7);
-}
-
-void testShuffleLongShiftBackwards()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- loadConstant(root, 7, Tmp(GPRInfo::regT6));
- loadConstant(root, 8, Tmp(GPRInfo::regT7));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT6), Tmp(GPRInfo::regT7), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT5), Tmp(GPRInfo::regT6), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT4), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32));
-
- int32_t things[8];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT6), Arg::addr(base, 6 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT7), Arg::addr(base, 7 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 1);
- CHECK(things[2] == 2);
- CHECK(things[3] == 3);
- CHECK(things[4] == 4);
- CHECK(things[5] == 5);
- CHECK(things[6] == 6);
- CHECK(things[7] == 7);
-}
-
-void testShuffleSimpleRotate()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT0), Arg::widthArg(Arg::Width32));
-
- int32_t things[4];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 3);
- CHECK(things[1] == 1);
- CHECK(things[2] == 2);
- CHECK(things[3] == 4);
-}
-
-void testShuffleSimpleBroadcast()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32));
-
- int32_t things[4];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 1);
- CHECK(things[2] == 1);
- CHECK(things[3] == 1);
-}
-
-void testShuffleBroadcastAllRegs()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- const Vector<Reg>& regs = regsInPriorityOrder(Arg::GP);
-
- BasicBlock* root = code.addBlock();
- root->append(Move, nullptr, Arg::imm(35), Tmp(GPRInfo::regT0));
- unsigned count = 1;
- for (Reg reg : regs) {
- if (reg != Reg(GPRInfo::regT0))
- loadConstant(root, count++, Tmp(reg));
- }
- Inst& shuffle = root->append(Shuffle, nullptr);
- for (Reg reg : regs) {
- if (reg != Reg(GPRInfo::regT0))
- shuffle.append(Tmp(GPRInfo::regT0), Tmp(reg), Arg::widthArg(Arg::Width32));
- }
-
- StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), B3::StackSlotKind::Locked);
- for (unsigned i = 0; i < regs.size(); ++i)
- root->append(Move32, nullptr, Tmp(regs[i]), Arg::stack(slot, i * sizeof(int32_t)));
-
- Vector<int32_t> things(regs.size(), 666);
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things[0])), base);
- for (unsigned i = 0; i < regs.size(); ++i) {
- root->append(Move32, nullptr, Arg::stack(slot, i * sizeof(int32_t)), Tmp(GPRInfo::regT0));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, i * sizeof(int32_t)));
- }
-
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(!compileAndRun<int>(proc));
-
- for (int32_t thing : things)
- CHECK(thing == 35);
-}
-
-void testShuffleTreeShift()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- loadConstant(root, 7, Tmp(GPRInfo::regT6));
- loadConstant(root, 8, Tmp(GPRInfo::regT7));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT6), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT7), Arg::widthArg(Arg::Width32));
-
- int32_t things[8];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT6), Arg::addr(base, 6 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT7), Arg::addr(base, 7 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 1);
- CHECK(things[2] == 1);
- CHECK(things[3] == 2);
- CHECK(things[4] == 2);
- CHECK(things[5] == 3);
- CHECK(things[6] == 3);
- CHECK(things[7] == 4);
-}
-
-void testShuffleTreeShiftBackward()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- loadConstant(root, 7, Tmp(GPRInfo::regT6));
- loadConstant(root, 8, Tmp(GPRInfo::regT7));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT7), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT6), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32));
-
- int32_t things[8];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT6), Arg::addr(base, 6 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT7), Arg::addr(base, 7 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 1);
- CHECK(things[2] == 1);
- CHECK(things[3] == 2);
- CHECK(things[4] == 2);
- CHECK(things[5] == 3);
- CHECK(things[6] == 3);
- CHECK(things[7] == 4);
-}
-
-void testShuffleTreeShiftOtherBackward()
-{
- // NOTE: This test was my original attempt at TreeShiftBackward but mistakes were made. So, this
- // ends up being just a weird test. But weird tests are useful, so I kept it.
-
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- loadConstant(root, 7, Tmp(GPRInfo::regT6));
- loadConstant(root, 8, Tmp(GPRInfo::regT7));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT4), Tmp(GPRInfo::regT7), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT5), Tmp(GPRInfo::regT6), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT5), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT6), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT6), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT7), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT7), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32));
-
- int32_t things[8];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT6), Arg::addr(base, 6 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT7), Arg::addr(base, 7 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 8);
- CHECK(things[2] == 8);
- CHECK(things[3] == 7);
- CHECK(things[4] == 7);
- CHECK(things[5] == 6);
- CHECK(things[6] == 6);
- CHECK(things[7] == 5);
-}
-
-void testShuffleMultipleShifts()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32));
-
- int32_t things[6];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 1);
- CHECK(things[2] == 3);
- CHECK(things[3] == 3);
- CHECK(things[4] == 3);
- CHECK(things[5] == 1);
-}
-
-void testShuffleRotateWithFringe()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT0), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32));
-
- int32_t things[6];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 3);
- CHECK(things[1] == 1);
- CHECK(things[2] == 2);
- CHECK(things[3] == 1);
- CHECK(things[4] == 2);
- CHECK(things[5] == 3);
-}
-
-void testShuffleRotateWithLongFringe()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT0), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT4), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32));
-
- int32_t things[6];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 3);
- CHECK(things[1] == 1);
- CHECK(things[2] == 2);
- CHECK(things[3] == 1);
- CHECK(things[4] == 4);
- CHECK(things[5] == 5);
-}
-
-void testShuffleMultipleRotates()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT0), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT4), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT5), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32));
-
- int32_t things[6];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 3);
- CHECK(things[1] == 1);
- CHECK(things[2] == 2);
- CHECK(things[3] == 6);
- CHECK(things[4] == 4);
- CHECK(things[5] == 5);
-}
-
-void testShuffleShiftAndRotate()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- loadConstant(root, 4, Tmp(GPRInfo::regT3));
- loadConstant(root, 5, Tmp(GPRInfo::regT4));
- loadConstant(root, 6, Tmp(GPRInfo::regT5));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT1), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT0), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT4), Tmp(GPRInfo::regT5), Arg::widthArg(Arg::Width32));
-
- int32_t things[6];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT5), Arg::addr(base, 5 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 3);
- CHECK(things[1] == 1);
- CHECK(things[2] == 2);
- CHECK(things[3] == 4);
- CHECK(things[4] == 4);
- CHECK(things[5] == 5);
-}
-
-void testShuffleShiftAllRegs()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- const Vector<Reg>& regs = regsInPriorityOrder(Arg::GP);
-
- BasicBlock* root = code.addBlock();
- for (unsigned i = 0; i < regs.size(); ++i)
- loadConstant(root, 35 + i, Tmp(regs[i]));
- Inst& shuffle = root->append(Shuffle, nullptr);
- for (unsigned i = 1; i < regs.size(); ++i)
- shuffle.append(Tmp(regs[i - 1]), Tmp(regs[i]), Arg::widthArg(Arg::Width32));
-
- StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), B3::StackSlotKind::Locked);
- for (unsigned i = 0; i < regs.size(); ++i)
- root->append(Move32, nullptr, Tmp(regs[i]), Arg::stack(slot, i * sizeof(int32_t)));
-
- Vector<int32_t> things(regs.size(), 666);
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things[0])), base);
- for (unsigned i = 0; i < regs.size(); ++i) {
- root->append(Move32, nullptr, Arg::stack(slot, i * sizeof(int32_t)), Tmp(GPRInfo::regT0));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, i * sizeof(int32_t)));
- }
-
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 35);
- for (unsigned i = 1; i < regs.size(); ++i)
- CHECK(things[i] == 35 + static_cast<int32_t>(i) - 1);
-}
-
-void testShuffleRotateAllRegs()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- const Vector<Reg>& regs = regsInPriorityOrder(Arg::GP);
-
- BasicBlock* root = code.addBlock();
- for (unsigned i = 0; i < regs.size(); ++i)
- loadConstant(root, 35 + i, Tmp(regs[i]));
- Inst& shuffle = root->append(Shuffle, nullptr);
- for (unsigned i = 1; i < regs.size(); ++i)
- shuffle.append(Tmp(regs[i - 1]), Tmp(regs[i]), Arg::widthArg(Arg::Width32));
- shuffle.append(Tmp(regs.last()), Tmp(regs[0]), Arg::widthArg(Arg::Width32));
-
- StackSlot* slot = code.addStackSlot(sizeof(int32_t) * regs.size(), B3::StackSlotKind::Locked);
- for (unsigned i = 0; i < regs.size(); ++i)
- root->append(Move32, nullptr, Tmp(regs[i]), Arg::stack(slot, i * sizeof(int32_t)));
-
- Vector<int32_t> things(regs.size(), 666);
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things[0])), base);
- for (unsigned i = 0; i < regs.size(); ++i) {
- root->append(Move32, nullptr, Arg::stack(slot, i * sizeof(int32_t)), Tmp(GPRInfo::regT0));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, i * sizeof(int32_t)));
- }
-
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 35 + static_cast<int32_t>(regs.size()) - 1);
- for (unsigned i = 1; i < regs.size(); ++i)
- CHECK(things[i] == 35 + static_cast<int32_t>(i) - 1);
-}
-
-void testShuffleSimpleSwap64()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 10000000000000000ll, Tmp(GPRInfo::regT0));
- loadConstant(root, 20000000000000000ll, Tmp(GPRInfo::regT1));
- loadConstant(root, 30000000000000000ll, Tmp(GPRInfo::regT2));
- loadConstant(root, 40000000000000000ll, Tmp(GPRInfo::regT3));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width64),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width64));
-
- int64_t things[4];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int64_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 10000000000000000ll);
- CHECK(things[1] == 20000000000000000ll);
- CHECK(things[2] == 40000000000000000ll);
- CHECK(things[3] == 30000000000000000ll);
-}
-
-void testShuffleSimpleShift64()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 10000000000000000ll, Tmp(GPRInfo::regT0));
- loadConstant(root, 20000000000000000ll, Tmp(GPRInfo::regT1));
- loadConstant(root, 30000000000000000ll, Tmp(GPRInfo::regT2));
- loadConstant(root, 40000000000000000ll, Tmp(GPRInfo::regT3));
- loadConstant(root, 50000000000000000ll, Tmp(GPRInfo::regT4));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width64),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width64));
-
- int64_t things[5];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int64_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 10000000000000000ll);
- CHECK(things[1] == 20000000000000000ll);
- CHECK(things[2] == 30000000000000000ll);
- CHECK(things[3] == 30000000000000000ll);
- CHECK(things[4] == 40000000000000000ll);
-}
-
-void testShuffleSwapMixedWidth()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 10000000000000000ll, Tmp(GPRInfo::regT0));
- loadConstant(root, 20000000000000000ll, Tmp(GPRInfo::regT1));
- loadConstant(root, 30000000000000000ll, Tmp(GPRInfo::regT2));
- loadConstant(root, 40000000000000000ll, Tmp(GPRInfo::regT3));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width32),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT2), Arg::widthArg(Arg::Width64));
-
- int64_t things[4];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int64_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 10000000000000000ll);
- CHECK(things[1] == 20000000000000000ll);
- CHECK(things[2] == 40000000000000000ll);
- CHECK(things[3] == static_cast<uint32_t>(30000000000000000ll));
-}
-
-void testShuffleShiftMixedWidth()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 10000000000000000ll, Tmp(GPRInfo::regT0));
- loadConstant(root, 20000000000000000ll, Tmp(GPRInfo::regT1));
- loadConstant(root, 30000000000000000ll, Tmp(GPRInfo::regT2));
- loadConstant(root, 40000000000000000ll, Tmp(GPRInfo::regT3));
- loadConstant(root, 50000000000000000ll, Tmp(GPRInfo::regT4));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT2), Tmp(GPRInfo::regT3), Arg::widthArg(Arg::Width64),
- Tmp(GPRInfo::regT3), Tmp(GPRInfo::regT4), Arg::widthArg(Arg::Width32));
-
- int64_t things[5];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT3), Arg::addr(base, 3 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT4), Arg::addr(base, 4 * sizeof(int64_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 10000000000000000ll);
- CHECK(things[1] == 20000000000000000ll);
- CHECK(things[2] == 30000000000000000ll);
- CHECK(things[3] == 30000000000000000ll);
- CHECK(things[4] == static_cast<uint32_t>(40000000000000000ll));
-}
-
-void testShuffleShiftMemory()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int32_t memory[2];
- memory[0] = 35;
- memory[1] = 36;
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT2));
- root->append(
- Shuffle, nullptr,
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
- Arg::addr(Tmp(GPRInfo::regT2), 0 * sizeof(int32_t)),
- Arg::addr(Tmp(GPRInfo::regT2), 1 * sizeof(int32_t)), Arg::widthArg(Arg::Width32));
-
- int32_t things[2];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 1);
- CHECK(memory[0] == 35);
- CHECK(memory[1] == 35);
-}
-
-void testShuffleShiftMemoryLong()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int32_t memory[2];
- memory[0] = 35;
- memory[1] = 36;
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- loadConstant(root, 3, Tmp(GPRInfo::regT2));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT3));
- root->append(
- Shuffle, nullptr,
-
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
-
- Tmp(GPRInfo::regT1), Arg::addr(Tmp(GPRInfo::regT3), 0 * sizeof(int32_t)),
- Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT3), 0 * sizeof(int32_t)),
- Arg::addr(Tmp(GPRInfo::regT3), 1 * sizeof(int32_t)), Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT3), 1 * sizeof(int32_t)), Tmp(GPRInfo::regT2),
- Arg::widthArg(Arg::Width32));
-
- int32_t things[3];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT2), Arg::addr(base, 2 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 1);
- CHECK(things[2] == 36);
- CHECK(memory[0] == 2);
- CHECK(memory[1] == 35);
-}
-
-void testShuffleShiftMemoryAllRegs()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int32_t memory[2];
- memory[0] = 35;
- memory[1] = 36;
-
- Vector<Reg> regs = regsInPriorityOrder(Arg::GP);
- regs.removeFirst(Reg(GPRInfo::regT0));
-
- BasicBlock* root = code.addBlock();
- for (unsigned i = 0; i < regs.size(); ++i)
- loadConstant(root, i + 1, Tmp(regs[i]));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT0));
- Inst& shuffle = root->append(
- Shuffle, nullptr,
-
- Tmp(regs[0]), Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int32_t)),
- Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int32_t)),
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int32_t)), Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int32_t)), Tmp(regs[1]),
- Arg::widthArg(Arg::Width32));
-
- for (unsigned i = 2; i < regs.size(); ++i)
- shuffle.append(Tmp(regs[i - 1]), Tmp(regs[i]), Arg::widthArg(Arg::Width32));
-
- Vector<int32_t> things(regs.size(), 666);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things[0])), Tmp(GPRInfo::regT0));
- for (unsigned i = 0; i < regs.size(); ++i) {
- root->append(
- Move32, nullptr, Tmp(regs[i]), Arg::addr(Tmp(GPRInfo::regT0), i * sizeof(int32_t)));
- }
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 36);
- for (unsigned i = 2; i < regs.size(); ++i)
- CHECK(things[i] == static_cast<int32_t>(i));
- CHECK(memory[0] == 1);
- CHECK(memory[1] == 35);
-}
-
-void testShuffleShiftMemoryAllRegs64()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int64_t memory[2];
- memory[0] = 35000000000000ll;
- memory[1] = 36000000000000ll;
-
- Vector<Reg> regs = regsInPriorityOrder(Arg::GP);
- regs.removeFirst(Reg(GPRInfo::regT0));
-
- BasicBlock* root = code.addBlock();
- for (unsigned i = 0; i < regs.size(); ++i)
- loadConstant(root, (i + 1) * 1000000000000ll, Tmp(regs[i]));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT0));
- Inst& shuffle = root->append(
- Shuffle, nullptr,
-
- Tmp(regs[0]), Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int64_t)),
- Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int64_t)),
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int64_t)), Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int64_t)), Tmp(regs[1]),
- Arg::widthArg(Arg::Width64));
-
- for (unsigned i = 2; i < regs.size(); ++i)
- shuffle.append(Tmp(regs[i - 1]), Tmp(regs[i]), Arg::widthArg(Arg::Width64));
-
- Vector<int64_t> things(regs.size(), 666);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things[0])), Tmp(GPRInfo::regT0));
- for (unsigned i = 0; i < regs.size(); ++i) {
- root->append(
- Move, nullptr, Tmp(regs[i]), Arg::addr(Tmp(GPRInfo::regT0), i * sizeof(int64_t)));
- }
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1000000000000ll);
- CHECK(things[1] == 36000000000000ll);
- for (unsigned i = 2; i < regs.size(); ++i)
- CHECK(things[i] == static_cast<int64_t>(i) * 1000000000000ll);
- CHECK(memory[0] == 1000000000000ll);
- CHECK(memory[1] == 35000000000000ll);
-}
-
-int64_t combineHiLo(int64_t high, int64_t low)
-{
- union {
- int64_t value;
- int32_t halves[2];
- } u;
- u.value = high;
- u.halves[0] = static_cast<int32_t>(low);
- return u.value;
-}
-
-void testShuffleShiftMemoryAllRegsMixedWidth()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int64_t memory[2];
- memory[0] = 35000000000000ll;
- memory[1] = 36000000000000ll;
-
- Vector<Reg> regs = regsInPriorityOrder(Arg::GP);
- regs.removeFirst(Reg(GPRInfo::regT0));
-
- BasicBlock* root = code.addBlock();
- for (unsigned i = 0; i < regs.size(); ++i)
- loadConstant(root, (i + 1) * 1000000000000ll, Tmp(regs[i]));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT0));
- Inst& shuffle = root->append(
- Shuffle, nullptr,
-
- Tmp(regs[0]), Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int64_t)),
- Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int64_t)),
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int64_t)), Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int64_t)), Tmp(regs[1]),
- Arg::widthArg(Arg::Width32));
-
- for (unsigned i = 2; i < regs.size(); ++i) {
- shuffle.append(
- Tmp(regs[i - 1]), Tmp(regs[i]),
- (i & 1) ? Arg::widthArg(Arg::Width32) : Arg::widthArg(Arg::Width64));
- }
-
- Vector<int64_t> things(regs.size(), 666);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things[0])), Tmp(GPRInfo::regT0));
- for (unsigned i = 0; i < regs.size(); ++i) {
- root->append(
- Move, nullptr, Tmp(regs[i]), Arg::addr(Tmp(GPRInfo::regT0), i * sizeof(int64_t)));
- }
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1000000000000ll);
- CHECK(things[1] == static_cast<uint32_t>(36000000000000ll));
- for (unsigned i = 2; i < regs.size(); ++i) {
- int64_t value = static_cast<int64_t>(i) * 1000000000000ll;
- CHECK(things[i] == ((i & 1) ? static_cast<uint32_t>(value) : value));
- }
- CHECK(memory[0] == combineHiLo(35000000000000ll, 1000000000000ll));
- CHECK(memory[1] == 35000000000000ll);
-}
-
-void testShuffleRotateMemory()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int32_t memory[2];
- memory[0] = 35;
- memory[1] = 36;
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1, Tmp(GPRInfo::regT0));
- loadConstant(root, 2, Tmp(GPRInfo::regT1));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT2));
- root->append(
- Shuffle, nullptr,
-
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
-
- Tmp(GPRInfo::regT1), Arg::addr(Tmp(GPRInfo::regT2), 0 * sizeof(int32_t)),
- Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT2), 0 * sizeof(int32_t)),
- Arg::addr(Tmp(GPRInfo::regT2), 1 * sizeof(int32_t)), Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT2), 1 * sizeof(int32_t)), Tmp(GPRInfo::regT0),
- Arg::widthArg(Arg::Width32));
-
- int32_t things[2];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move32, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int32_t)));
- root->append(Move32, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int32_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 36);
- CHECK(things[1] == 1);
- CHECK(memory[0] == 2);
- CHECK(memory[1] == 35);
-}
-
-void testShuffleRotateMemory64()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int64_t memory[2];
- memory[0] = 35000000000000ll;
- memory[1] = 36000000000000ll;
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1000000000000ll, Tmp(GPRInfo::regT0));
- loadConstant(root, 2000000000000ll, Tmp(GPRInfo::regT1));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT2));
- root->append(
- Shuffle, nullptr,
-
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width64),
-
- Tmp(GPRInfo::regT1), Arg::addr(Tmp(GPRInfo::regT2), 0 * sizeof(int64_t)),
- Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT2), 0 * sizeof(int64_t)),
- Arg::addr(Tmp(GPRInfo::regT2), 1 * sizeof(int64_t)), Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT2), 1 * sizeof(int64_t)), Tmp(GPRInfo::regT0),
- Arg::widthArg(Arg::Width64));
-
- int64_t things[2];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int64_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 36000000000000ll);
- CHECK(things[1] == 1000000000000ll);
- CHECK(memory[0] == 2000000000000ll);
- CHECK(memory[1] == 35000000000000ll);
-}
-
-void testShuffleRotateMemoryMixedWidth()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int64_t memory[2];
- memory[0] = 35000000000000ll;
- memory[1] = 36000000000000ll;
-
- BasicBlock* root = code.addBlock();
- loadConstant(root, 1000000000000ll, Tmp(GPRInfo::regT0));
- loadConstant(root, 2000000000000ll, Tmp(GPRInfo::regT1));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT2));
- root->append(
- Shuffle, nullptr,
-
- Tmp(GPRInfo::regT0), Tmp(GPRInfo::regT1), Arg::widthArg(Arg::Width32),
-
- Tmp(GPRInfo::regT1), Arg::addr(Tmp(GPRInfo::regT2), 0 * sizeof(int64_t)),
- Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT2), 0 * sizeof(int64_t)),
- Arg::addr(Tmp(GPRInfo::regT2), 1 * sizeof(int64_t)), Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT2), 1 * sizeof(int64_t)), Tmp(GPRInfo::regT0),
- Arg::widthArg(Arg::Width64));
-
- int64_t things[2];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(Move, nullptr, Tmp(GPRInfo::regT0), Arg::addr(base, 0 * sizeof(int64_t)));
- root->append(Move, nullptr, Tmp(GPRInfo::regT1), Arg::addr(base, 1 * sizeof(int64_t)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 36000000000000ll);
- CHECK(things[1] == static_cast<uint32_t>(1000000000000ll));
- CHECK(memory[0] == 2000000000000ll);
- CHECK(memory[1] == combineHiLo(36000000000000ll, 35000000000000ll));
-}
-
-void testShuffleRotateMemoryAllRegs64()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int64_t memory[2];
- memory[0] = 35000000000000ll;
- memory[1] = 36000000000000ll;
-
- Vector<Reg> regs = regsInPriorityOrder(Arg::GP);
- regs.removeFirst(Reg(GPRInfo::regT0));
-
- BasicBlock* root = code.addBlock();
- for (unsigned i = 0; i < regs.size(); ++i)
- loadConstant(root, (i + 1) * 1000000000000ll, Tmp(regs[i]));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT0));
- Inst& shuffle = root->append(
- Shuffle, nullptr,
-
- Tmp(regs[0]), Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int64_t)),
- Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int64_t)),
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int64_t)), Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int64_t)), Tmp(regs[1]),
- Arg::widthArg(Arg::Width64),
-
- regs.last(), regs[0], Arg::widthArg(Arg::Width64));
-
- for (unsigned i = 2; i < regs.size(); ++i)
- shuffle.append(Tmp(regs[i - 1]), Tmp(regs[i]), Arg::widthArg(Arg::Width64));
-
- Vector<int64_t> things(regs.size(), 666);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things[0])), Tmp(GPRInfo::regT0));
- for (unsigned i = 0; i < regs.size(); ++i) {
- root->append(
- Move, nullptr, Tmp(regs[i]), Arg::addr(Tmp(GPRInfo::regT0), i * sizeof(int64_t)));
- }
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == static_cast<int64_t>(regs.size()) * 1000000000000ll);
- CHECK(things[1] == 36000000000000ll);
- for (unsigned i = 2; i < regs.size(); ++i)
- CHECK(things[i] == static_cast<int64_t>(i) * 1000000000000ll);
- CHECK(memory[0] == 1000000000000ll);
- CHECK(memory[1] == 35000000000000ll);
-}
-
-void testShuffleRotateMemoryAllRegsMixedWidth()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- int64_t memory[2];
- memory[0] = 35000000000000ll;
- memory[1] = 36000000000000ll;
-
- Vector<Reg> regs = regsInPriorityOrder(Arg::GP);
- regs.removeFirst(Reg(GPRInfo::regT0));
-
- BasicBlock* root = code.addBlock();
- for (unsigned i = 0; i < regs.size(); ++i)
- loadConstant(root, (i + 1) * 1000000000000ll, Tmp(regs[i]));
- root->append(Move, nullptr, Arg::immPtr(&memory), Tmp(GPRInfo::regT0));
- Inst& shuffle = root->append(
- Shuffle, nullptr,
-
- Tmp(regs[0]), Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int64_t)),
- Arg::widthArg(Arg::Width32),
-
- Arg::addr(Tmp(GPRInfo::regT0), 0 * sizeof(int64_t)),
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int64_t)), Arg::widthArg(Arg::Width64),
-
- Arg::addr(Tmp(GPRInfo::regT0), 1 * sizeof(int64_t)), Tmp(regs[1]),
- Arg::widthArg(Arg::Width32),
-
- regs.last(), regs[0], Arg::widthArg(Arg::Width32));
-
- for (unsigned i = 2; i < regs.size(); ++i)
- shuffle.append(Tmp(regs[i - 1]), Tmp(regs[i]), Arg::widthArg(Arg::Width64));
-
- Vector<int64_t> things(regs.size(), 666);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things[0])), Tmp(GPRInfo::regT0));
- for (unsigned i = 0; i < regs.size(); ++i) {
- root->append(
- Move, nullptr, Tmp(regs[i]), Arg::addr(Tmp(GPRInfo::regT0), i * sizeof(int64_t)));
- }
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == static_cast<uint32_t>(static_cast<int64_t>(regs.size()) * 1000000000000ll));
- CHECK(things[1] == static_cast<uint32_t>(36000000000000ll));
- for (unsigned i = 2; i < regs.size(); ++i)
- CHECK(things[i] == static_cast<int64_t>(i) * 1000000000000ll);
- CHECK(memory[0] == combineHiLo(35000000000000ll, 1000000000000ll));
- CHECK(memory[1] == 35000000000000ll);
-}
-
-void testShuffleSwapDouble()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadDoubleConstant(root, 1, Tmp(FPRInfo::fpRegT0), Tmp(GPRInfo::regT0));
- loadDoubleConstant(root, 2, Tmp(FPRInfo::fpRegT1), Tmp(GPRInfo::regT0));
- loadDoubleConstant(root, 3, Tmp(FPRInfo::fpRegT2), Tmp(GPRInfo::regT0));
- loadDoubleConstant(root, 4, Tmp(FPRInfo::fpRegT3), Tmp(GPRInfo::regT0));
- root->append(
- Shuffle, nullptr,
- Tmp(FPRInfo::fpRegT2), Tmp(FPRInfo::fpRegT3), Arg::widthArg(Arg::Width64),
- Tmp(FPRInfo::fpRegT3), Tmp(FPRInfo::fpRegT2), Arg::widthArg(Arg::Width64));
-
- double things[4];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(MoveDouble, nullptr, Tmp(FPRInfo::fpRegT0), Arg::addr(base, 0 * sizeof(double)));
- root->append(MoveDouble, nullptr, Tmp(FPRInfo::fpRegT1), Arg::addr(base, 1 * sizeof(double)));
- root->append(MoveDouble, nullptr, Tmp(FPRInfo::fpRegT2), Arg::addr(base, 2 * sizeof(double)));
- root->append(MoveDouble, nullptr, Tmp(FPRInfo::fpRegT3), Arg::addr(base, 3 * sizeof(double)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 2);
- CHECK(things[2] == 4);
- CHECK(things[3] == 3);
-}
-
-void testShuffleShiftDouble()
-{
- B3::Procedure proc;
- Code& code = proc.code();
-
- BasicBlock* root = code.addBlock();
- loadDoubleConstant(root, 1, Tmp(FPRInfo::fpRegT0), Tmp(GPRInfo::regT0));
- loadDoubleConstant(root, 2, Tmp(FPRInfo::fpRegT1), Tmp(GPRInfo::regT0));
- loadDoubleConstant(root, 3, Tmp(FPRInfo::fpRegT2), Tmp(GPRInfo::regT0));
- loadDoubleConstant(root, 4, Tmp(FPRInfo::fpRegT3), Tmp(GPRInfo::regT0));
- root->append(
- Shuffle, nullptr,
- Tmp(FPRInfo::fpRegT2), Tmp(FPRInfo::fpRegT3), Arg::widthArg(Arg::Width64));
-
- double things[4];
- Tmp base = code.newTmp(Arg::GP);
- root->append(Move, nullptr, Arg::imm64(bitwise_cast<intptr_t>(&things)), base);
- root->append(MoveDouble, nullptr, Tmp(FPRInfo::fpRegT0), Arg::addr(base, 0 * sizeof(double)));
- root->append(MoveDouble, nullptr, Tmp(FPRInfo::fpRegT1), Arg::addr(base, 1 * sizeof(double)));
- root->append(MoveDouble, nullptr, Tmp(FPRInfo::fpRegT2), Arg::addr(base, 2 * sizeof(double)));
- root->append(MoveDouble, nullptr, Tmp(FPRInfo::fpRegT3), Arg::addr(base, 3 * sizeof(double)));
- root->append(Move, nullptr, Arg::imm(0), Tmp(GPRInfo::returnValueGPR));
- root->append(Ret32, nullptr, Tmp(GPRInfo::returnValueGPR));
-
- memset(things, 0, sizeof(things));
-
- CHECK(!compileAndRun<int>(proc));
-
- CHECK(things[0] == 1);
- CHECK(things[1] == 2);
- CHECK(things[2] == 3);
- CHECK(things[3] == 3);
-}
-
-#define RUN(test) do { \
- if (!shouldRun(#test)) \
- break; \
- tasks.append( \
- createSharedTask<void()>( \
- [&] () { \
- dataLog(#test "...\n"); \
- test; \
- dataLog(#test ": OK!\n"); \
- })); \
- } while (false);
-
-void run(const char* filter)
-{
- JSC::initializeThreading();
- vm = &VM::create(LargeHeap).leakRef();
-
- Deque<RefPtr<SharedTask<void()>>> tasks;
-
- auto shouldRun = [&] (const char* testName) -> bool {
- return !filter || !!strcasestr(testName, filter);
- };
-
- RUN(testSimple());
-
- RUN(testShuffleSimpleSwap());
- RUN(testShuffleSimpleShift());
- RUN(testShuffleLongShift());
- RUN(testShuffleLongShiftBackwards());
- RUN(testShuffleSimpleRotate());
- RUN(testShuffleSimpleBroadcast());
- RUN(testShuffleBroadcastAllRegs());
- RUN(testShuffleTreeShift());
- RUN(testShuffleTreeShiftBackward());
- RUN(testShuffleTreeShiftOtherBackward());
- RUN(testShuffleMultipleShifts());
- RUN(testShuffleRotateWithFringe());
- RUN(testShuffleRotateWithLongFringe());
- RUN(testShuffleMultipleRotates());
- RUN(testShuffleShiftAndRotate());
- RUN(testShuffleShiftAllRegs());
- RUN(testShuffleRotateAllRegs());
- RUN(testShuffleSimpleSwap64());
- RUN(testShuffleSimpleShift64());
- RUN(testShuffleSwapMixedWidth());
- RUN(testShuffleShiftMixedWidth());
- RUN(testShuffleShiftMemory());
- RUN(testShuffleShiftMemoryLong());
- RUN(testShuffleShiftMemoryAllRegs());
- RUN(testShuffleShiftMemoryAllRegs64());
- RUN(testShuffleShiftMemoryAllRegsMixedWidth());
- RUN(testShuffleRotateMemory());
- RUN(testShuffleRotateMemory64());
- RUN(testShuffleRotateMemoryMixedWidth());
- RUN(testShuffleRotateMemoryAllRegs64());
- RUN(testShuffleRotateMemoryAllRegsMixedWidth());
- RUN(testShuffleSwapDouble());
- RUN(testShuffleShiftDouble());
-
- if (tasks.isEmpty())
- usage();
-
- Lock lock;
-
- Vector<ThreadIdentifier> threads;
- for (unsigned i = filter ? 1 : WTF::numberOfProcessorCores(); i--;) {
- threads.append(
- createThread(
- "testb3 thread",
- [&] () {
- for (;;) {
- RefPtr<SharedTask<void()>> task;
- {
- LockHolder locker(lock);
- if (tasks.isEmpty())
- return;
- task = tasks.takeFirst();
- }
-
- task->run();
- }
- }));
- }
-
- for (ThreadIdentifier thread : threads)
- waitForThreadCompletion(thread);
- crashLock.lock();
-}
-
-} // anonymois namespace
-
-#else // ENABLE(B3_JIT)
-
-static void run(const char*)
-{
- dataLog("B3 JIT is not enabled.\n");
-}
-
-#endif // ENABLE(B3_JIT)
-
-int main(int argc, char** argv)
-{
- const char* filter = nullptr;
- switch (argc) {
- case 1:
- break;
- case 2:
- filter = argv[1];
- break;
- default:
- usage();
- break;
- }
-
- run(filter);
- return 0;
-}
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -7775,65 +7775,6 @@
</span><span class="cx"> CHECK(compileAndRun<int>(proc, a, b) == a + b);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void testCallRare(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* common = proc.addBlock();
- BasicBlock* rare = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- FrequentedBlock(rare, FrequencyClass::Rare),
- FrequentedBlock(common));
-
- common->appendNew<ControlValue>(
- proc, Return, Origin(), common->appendNew<Const32Value>(proc, Origin(), 0));
-
- rare->appendNew<ControlValue>(
- proc, Return, Origin(),
- rare->appendNew<CCallValue>(
- proc, Int32, Origin(),
- rare->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
-
- CHECK(compileAndRun<int>(proc, true, a, b) == a + b);
-}
-
-void testCallRareLive(int a, int b, int c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* common = proc.addBlock();
- BasicBlock* rare = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- FrequentedBlock(rare, FrequencyClass::Rare),
- FrequentedBlock(common));
-
- common->appendNew<ControlValue>(
- proc, Return, Origin(), common->appendNew<Const32Value>(proc, Origin(), 0));
-
- rare->appendNew<ControlValue>(
- proc, Return, Origin(),
- rare->appendNew<Value>(
- proc, Add, Origin(),
- rare->appendNew<CCallValue>(
- proc, Int32, Origin(),
- rare->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)),
- rare->appendNew<Value>(
- proc, Trunc, Origin(),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3))));
-
- CHECK(compileAndRun<int>(proc, true, a, b, c) == a + b + c);
-}
-
</del><span class="cx"> void testCallSimplePure(int a, int b)
</span><span class="cx"> {
</span><span class="cx"> Procedure proc;
</span><span class="lines">@@ -10128,8 +10069,6 @@
</span><span class="cx"> RUN(testInt32ToDoublePartialRegisterWithoutStall());
</span><span class="cx">
</span><span class="cx"> RUN(testCallSimple(1, 2));
</span><del>- RUN(testCallRare(1, 2));
- RUN(testCallRareLive(1, 2, 3));
</del><span class="cx"> RUN(testCallSimplePure(1, 2));
</span><span class="cx"> RUN(testCallFunctionWithHellaArguments());
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -3540,7 +3540,7 @@
</span><span class="cx"> m_out.branch(
</span><span class="cx"> m_out.aboveOrEqual(
</span><span class="cx"> prevLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength)),
</span><del>- unsure(slowPath), unsure(fastPath));
</del><ins>+ rarely(slowPath), usually(fastPath));
</ins><span class="cx">
</span><span class="cx"> LBasicBlock lastNext = m_out.appendTo(fastPath, slowPath);
</span><span class="cx"> m_out.store(
</span><span class="lines">@@ -8225,7 +8225,7 @@
</span><span class="cx"> LBasicBlock holeCase =
</span><span class="cx"> FTL_NEW_BLOCK(m_out, ("PutByVal hole case"));
</span><span class="cx">
</span><del>- m_out.branch(isOutOfBounds, rarely(outOfBoundsCase), usually(holeCase));
</del><ins>+ m_out.branch(isOutOfBounds, unsure(outOfBoundsCase), unsure(holeCase));
</ins><span class="cx">
</span><span class="cx"> LBasicBlock innerLastNext = m_out.appendTo(outOfBoundsCase, holeCase);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -73,7 +73,7 @@
</span><span class="cx"> {
</span><span class="cx"> RefPtr<OSRExitHandle> handle =
</span><span class="cx"> prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset, isExceptionHandler);
</span><del>- handle->emitExitThunk(state, jit);
</del><ins>+ handle->emitExitThunk(jit);
</ins><span class="cx"> return handle;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -84,8 +84,8 @@
</span><span class="cx"> RefPtr<OSRExitHandle> handle =
</span><span class="cx"> prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset, isExceptionHandler);
</span><span class="cx"> params.addLatePath(
</span><del>- [handle, &state] (CCallHelpers& jit) {
- handle->emitExitThunk(state, jit);
</del><ins>+ [handle] (CCallHelpers& jit) {
+ handle->emitExitThunk(jit);
</ins><span class="cx"> });
</span><span class="cx"> return handle;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitHandlecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.cpp (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.cpp        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.cpp        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015 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,30 +29,24 @@
</span><span class="cx"> #if ENABLE(FTL_JIT) && FTL_USES_B3
</span><span class="cx">
</span><span class="cx"> #include "FTLOSRExit.h"
</span><del>-#include "FTLState.h"
</del><span class="cx"> #include "FTLThunks.h"
</span><span class="cx"> #include "LinkBuffer.h"
</span><del>-#include "ProfilerCompilation.h"
</del><span class="cx">
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx">
</span><del>-void OSRExitHandle::emitExitThunk(State& state, CCallHelpers& jit)
</del><ins>+void OSRExitHandle::emitExitThunk(CCallHelpers& jit)
</ins><span class="cx"> {
</span><del>- Profiler::Compilation* compilation = state.graph.compilation();
- CCallHelpers::Label myLabel = jit.label();
- label = myLabel;
</del><ins>+ label = jit.label();
</ins><span class="cx"> jit.pushToSaveImmediateWithoutTouchingRegisters(CCallHelpers::TrustedImm32(index));
</span><span class="cx"> CCallHelpers::PatchableJump jump = jit.patchableJump();
</span><span class="cx"> RefPtr<OSRExitHandle> self = this;
</span><span class="cx"> jit.addLinkTask(
</span><del>- [self, jump, myLabel, compilation] (LinkBuffer& linkBuffer) {
</del><ins>+ [self, jump] (LinkBuffer& linkBuffer) {
</ins><span class="cx"> self->exit.m_patchableJump = CodeLocationJump(linkBuffer.locationOf(jump));
</span><span class="cx">
</span><span class="cx"> linkBuffer.link(
</span><span class="cx"> jump.m_jump,
</span><span class="cx"> CodeLocationLabel(linkBuffer.vm().getCTIStub(osrExitGenerationThunkGenerator).code()));
</span><del>- if (compilation)
- compilation->addOSRExitSite({ linkBuffer.locationOf(myLabel).executableAddress() });
</del><span class="cx"> });
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitHandleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.h (195132 => 195133)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.h        2016-01-15 17:06:51 UTC (rev 195132)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitHandle.h        2016-01-15 17:07:50 UTC (rev 195133)
</span><span class="lines">@@ -35,7 +35,6 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx">
</span><del>-class State;
</del><span class="cx"> struct OSRExit;
</span><span class="cx">
</span><span class="cx"> // This is an object that stores some interesting data about an OSR exit. It's expected that you will
</span><span class="lines">@@ -56,7 +55,7 @@
</span><span class="cx"> CCallHelpers::Label label;
</span><span class="cx">
</span><span class="cx"> // This emits the exit thunk and populates 'label'.
</span><del>- void emitExitThunk(State&, CCallHelpers&);
</del><ins>+ void emitExitThunk(CCallHelpers&);
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre>
</div>
</div>
</body>
</html>