<!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>[195395] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/195395">195395</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-01-20 19:12:55 -0800 (Wed, 20 Jan 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>B3 should have basic path specialization
https://bugs.webkit.org/show_bug.cgi?id=153200

Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

This adds two different kind of path specializations:

- Check(Select) where the Select results are constants is specialized into a Branch
  instead of a Select and duplicated paths where the results of the Select are folded.

- Tail duplication. A jump to a small block causes the block's contents to be copied over
  the Jump.

Both optimizations required being able to clone Values. We can now do that using
proc.clone(value).

Check(Select) specialization needed some utilities for walking graphs of Values.

Tail duplication needed SSA fixup, so I added a way to demote values to anonymous stack
slots (B3's equivalent of non-SSA variables) and a way to &quot;fix SSA&quot;, i.e. to allocate
anonymous stack slots to SSA values along with an optimal Phi graph.

This is a big speed-up on Octane/deltablue. It's a 2.2% speed-up on Octane overall.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/B3ArgumentRegValue.cpp:
(JSC::B3::ArgumentRegValue::dumpMeta):
(JSC::B3::ArgumentRegValue::cloneImpl):
* b3/B3ArgumentRegValue.h:
* b3/B3BasicBlock.cpp:
(JSC::B3::BasicBlock::append):
(JSC::B3::BasicBlock::appendNonTerminal):
(JSC::B3::BasicBlock::removeLast):
* b3/B3BasicBlock.h:
(JSC::B3::BasicBlock::values):
* b3/B3BasicBlockInlines.h:
(JSC::B3::BasicBlock::appendNew):
(JSC::B3::BasicBlock::appendNewNonTerminal):
(JSC::B3::BasicBlock::replaceLastWithNew):
* b3/B3BlockInsertionSet.h:
* b3/B3BreakCriticalEdges.cpp: Added.
(JSC::B3::breakCriticalEdges):
* b3/B3BreakCriticalEdges.h: Added.
* b3/B3CCallValue.cpp:
(JSC::B3::CCallValue::~CCallValue):
(JSC::B3::CCallValue::cloneImpl):
* b3/B3CCallValue.h:
* b3/B3CheckValue.cpp:
(JSC::B3::CheckValue::convertToAdd):
(JSC::B3::CheckValue::cloneImpl):
(JSC::B3::CheckValue::CheckValue):
* b3/B3CheckValue.h:
* b3/B3Const32Value.cpp:
(JSC::B3::Const32Value::dumpMeta):
(JSC::B3::Const32Value::cloneImpl):
* b3/B3Const32Value.h:
* b3/B3Const64Value.cpp:
(JSC::B3::Const64Value::dumpMeta):
(JSC::B3::Const64Value::cloneImpl):
* b3/B3Const64Value.h:
* b3/B3ConstDoubleValue.cpp:
(JSC::B3::ConstDoubleValue::dumpMeta):
(JSC::B3::ConstDoubleValue::cloneImpl):
* b3/B3ConstDoubleValue.h:
* b3/B3ConstFloatValue.cpp:
(JSC::B3::ConstFloatValue::dumpMeta):
(JSC::B3::ConstFloatValue::cloneImpl):
* b3/B3ConstFloatValue.h:
* b3/B3ControlValue.cpp:
(JSC::B3::ControlValue::dumpMeta):
(JSC::B3::ControlValue::cloneImpl):
* b3/B3ControlValue.h:
* b3/B3DuplicateTails.cpp: Added.
(JSC::B3::duplicateTails):
* b3/B3DuplicateTails.h: Added.
* b3/B3FixSSA.cpp: Added.
(JSC::B3::demoteValues):
(JSC::B3::fixSSA):
* b3/B3FixSSA.h: Added.
* b3/B3Generate.cpp:
(JSC::B3::generateToAir):
* b3/B3IndexSet.h:
(JSC::B3::IndexSet::Iterable::Iterable):
(JSC::B3::IndexSet::values):
(JSC::B3::IndexSet::indices):
* b3/B3InsertionSet.cpp:
(JSC::B3::InsertionSet::insertIntConstant):
(JSC::B3::InsertionSet::insertBottom):
(JSC::B3::InsertionSet::execute):
* b3/B3InsertionSet.h:
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::run):
(JSC::B3::Air::LowerToAir::tmp):
* b3/B3MemoryValue.cpp:
(JSC::B3::MemoryValue::dumpMeta):
(JSC::B3::MemoryValue::cloneImpl):
* b3/B3MemoryValue.h:
* b3/B3OriginDump.cpp: Added.
(JSC::B3::OriginDump::dump):
* b3/B3OriginDump.h:
(JSC::B3::OriginDump::OriginDump):
(JSC::B3::OriginDump::dump): Deleted.
* b3/B3PatchpointValue.cpp:
(JSC::B3::PatchpointValue::dumpMeta):
(JSC::B3::PatchpointValue::cloneImpl):
(JSC::B3::PatchpointValue::PatchpointValue):
* b3/B3PatchpointValue.h:
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::addBlock):
(JSC::B3::Procedure::clone):
(JSC::B3::Procedure::addIntConstant):
(JSC::B3::Procedure::addBottom):
(JSC::B3::Procedure::addBoolConstant):
(JSC::B3::Procedure::deleteValue):
* b3/B3Procedure.h:
* b3/B3ReduceStrength.cpp:
* b3/B3SSACalculator.cpp: Added.
(JSC::B3::SSACalculator::Variable::dump):
(JSC::B3::SSACalculator::Variable::dumpVerbose):
(JSC::B3::SSACalculator::Def::dump):
(JSC::B3::SSACalculator::SSACalculator):
(JSC::B3::SSACalculator::~SSACalculator):
(JSC::B3::SSACalculator::reset):
(JSC::B3::SSACalculator::newVariable):
(JSC::B3::SSACalculator::newDef):
(JSC::B3::SSACalculator::nonLocalReachingDef):
(JSC::B3::SSACalculator::reachingDefAtTail):
(JSC::B3::SSACalculator::dump):
* b3/B3SSACalculator.h: Added.
(JSC::B3::SSACalculator::Variable::index):
(JSC::B3::SSACalculator::Variable::Variable):
(JSC::B3::SSACalculator::Def::variable):
(JSC::B3::SSACalculator::Def::block):
(JSC::B3::SSACalculator::Def::value):
(JSC::B3::SSACalculator::Def::Def):
(JSC::B3::SSACalculator::variable):
(JSC::B3::SSACalculator::computePhis):
(JSC::B3::SSACalculator::phisForBlock):
(JSC::B3::SSACalculator::reachingDefAtHead):
* b3/B3StackSlotKind.h:
* b3/B3StackSlotValue.cpp:
(JSC::B3::StackSlotValue::dumpMeta):
(JSC::B3::StackSlotValue::cloneImpl):
* b3/B3StackSlotValue.h:
* b3/B3SwitchValue.cpp:
(JSC::B3::SwitchValue::dumpMeta):
(JSC::B3::SwitchValue::cloneImpl):
(JSC::B3::SwitchValue::SwitchValue):
* b3/B3SwitchValue.h:
* b3/B3UpsilonValue.cpp:
(JSC::B3::UpsilonValue::dumpMeta):
(JSC::B3::UpsilonValue::cloneImpl):
* b3/B3UpsilonValue.h:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::replaceWithNop):
(JSC::B3::Value::replaceWithPhi):
(JSC::B3::Value::dump):
(JSC::B3::Value::cloneImpl):
(JSC::B3::Value::dumpChildren):
(JSC::B3::Value::deepDump):
* b3/B3Value.h:
(JSC::B3::DeepValueDump::DeepValueDump):
(JSC::B3::DeepValueDump::dump):
(JSC::B3::deepDump):
* b3/B3ValueInlines.h:
(JSC::B3::Value::asNumber):
(JSC::B3::Value::walk):
* b3/B3ValueKey.cpp:
(JSC::B3::ValueKey::intConstant):
(JSC::B3::ValueKey::dump):
* b3/B3ValueKey.h:
(JSC::B3::ValueKey::ValueKey):
(JSC::B3::ValueKey::opcode):
(JSC::B3::ValueKey::type):
(JSC::B3::ValueKey::childIndex):
* b3/air/AirCode.h:
(JSC::B3::Air::Code::forAllTmps):
(JSC::B3::Air::Code::isFastTmp):
* b3/air/AirIteratedRegisterCoalescing.cpp:
* b3/air/AirUseCounts.h:
(JSC::B3::Air::UseCounts::UseCounts):
(JSC::B3::Air::UseCounts::operator[]):
(JSC::B3::Air::UseCounts::dump):
* b3/testb3.cpp:
(JSC::B3::testSelectInvert):
(JSC::B3::testCheckSelect):
(JSC::B3::testCheckSelectCheckSelect):
(JSC::B3::testPowDoubleByIntegerLoop):
(JSC::B3::run):
* runtime/Options.h:

Source/WTF:

* wtf/GraphNodeWorklist.h:
(WTF::GraphNodeWorklist::push):
(WTF::GraphNodeWorklist::pushAll):
(WTF::GraphNodeWorklist::isEmpty):
(WTF::GraphNodeWorklist::notEmpty):</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="#trunkSourceJavaScriptCoreb3B3ArgumentRegValuecpp">trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ArgumentRegValueh">trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3BasicBlockcpp">trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3BasicBlockh">trunk/Source/JavaScriptCore/b3/B3BasicBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3BasicBlockInlinesh">trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3BlockInsertionSeth">trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CCallValuecpp">trunk/Source/JavaScriptCore/b3/B3CCallValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CCallValueh">trunk/Source/JavaScriptCore/b3/B3CCallValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CheckValuecpp">trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3CheckValueh">trunk/Source/JavaScriptCore/b3/B3CheckValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const32Valuecpp">trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const32Valueh">trunk/Source/JavaScriptCore/b3/B3Const32Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const64Valuecpp">trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Const64Valueh">trunk/Source/JavaScriptCore/b3/B3Const64Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstDoubleValuecpp">trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstDoubleValueh">trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstFloatValuecpp">trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ConstFloatValueh">trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ControlValuecpp">trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ControlValueh">trunk/Source/JavaScriptCore/b3/B3ControlValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Generatecpp">trunk/Source/JavaScriptCore/b3/B3Generate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3IndexSeth">trunk/Source/JavaScriptCore/b3/B3IndexSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3InsertionSetcpp">trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3InsertionSeth">trunk/Source/JavaScriptCore/b3/B3InsertionSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerToAircpp">trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3MemoryValuecpp">trunk/Source/JavaScriptCore/b3/B3MemoryValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3MemoryValueh">trunk/Source/JavaScriptCore/b3/B3MemoryValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3OriginDumph">trunk/Source/JavaScriptCore/b3/B3OriginDump.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3PatchpointValuecpp">trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3PatchpointValueh">trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedurecpp">trunk/Source/JavaScriptCore/b3/B3Procedure.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Procedureh">trunk/Source/JavaScriptCore/b3/B3Procedure.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp">trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackSlotKindh">trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackSlotValuecpp">trunk/Source/JavaScriptCore/b3/B3StackSlotValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3StackSlotValueh">trunk/Source/JavaScriptCore/b3/B3StackSlotValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3SwitchValuecpp">trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3SwitchValueh">trunk/Source/JavaScriptCore/b3/B3SwitchValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3UpsilonValuecpp">trunk/Source/JavaScriptCore/b3/B3UpsilonValue.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3UpsilonValueh">trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Validatecpp">trunk/Source/JavaScriptCore/b3/B3Validate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valuecpp">trunk/Source/JavaScriptCore/b3/B3Value.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Valueh">trunk/Source/JavaScriptCore/b3/B3Value.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ValueInlinesh">trunk/Source/JavaScriptCore/b3/B3ValueInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ValueKeycpp">trunk/Source/JavaScriptCore/b3/B3ValueKey.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3ValueKeyh">trunk/Source/JavaScriptCore/b3/B3ValueKey.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirCodeh">trunk/Source/JavaScriptCore/b3/air/AirCode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirIteratedRegisterCoalescingcpp">trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirUseCountsh">trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfGraphNodeWorklisth">trunk/Source/WTF/wtf/GraphNodeWorklist.h</a></li>
<li><a href="#trunkToolsScriptsdisplayprofileroutput">trunk/Tools/Scripts/display-profiler-output</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3B3BreakCriticalEdgescpp">trunk/Source/JavaScriptCore/b3/B3BreakCriticalEdges.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3BreakCriticalEdgesh">trunk/Source/JavaScriptCore/b3/B3BreakCriticalEdges.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3DuplicateTailscpp">trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3DuplicateTailsh">trunk/Source/JavaScriptCore/b3/B3DuplicateTails.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3FixSSAcpp">trunk/Source/JavaScriptCore/b3/B3FixSSA.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3FixSSAh">trunk/Source/JavaScriptCore/b3/B3FixSSA.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3FoldPathConstantscpp">trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3FoldPathConstantsh">trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3OriginDumpcpp">trunk/Source/JavaScriptCore/b3/B3OriginDump.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3SSACalculatorcpp">trunk/Source/JavaScriptCore/b3/B3SSACalculator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3SSACalculatorh">trunk/Source/JavaScriptCore/b3/B3SSACalculator.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -104,6 +104,7 @@
</span><span class="cx">     b3/B3ArgumentRegValue.cpp
</span><span class="cx">     b3/B3BasicBlock.cpp
</span><span class="cx">     b3/B3BlockInsertionSet.cpp
</span><ins>+    b3/B3BreakCriticalEdges.cpp
</ins><span class="cx">     b3/B3CCallValue.cpp
</span><span class="cx">     b3/B3CheckSpecial.cpp
</span><span class="cx">     b3/B3CheckValue.cpp
</span><span class="lines">@@ -117,7 +118,9 @@
</span><span class="cx">     b3/B3ConstrainedValue.cpp
</span><span class="cx">     b3/B3ControlValue.cpp
</span><span class="cx">     b3/B3DataSection.cpp
</span><ins>+    b3/B3DuplicateTails.cpp
</ins><span class="cx">     b3/B3Effects.cpp
</span><ins>+    b3/B3FixSSA.cpp
</ins><span class="cx">     b3/B3FrequencyClass.cpp
</span><span class="cx">     b3/B3Generate.cpp
</span><span class="cx">     b3/B3HeapRange.cpp
</span><span class="lines">@@ -132,6 +135,7 @@
</span><span class="cx">     b3/B3OpaqueByproducts.cpp
</span><span class="cx">     b3/B3Opcode.cpp
</span><span class="cx">     b3/B3Origin.cpp
</span><ins>+    b3/B3OriginDump.cpp
</ins><span class="cx">     b3/B3PatchpointSpecial.cpp
</span><span class="cx">     b3/B3PatchpointValue.cpp
</span><span class="cx">     b3/B3PhaseScope.cpp
</span><span class="lines">@@ -139,6 +143,7 @@
</span><span class="cx">     b3/B3Procedure.cpp
</span><span class="cx">     b3/B3ReduceDoubleToFloat.cpp
</span><span class="cx">     b3/B3ReduceStrength.cpp
</span><ins>+    b3/B3SSACalculator.cpp
</ins><span class="cx">     b3/B3StackmapGenerationParams.cpp
</span><span class="cx">     b3/B3StackmapSpecial.cpp
</span><span class="cx">     b3/B3StackmapValue.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,3 +1,198 @@
</span><ins>+2016-01-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        B3 should have basic path specialization
+        https://bugs.webkit.org/show_bug.cgi?id=153200
+
+        Reviewed by Benjamin Poulain.
+
+        This adds two different kind of path specializations:
+
+        - Check(Select) where the Select results are constants is specialized into a Branch
+          instead of a Select and duplicated paths where the results of the Select are folded.
+
+        - Tail duplication. A jump to a small block causes the block's contents to be copied over
+          the Jump.
+
+        Both optimizations required being able to clone Values. We can now do that using
+        proc.clone(value).
+
+        Check(Select) specialization needed some utilities for walking graphs of Values.
+
+        Tail duplication needed SSA fixup, so I added a way to demote values to anonymous stack
+        slots (B3's equivalent of non-SSA variables) and a way to &quot;fix SSA&quot;, i.e. to allocate
+        anonymous stack slots to SSA values along with an optimal Phi graph.
+
+        This is a big speed-up on Octane/deltablue. It's a 2.2% speed-up on Octane overall.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * b3/B3ArgumentRegValue.cpp:
+        (JSC::B3::ArgumentRegValue::dumpMeta):
+        (JSC::B3::ArgumentRegValue::cloneImpl):
+        * b3/B3ArgumentRegValue.h:
+        * b3/B3BasicBlock.cpp:
+        (JSC::B3::BasicBlock::append):
+        (JSC::B3::BasicBlock::appendNonTerminal):
+        (JSC::B3::BasicBlock::removeLast):
+        * b3/B3BasicBlock.h:
+        (JSC::B3::BasicBlock::values):
+        * b3/B3BasicBlockInlines.h:
+        (JSC::B3::BasicBlock::appendNew):
+        (JSC::B3::BasicBlock::appendNewNonTerminal):
+        (JSC::B3::BasicBlock::replaceLastWithNew):
+        * b3/B3BlockInsertionSet.h:
+        * b3/B3BreakCriticalEdges.cpp: Added.
+        (JSC::B3::breakCriticalEdges):
+        * b3/B3BreakCriticalEdges.h: Added.
+        * b3/B3CCallValue.cpp:
+        (JSC::B3::CCallValue::~CCallValue):
+        (JSC::B3::CCallValue::cloneImpl):
+        * b3/B3CCallValue.h:
+        * b3/B3CheckValue.cpp:
+        (JSC::B3::CheckValue::convertToAdd):
+        (JSC::B3::CheckValue::cloneImpl):
+        (JSC::B3::CheckValue::CheckValue):
+        * b3/B3CheckValue.h:
+        * b3/B3Const32Value.cpp:
+        (JSC::B3::Const32Value::dumpMeta):
+        (JSC::B3::Const32Value::cloneImpl):
+        * b3/B3Const32Value.h:
+        * b3/B3Const64Value.cpp:
+        (JSC::B3::Const64Value::dumpMeta):
+        (JSC::B3::Const64Value::cloneImpl):
+        * b3/B3Const64Value.h:
+        * b3/B3ConstDoubleValue.cpp:
+        (JSC::B3::ConstDoubleValue::dumpMeta):
+        (JSC::B3::ConstDoubleValue::cloneImpl):
+        * b3/B3ConstDoubleValue.h:
+        * b3/B3ConstFloatValue.cpp:
+        (JSC::B3::ConstFloatValue::dumpMeta):
+        (JSC::B3::ConstFloatValue::cloneImpl):
+        * b3/B3ConstFloatValue.h:
+        * b3/B3ControlValue.cpp:
+        (JSC::B3::ControlValue::dumpMeta):
+        (JSC::B3::ControlValue::cloneImpl):
+        * b3/B3ControlValue.h:
+        * b3/B3DuplicateTails.cpp: Added.
+        (JSC::B3::duplicateTails):
+        * b3/B3DuplicateTails.h: Added.
+        * b3/B3FixSSA.cpp: Added.
+        (JSC::B3::demoteValues):
+        (JSC::B3::fixSSA):
+        * b3/B3FixSSA.h: Added.
+        * b3/B3Generate.cpp:
+        (JSC::B3::generateToAir):
+        * b3/B3IndexSet.h:
+        (JSC::B3::IndexSet::Iterable::Iterable):
+        (JSC::B3::IndexSet::values):
+        (JSC::B3::IndexSet::indices):
+        * b3/B3InsertionSet.cpp:
+        (JSC::B3::InsertionSet::insertIntConstant):
+        (JSC::B3::InsertionSet::insertBottom):
+        (JSC::B3::InsertionSet::execute):
+        * b3/B3InsertionSet.h:
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::run):
+        (JSC::B3::Air::LowerToAir::tmp):
+        * b3/B3MemoryValue.cpp:
+        (JSC::B3::MemoryValue::dumpMeta):
+        (JSC::B3::MemoryValue::cloneImpl):
+        * b3/B3MemoryValue.h:
+        * b3/B3OriginDump.cpp: Added.
+        (JSC::B3::OriginDump::dump):
+        * b3/B3OriginDump.h:
+        (JSC::B3::OriginDump::OriginDump):
+        (JSC::B3::OriginDump::dump): Deleted.
+        * b3/B3PatchpointValue.cpp:
+        (JSC::B3::PatchpointValue::dumpMeta):
+        (JSC::B3::PatchpointValue::cloneImpl):
+        (JSC::B3::PatchpointValue::PatchpointValue):
+        * b3/B3PatchpointValue.h:
+        * b3/B3Procedure.cpp:
+        (JSC::B3::Procedure::addBlock):
+        (JSC::B3::Procedure::clone):
+        (JSC::B3::Procedure::addIntConstant):
+        (JSC::B3::Procedure::addBottom):
+        (JSC::B3::Procedure::addBoolConstant):
+        (JSC::B3::Procedure::deleteValue):
+        * b3/B3Procedure.h:
+        * b3/B3ReduceStrength.cpp:
+        * b3/B3SSACalculator.cpp: Added.
+        (JSC::B3::SSACalculator::Variable::dump):
+        (JSC::B3::SSACalculator::Variable::dumpVerbose):
+        (JSC::B3::SSACalculator::Def::dump):
+        (JSC::B3::SSACalculator::SSACalculator):
+        (JSC::B3::SSACalculator::~SSACalculator):
+        (JSC::B3::SSACalculator::reset):
+        (JSC::B3::SSACalculator::newVariable):
+        (JSC::B3::SSACalculator::newDef):
+        (JSC::B3::SSACalculator::nonLocalReachingDef):
+        (JSC::B3::SSACalculator::reachingDefAtTail):
+        (JSC::B3::SSACalculator::dump):
+        * b3/B3SSACalculator.h: Added.
+        (JSC::B3::SSACalculator::Variable::index):
+        (JSC::B3::SSACalculator::Variable::Variable):
+        (JSC::B3::SSACalculator::Def::variable):
+        (JSC::B3::SSACalculator::Def::block):
+        (JSC::B3::SSACalculator::Def::value):
+        (JSC::B3::SSACalculator::Def::Def):
+        (JSC::B3::SSACalculator::variable):
+        (JSC::B3::SSACalculator::computePhis):
+        (JSC::B3::SSACalculator::phisForBlock):
+        (JSC::B3::SSACalculator::reachingDefAtHead):
+        * b3/B3StackSlotKind.h:
+        * b3/B3StackSlotValue.cpp:
+        (JSC::B3::StackSlotValue::dumpMeta):
+        (JSC::B3::StackSlotValue::cloneImpl):
+        * b3/B3StackSlotValue.h:
+        * b3/B3SwitchValue.cpp:
+        (JSC::B3::SwitchValue::dumpMeta):
+        (JSC::B3::SwitchValue::cloneImpl):
+        (JSC::B3::SwitchValue::SwitchValue):
+        * b3/B3SwitchValue.h:
+        * b3/B3UpsilonValue.cpp:
+        (JSC::B3::UpsilonValue::dumpMeta):
+        (JSC::B3::UpsilonValue::cloneImpl):
+        * b3/B3UpsilonValue.h:
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::replaceWithNop):
+        (JSC::B3::Value::replaceWithPhi):
+        (JSC::B3::Value::dump):
+        (JSC::B3::Value::cloneImpl):
+        (JSC::B3::Value::dumpChildren):
+        (JSC::B3::Value::deepDump):
+        * b3/B3Value.h:
+        (JSC::B3::DeepValueDump::DeepValueDump):
+        (JSC::B3::DeepValueDump::dump):
+        (JSC::B3::deepDump):
+        * b3/B3ValueInlines.h:
+        (JSC::B3::Value::asNumber):
+        (JSC::B3::Value::walk):
+        * b3/B3ValueKey.cpp:
+        (JSC::B3::ValueKey::intConstant):
+        (JSC::B3::ValueKey::dump):
+        * b3/B3ValueKey.h:
+        (JSC::B3::ValueKey::ValueKey):
+        (JSC::B3::ValueKey::opcode):
+        (JSC::B3::ValueKey::type):
+        (JSC::B3::ValueKey::childIndex):
+        * b3/air/AirCode.h:
+        (JSC::B3::Air::Code::forAllTmps):
+        (JSC::B3::Air::Code::isFastTmp):
+        * b3/air/AirIteratedRegisterCoalescing.cpp:
+        * b3/air/AirUseCounts.h:
+        (JSC::B3::Air::UseCounts::UseCounts):
+        (JSC::B3::Air::UseCounts::operator[]):
+        (JSC::B3::Air::UseCounts::dump):
+        * b3/testb3.cpp:
+        (JSC::B3::testSelectInvert):
+        (JSC::B3::testCheckSelect):
+        (JSC::B3::testCheckSelectCheckSelect):
+        (JSC::B3::testPowDoubleByIntegerLoop):
+        (JSC::B3::run):
+        * runtime/Options.h:
+
</ins><span class="cx"> 2016-01-20  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [JSC] Fix a typo in the Air definition of CeilDouble/CeilFloat
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -381,6 +381,7 @@
</span><span class="cx">                 0F4C91661C29F4F2004341A6 /* B3OriginDump.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4C91651C29F4F2004341A6 /* B3OriginDump.h */; };
</span><span class="cx">                 0F4DE1CE1C4C1B54004D6C11 /* AirFixObviousSpills.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4DE1CC1C4C1B54004D6C11 /* AirFixObviousSpills.cpp */; };
</span><span class="cx">                 0F4DE1CF1C4C1B54004D6C11 /* AirFixObviousSpills.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4DE1CD1C4C1B54004D6C11 /* AirFixObviousSpills.h */; };
</span><ins>+                0F4DE1D11C4D764B004D6C11 /* B3OriginDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */; };
</ins><span class="cx">                 0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */; };
</span><span class="cx">                 0F4F29E018B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */; };
</span><span class="cx">                 0F50AF3C193E8B3900674EE8 /* DFGStructureClobberState.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */; };
</span><span class="lines">@@ -449,6 +450,14 @@
</span><span class="cx">                 0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F6B1CC51862C47800845D97 /* FTLUnwindInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B1CC11862C47800845D97 /* FTLUnwindInfo.cpp */; };
</span><span class="cx">                 0F6B1CC61862C47800845D97 /* FTLUnwindInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F6B8AD81C4EDDA200969052 /* B3DuplicateTails.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B8AD61C4EDDA200969052 /* B3DuplicateTails.cpp */; };
+                0F6B8AD91C4EDDA200969052 /* B3DuplicateTails.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B8AD71C4EDDA200969052 /* B3DuplicateTails.h */; };
+                0F6B8ADC1C4EFAC300969052 /* B3SSACalculator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B8ADA1C4EFAC300969052 /* B3SSACalculator.cpp */; };
+                0F6B8ADD1C4EFAC300969052 /* B3SSACalculator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B8ADB1C4EFAC300969052 /* B3SSACalculator.h */; };
+                0F6B8AE21C4EFE1700969052 /* B3BreakCriticalEdges.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */; };
+                0F6B8AE31C4EFE1700969052 /* B3BreakCriticalEdges.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */; };
+                0F6B8AE41C4EFE1700969052 /* B3FixSSA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6B8AE01C4EFE1700969052 /* B3FixSSA.cpp */; };
+                0F6B8AE51C4EFE1700969052 /* B3FixSSA.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6B8AE11C4EFE1700969052 /* B3FixSSA.h */; };
</ins><span class="cx">                 0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */; };
</span><span class="cx">                 0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F6E845A19030BEF00562741 /* DFGVariableAccessData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */; };
</span><span class="lines">@@ -458,6 +467,8 @@
</span><span class="cx">                 0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */; };
</span><span class="cx">                 0F714CA416EA92F000F3EBEB /* DFGBackwardsPropagationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */; };
</span><span class="cx">                 0F714CA516EA92F200F3EBEB /* DFGBackwardsPropagationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */; };
</span><ins>+                0F725CAF1C506D3B00AD943A /* B3FoldPathConstants.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F725CAD1C506D3B00AD943A /* B3FoldPathConstants.cpp */; };
+                0F725CB01C506D3B00AD943A /* B3FoldPathConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F725CAE1C506D3B00AD943A /* B3FoldPathConstants.h */; };
</ins><span class="cx">                 0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 652A3A201651C66100A80AFE /* ARM64Disassembler.cpp */; };
</span><span class="cx">                 0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */; };
</span><span class="cx">                 0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */; };
</span><span class="lines">@@ -2548,6 +2559,7 @@
</span><span class="cx">                 0F4C91651C29F4F2004341A6 /* B3OriginDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3OriginDump.h; path = b3/B3OriginDump.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F4DE1CC1C4C1B54004D6C11 /* AirFixObviousSpills.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AirFixObviousSpills.cpp; path = b3/air/AirFixObviousSpills.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F4DE1CD1C4C1B54004D6C11 /* AirFixObviousSpills.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AirFixObviousSpills.h; path = b3/air/AirFixObviousSpills.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3OriginDump.cpp; path = b3/B3OriginDump.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F4F29DD18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGStaticExecutionCountEstimationPhase.cpp; path = dfg/DFGStaticExecutionCountEstimationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F4F29DE18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStaticExecutionCountEstimationPhase.h; path = dfg/DFGStaticExecutionCountEstimationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F50AF3B193E8B3900674EE8 /* DFGStructureClobberState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureClobberState.h; path = dfg/DFGStructureClobberState.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2618,6 +2630,14 @@
</span><span class="cx">                 0F6B1CB71861244C00845D97 /* ArityCheckMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArityCheckMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CC11862C47800845D97 /* FTLUnwindInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLUnwindInfo.cpp; path = ftl/FTLUnwindInfo.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6B1CC21862C47800845D97 /* FTLUnwindInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLUnwindInfo.h; path = ftl/FTLUnwindInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F6B8AD61C4EDDA200969052 /* B3DuplicateTails.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3DuplicateTails.cpp; path = b3/B3DuplicateTails.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6B8AD71C4EDDA200969052 /* B3DuplicateTails.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3DuplicateTails.h; path = b3/B3DuplicateTails.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6B8ADA1C4EFAC300969052 /* B3SSACalculator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3SSACalculator.cpp; path = b3/B3SSACalculator.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6B8ADB1C4EFAC300969052 /* B3SSACalculator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3SSACalculator.h; path = b3/B3SSACalculator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3BreakCriticalEdges.cpp; path = b3/B3BreakCriticalEdges.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3BreakCriticalEdges.h; path = b3/B3BreakCriticalEdges.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6B8AE01C4EFE1700969052 /* B3FixSSA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3FixSSA.cpp; path = b3/B3FixSSA.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F6B8AE11C4EFE1700969052 /* B3FixSSA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3FixSSA.h; path = b3/B3FixSSA.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F6C734E1AC9F99F00BE1682 /* VariableWriteFireDetail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableWriteFireDetail.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6C734F1AC9F99F00BE1682 /* VariableWriteFireDetail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableWriteFireDetail.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F6E845919030BEF00562741 /* DFGVariableAccessData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGVariableAccessData.cpp; path = dfg/DFGVariableAccessData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2627,6 +2647,8 @@
</span><span class="cx">                 0F7025A81714B0F800382C0E /* DFGOSRExitCompilerCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGOSRExitCompilerCommon.h; path = dfg/DFGOSRExitCompilerCommon.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F714CA116EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGBackwardsPropagationPhase.cpp; path = dfg/DFGBackwardsPropagationPhase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F714CA216EA92ED00F3EBEB /* DFGBackwardsPropagationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGBackwardsPropagationPhase.h; path = dfg/DFGBackwardsPropagationPhase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F725CAD1C506D3B00AD943A /* B3FoldPathConstants.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3FoldPathConstants.cpp; path = b3/B3FoldPathConstants.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F725CAE1C506D3B00AD943A /* B3FoldPathConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3FoldPathConstants.h; path = b3/B3FoldPathConstants.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F766D1C15A5028D008F363E /* JITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutine.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubRoutine.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F766D2915A8CC34008F363E /* JITStubRoutineSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITStubRoutineSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4726,6 +4748,8 @@
</span><span class="cx">                                 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */,
</span><span class="cx">                                 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */,
</span><span class="cx">                                 0FEC84BA1BDACDAC0080FF74 /* B3BlockWorklist.h */,
</span><ins>+                                0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */,
+                                0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */,
</ins><span class="cx">                                 0F338DF71BE96AA80013C88F /* B3CCallValue.cpp */,
</span><span class="cx">                                 0F338DF81BE96AA80013C88F /* B3CCallValue.h */,
</span><span class="cx">                                 0F33FCF91C1625BE00323F67 /* B3CFG.h */,
</span><span class="lines">@@ -4755,8 +4779,14 @@
</span><span class="cx">                                 0F338E011BF0276C0013C88F /* B3DataSection.cpp */,
</span><span class="cx">                                 0F338E021BF0276C0013C88F /* B3DataSection.h */,
</span><span class="cx">                                 0F33FCFA1C1625BE00323F67 /* B3Dominators.h */,
</span><ins>+                                0F6B8AD61C4EDDA200969052 /* B3DuplicateTails.cpp */,
+                                0F6B8AD71C4EDDA200969052 /* B3DuplicateTails.h */,
</ins><span class="cx">                                 0FEC85C41BE16F5A0080FF74 /* B3Effects.cpp */,
</span><span class="cx">                                 0FEC85BE1BE167A00080FF74 /* B3Effects.h */,
</span><ins>+                                0F6B8AE01C4EFE1700969052 /* B3FixSSA.cpp */,
+                                0F6B8AE11C4EFE1700969052 /* B3FixSSA.h */,
+                                0F725CAD1C506D3B00AD943A /* B3FoldPathConstants.cpp */,
+                                0F725CAE1C506D3B00AD943A /* B3FoldPathConstants.h */,
</ins><span class="cx">                                 0FEC84CB1BDACDAC0080FF74 /* B3FrequencyClass.cpp */,
</span><span class="cx">                                 0FEC84CC1BDACDAC0080FF74 /* B3FrequencyClass.h */,
</span><span class="cx">                                 0FEC84CD1BDACDAC0080FF74 /* B3FrequentedBlock.h */,
</span><span class="lines">@@ -4791,6 +4821,7 @@
</span><span class="cx">                                 0FEC84D81BDACDAC0080FF74 /* B3Opcode.h */,
</span><span class="cx">                                 0FEC84D91BDACDAC0080FF74 /* B3Origin.cpp */,
</span><span class="cx">                                 0FEC84DA1BDACDAC0080FF74 /* B3Origin.h */,
</span><ins>+                                0F4DE1D01C4D764B004D6C11 /* B3OriginDump.cpp */,
</ins><span class="cx">                                 0F4C91651C29F4F2004341A6 /* B3OriginDump.h */,
</span><span class="cx">                                 0FEC84DB1BDACDAC0080FF74 /* B3PatchpointSpecial.cpp */,
</span><span class="cx">                                 0FEC84DC1BDACDAC0080FF74 /* B3PatchpointSpecial.h */,
</span><span class="lines">@@ -4807,6 +4838,8 @@
</span><span class="cx">                                 43422A651C16221E00E2EB98 /* B3ReduceDoubleToFloat.h */,
</span><span class="cx">                                 0FEC85B71BE1462F0080FF74 /* B3ReduceStrength.cpp */,
</span><span class="cx">                                 0FEC85B81BE1462F0080FF74 /* B3ReduceStrength.h */,
</span><ins>+                                0F6B8ADA1C4EFAC300969052 /* B3SSACalculator.cpp */,
+                                0F6B8ADB1C4EFAC300969052 /* B3SSACalculator.h */,
</ins><span class="cx">                                 0F33FCF51C136E2500323F67 /* B3StackmapGenerationParams.cpp */,
</span><span class="cx">                                 0F33FCF61C136E2500323F67 /* B3StackmapGenerationParams.h */,
</span><span class="cx">                                 0FEC84E61BDACDAC0080FF74 /* B3StackmapSpecial.cpp */,
</span><span class="lines">@@ -7128,6 +7161,7 @@
</span><span class="cx">                                 0F24E54217EA9F5900ABB217 /* CCallHelpers.h in Headers */,
</span><span class="cx">                                 0F1C3DDA1BBCE09E00E523E4 /* CellState.h in Headers */,
</span><span class="cx">                                 BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
</span><ins>+                                0F6B8AD91C4EDDA200969052 /* B3DuplicateTails.h in Headers */,
</ins><span class="cx">                                 0FE050261AA9095600D33B33 /* ClonedArguments.h in Headers */,
</span><span class="cx">                                 969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
</span><span class="cx">                                 0F8F94411667633200D61971 /* CodeBlockHash.h in Headers */,
</span><span class="lines">@@ -7241,6 +7275,7 @@
</span><span class="cx">                                 0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */,
</span><span class="cx">                                 0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */,
</span><span class="cx">                                 0FEA0A32170D40BF00BB722C /* DFGCommonData.h in Headers */,
</span><ins>+                                0F725CB01C506D3B00AD943A /* B3FoldPathConstants.h in Headers */,
</ins><span class="cx">                                 0F38B01817CFE75500B144D3 /* DFGCompilationKey.h in Headers */,
</span><span class="cx">                                 0F9D4C111C3E2C74006CD984 /* FTLPatchpointExceptionHandle.h in Headers */,
</span><span class="cx">                                 0F38B01A17CFE75500B144D3 /* DFGCompilationMode.h in Headers */,
</span><span class="lines">@@ -7303,6 +7338,7 @@
</span><span class="cx">                                 79F8FC1F1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.h in Headers */,
</span><span class="cx">                                 0F5874EE194FEB1200AAB2C1 /* DFGMayExit.h in Headers */,
</span><span class="cx">                                 0F2BDC451522801B00CD8910 /* DFGMinifiedGraph.h in Headers */,
</span><ins>+                                0F6B8AE31C4EFE1700969052 /* B3BreakCriticalEdges.h in Headers */,
</ins><span class="cx">                                 0F2E892D16D02BAF009E4FD2 /* DFGMinifiedID.h in Headers */,
</span><span class="cx">                                 0F2BDC461522802000CD8910 /* DFGMinifiedNode.h in Headers */,
</span><span class="cx">                                 0F8F14361ADF090100ED792C /* DFGMovHintRemovalPhase.h in Headers */,
</span><span class="lines">@@ -7423,6 +7459,7 @@
</span><span class="cx">                                 0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */,
</span><span class="cx">                                 0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */,
</span><span class="cx">                                 0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */,
</span><ins>+                                0F6B8AE51C4EFE1700969052 /* B3FixSSA.h in Headers */,
</ins><span class="cx">                                 0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */,
</span><span class="cx">                                 0FEA0A231709606900BB722C /* FTLCommonValues.h in Headers */,
</span><span class="cx">                                 0FEA0A0C170513DB00BB722C /* FTLCompile.h in Headers */,
</span><span class="lines">@@ -8100,6 +8137,7 @@
</span><span class="cx">                                 7B2E010E1B97AA6900EF5D5C /* WASMFunctionCompiler.h in Headers */,
</span><span class="cx">                                 7B8329BF1BB21FE300649A6E /* WASMFunctionLLVMIRGenerator.h in Headers */,
</span><span class="cx">                                 7B0247571B8682E400542440 /* WASMFunctionParser.h in Headers */,
</span><ins>+                                0F6B8ADD1C4EFAC300969052 /* B3SSACalculator.h in Headers */,
</ins><span class="cx">                                 7B0247591B868EB700542440 /* WASMFunctionSyntaxChecker.h in Headers */,
</span><span class="cx">                                 7B39F76E1B62DE3200360FB4 /* WASMModuleParser.h in Headers */,
</span><span class="cx">                                 7B39F7701B62DE3200360FB4 /* WASMReader.h in Headers */,
</span><span class="lines">@@ -8783,6 +8821,7 @@
</span><span class="cx">                                 62D755D41B84FB3D001801FA /* CallFrameShuffler64.cpp in Sources */,
</span><span class="cx">                                 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
</span><span class="cx">                                 0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
</span><ins>+                                0F6B8ADC1C4EFAC300969052 /* B3SSACalculator.cpp in Sources */,
</ins><span class="cx">                                 627673231B680C1E00FD9F2E /* CallMode.cpp in Sources */,
</span><span class="cx">                                 0F3B7E2A19A11B8000D9BC56 /* CallVariant.cpp in Sources */,
</span><span class="cx">                                 0FE050251AA9095600D33B33 /* ClonedArguments.cpp in Sources */,
</span><span class="lines">@@ -8927,6 +8966,7 @@
</span><span class="cx">                                 0FC09791146A6F7100CF2442 /* DFGOSRExit.cpp in Sources */,
</span><span class="cx">                                 0F235BEB17178E7300690C7F /* DFGOSRExitBase.cpp in Sources */,
</span><span class="cx">                                 0FC09792146A6F7300CF2442 /* DFGOSRExitCompiler.cpp in Sources */,
</span><ins>+                                0F4DE1D11C4D764B004D6C11 /* B3OriginDump.cpp in Sources */,
</ins><span class="cx">                                 FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */,
</span><span class="cx">                                 0FC09776146943B000CF2442 /* DFGOSRExitCompiler32_64.cpp in Sources */,
</span><span class="cx">                                 0FC0977214693AF900CF2442 /* DFGOSRExitCompiler64.cpp in Sources */,
</span><span class="lines">@@ -9023,9 +9063,11 @@
</span><span class="cx">                                 0F25F1AF181635F300522F39 /* FTLInlineCacheSize.cpp in Sources */,
</span><span class="cx">                                 0FEA0A281709623B00BB722C /* FTLIntrinsicRepository.cpp in Sources */,
</span><span class="cx">                                 0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
</span><ins>+                                0F6B8AE21C4EFE1700969052 /* B3BreakCriticalEdges.cpp in Sources */,
</ins><span class="cx">                                 A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,
</span><span class="cx">                                 0F6B1CB5185FC9E900845D97 /* FTLJSCall.cpp in Sources */,
</span><span class="cx">                                 0FD1202F1A8AED12000F5280 /* FTLJSCallBase.cpp in Sources */,
</span><ins>+                                0F725CAF1C506D3B00AD943A /* B3FoldPathConstants.cpp in Sources */,
</ins><span class="cx">                                 0FD120331A8C85BD000F5280 /* FTLJSCallVarargs.cpp in Sources */,
</span><span class="cx">                                 62774DAA1B8D4B190006F05A /* FTLJSTailCall.cpp in Sources */,
</span><span class="cx">                                 FE187A0E1C030D640038BBCA /* JITDivGenerator.cpp in Sources */,
</span><span class="lines">@@ -9366,6 +9408,7 @@
</span><span class="cx">                                 A5BA15EC182340B400A82E69 /* RemoteConnectionToTarget.mm in Sources */,
</span><span class="cx">                                 A5BA15EE182340B400A82E69 /* RemoteInspectorXPCConnection.mm in Sources */,
</span><span class="cx">                                 0F24E55017EE274900ABB217 /* Repatch.cpp in Sources */,
</span><ins>+                                0F6B8AD81C4EDDA200969052 /* B3DuplicateTails.cpp in Sources */,
</ins><span class="cx">                                 527773DE1AAF83AC00BDE7E8 /* RuntimeType.cpp in Sources */,
</span><span class="cx">                                 0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */,
</span><span class="cx">                                 1429D8850ED21C3D00B89619 /* SamplingTool.cpp in Sources */,
</span><span class="lines">@@ -9429,6 +9472,7 @@
</span><span class="cx">                                 52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */,
</span><span class="cx">                                 0F2D4DEB19832DC4007D4B19 /* TypeProfilerLog.cpp in Sources */,
</span><span class="cx">                                 0F2D4DEF19832DD3007D4B19 /* TypeSet.cpp in Sources */,
</span><ins>+                                0F6B8AE41C4EFE1700969052 /* B3FixSSA.cpp in Sources */,
</ins><span class="cx">                                 0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
</span><span class="cx">                                 0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */,
</span><span class="cx">                                 0FF42743158EBE91004CB9FF /* udis86_input.c in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ArgumentRegValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -39,6 +39,11 @@
</span><span class="cx">     out.print(comma, m_reg);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* ArgumentRegValue::cloneImpl() const
+{
+    return new ArgumentRegValue(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ArgumentRegValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ArgumentRegValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -44,6 +44,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BasicBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -54,6 +54,12 @@
</span><span class="cx">     m_values.append(value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BasicBlock::appendNonTerminal(Value* value)
+{
+    m_values.append(m_values.last());
+    m_values[m_values.size() - 1] = value;
+}
+
</ins><span class="cx"> void BasicBlock::removeLast(Procedure&amp; proc)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_values.isEmpty());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BasicBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3BasicBlock.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BasicBlock.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3BasicBlock.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -71,10 +71,13 @@
</span><span class="cx">     ValueList&amp; values() { return m_values; }
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void append(Value*);
</span><ins>+    JS_EXPORT_PRIVATE void appendNonTerminal(Value*);
</ins><span class="cx">     JS_EXPORT_PRIVATE void replaceLast(Procedure&amp;, Value*);
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename ValueType, typename... Arguments&gt;
</span><span class="cx">     ValueType* appendNew(Procedure&amp;, Arguments...);
</span><ins>+    template&lt;typename ValueType, typename... Arguments&gt;
+    ValueType* appendNewNonTerminal(Procedure&amp;, Arguments...);
</ins><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE Value* appendIntConstant(Procedure&amp;, Origin, Type, int64_t value);
</span><span class="cx">     Value* appendIntConstant(Procedure&amp;, Value* likeValue, int64_t value);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BasicBlockInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -43,6 +43,14 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename ValueType, typename... Arguments&gt;
</span><ins>+ValueType* BasicBlock::appendNewNonTerminal(Procedure&amp; procedure, Arguments... arguments)
+{
+    ValueType* result = procedure.add&lt;ValueType&gt;(arguments...);
+    appendNonTerminal(result);
+    return result;
+}
+
+template&lt;typename ValueType, typename... Arguments&gt;
</ins><span class="cx"> ValueType* BasicBlock::replaceLastWithNew(Procedure&amp; procedure, Arguments... arguments)
</span><span class="cx"> {
</span><span class="cx">     ValueType* result = procedure.add&lt;ValueType&gt;(arguments...);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BlockInsertionSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -61,8 +61,8 @@
</span><span class="cx">     // everything at and after valueIndex. If the optional InsertionSet is provided, it will get
</span><span class="cx">     // executed on the newly created block - this makes sense if you had previously inserted
</span><span class="cx">     // things into the original block, since the newly created block will be indexed identically
</span><del>-    // to hold this block was indexed for all values prior to valueIndex. After this runs, it
-    // sets valueIndex to zero. This allows you to use this method for things like:
</del><ins>+    // to how this block was indexed for all values prior to valueIndex. After this runs, it sets
+    // valueIndex to zero. This allows you to use this method for things like:
</ins><span class="cx">     //
</span><span class="cx">     // for (unsigned valueIndex = 0; valueIndex &lt; block-&gt;size(); ++valueIndex) {
</span><span class="cx">     //     Value* value = block-&gt;at(valueIndex);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BreakCriticalEdgescpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3BreakCriticalEdges.cpp (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BreakCriticalEdges.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3BreakCriticalEdges.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3BreakCriticalEdges.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3BasicBlockInlines.h&quot;
+#include &quot;B3BlockInsertionSet.h&quot;
+#include &quot;B3ControlValue.h&quot;
+#include &quot;B3ProcedureInlines.h&quot;
+#include &quot;B3ValueInlines.h&quot;
+
+namespace JSC { namespace B3 {
+
+void breakCriticalEdges(Procedure&amp; proc)
+{
+    BlockInsertionSet insertionSet(proc);
+    
+    for (BasicBlock* block : proc) {
+        if (block-&gt;numSuccessors() &lt;= 1)
+            continue;
+
+        for (BasicBlock*&amp; successor : block-&gt;successorBlocks()) {
+            if (successor-&gt;numPredecessors() &lt;= 1)
+                continue;
+
+            BasicBlock* pad =
+                insertionSet.insertBefore(successor, successor-&gt;frequency());
+            pad-&gt;appendNew&lt;ControlValue&gt;(
+                proc, Jump, successor-&gt;at(0)-&gt;origin(), FrequentedBlock(successor));
+            pad-&gt;addPredecessor(block);
+            successor-&gt;replacePredecessor(block, pad);
+            successor = pad;
+        }
+    }
+
+    insertionSet.execute();
+    proc.invalidateCFG();
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BreakCriticalEdgesh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3BreakCriticalEdges.h (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BreakCriticalEdges.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3BreakCriticalEdges.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef B3BreakCriticalEdges_h
+#define B3BreakCriticalEdges_h
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+class Procedure;
+
+void breakCriticalEdges(Procedure&amp;);
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3BreakCriticalEdges_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CCallValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CCallValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CCallValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3CCallValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -34,6 +34,11 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* CCallValue::cloneImpl() const
+{
+    return new CCallValue(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CCallValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CCallValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CCallValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3CCallValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -41,6 +41,9 @@
</span><span class="cx"> 
</span><span class="cx">     Effects effects { Effects::forCall() };
</span><span class="cx"> 
</span><ins>+protected:
+    Value* cloneImpl() const override;
+    
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3CheckValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -40,6 +40,11 @@
</span><span class="cx">     m_opcode = CheckAdd;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* CheckValue::cloneImpl() const
+{
+    return new CheckValue(*this);
+}
+
</ins><span class="cx"> // Use this form for CheckAdd, CheckSub, and CheckMul.
</span><span class="cx"> CheckValue::CheckValue(unsigned index, Opcode opcode, Origin origin, Value* left, Value* right)
</span><span class="cx">     : StackmapValue(index, CheckedOpcode, opcode, left-&gt;type(), origin)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3CheckValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3CheckValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3CheckValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3CheckValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -51,6 +51,9 @@
</span><span class="cx"> 
</span><span class="cx">     void convertToAdd();
</span><span class="cx"> 
</span><ins>+protected:
+    Value* cloneImpl() const override;
+    
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const32Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -241,6 +241,11 @@
</span><span class="cx">     out.print(comma, m_value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* Const32Value::cloneImpl() const
+{
+    return new Const32Value(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const32Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const32Value.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const32Value.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Const32Value.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -73,6 +73,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><span class="cx">     Const32Value(unsigned index, Origin origin, int32_t value)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const64Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -241,6 +241,11 @@
</span><span class="cx">     out.print(comma, m_value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* Const64Value::cloneImpl() const
+{
+    return new Const64Value(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const64Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const64Value.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const64Value.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Const64Value.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -73,6 +73,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><span class="cx">     Const64Value(unsigned index, Origin origin, int64_t value)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstDoubleValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -175,6 +175,11 @@
</span><span class="cx">     out.printf(&quot;%le&quot;, m_value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* ConstDoubleValue::cloneImpl() const
+{
+    return new ConstDoubleValue(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstDoubleValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -65,6 +65,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstFloatValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -157,6 +157,11 @@
</span><span class="cx">     out.printf(&quot;%le&quot;, m_value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* ConstFloatValue::cloneImpl() const
+{
+    return new ConstFloatValue(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstFloatValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ConstFloatValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -63,6 +63,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ControlValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -83,6 +83,11 @@
</span><span class="cx">         out.print(comma, successor);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* ControlValue::cloneImpl() const
+{
+    return new ControlValue(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ControlValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ControlValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ControlValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ControlValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;B3FrequentedBlock.h&quot;
</span><ins>+#include &quot;B3SuccessorCollection.h&quot;
</ins><span class="cx"> #include &quot;B3Value.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="lines">@@ -64,6 +65,17 @@
</span><span class="cx">     const SuccessorList&amp; successors() const { return m_successors; }
</span><span class="cx">     SuccessorList&amp; successors() { return m_successors; }
</span><span class="cx"> 
</span><ins>+    BasicBlock* successorBlock(unsigned index) const { return successor(index).block(); }
+    BasicBlock*&amp; successorBlock(unsigned index) { return successor(index).block(); }
+    SuccessorCollection&lt;BasicBlock, SuccessorList&gt; successorBlocks()
+    {
+        return SuccessorCollection&lt;BasicBlock, SuccessorList&gt;(successors());
+    }
+    SuccessorCollection&lt;const BasicBlock, const SuccessorList&gt; successorBlocks() const
+    {
+        return SuccessorCollection&lt;const BasicBlock, const SuccessorList&gt;(successors());
+    }
+
</ins><span class="cx">     bool replaceSuccessor(BasicBlock* from, BasicBlock* to);
</span><span class="cx"> 
</span><span class="cx">     const FrequentedBlock&amp; taken() const
</span><span class="lines">@@ -93,6 +105,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx">     // Use this for subclasses.
</span><span class="cx">     template&lt;typename... Arguments&gt;
</span><span class="cx">     ControlValue(unsigned index, Opcode opcode, Type type, Origin origin, Arguments... arguments)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3DuplicateTailscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3DuplicateTails.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,154 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3DuplicateTails.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3BasicBlockInlines.h&quot;
+#include &quot;B3ControlValue.h&quot;
+#include &quot;B3Dominators.h&quot;
+#include &quot;B3FixSSA.h&quot;
+#include &quot;B3IndexSet.h&quot;
+#include &quot;B3InsertionSetInlines.h&quot;
+#include &quot;B3PhaseScope.h&quot;
+#include &quot;B3ProcedureInlines.h&quot;
+#include &quot;B3SwitchValue.h&quot;
+#include &quot;B3UpsilonValue.h&quot;
+#include &quot;B3ValueInlines.h&quot;
+
+namespace JSC { namespace B3 {
+
+namespace {
+
+const bool verbose = false;
+
+class DuplicateTails {
+public:
+    DuplicateTails(Procedure&amp; proc)
+        : m_proc(proc)
+        , m_insertionSet(proc)
+        , m_maxSize(Options::maxB3TailDupBlockSize())
+        , m_maxSuccessors(Options::maxB3TailDupBlockSuccessors())
+    {
+    }
+
+    void run()
+    {
+        // Find blocks that would be candidates for tail duplication. They must be small enough
+        // and they much not have too many successors.
+
+        m_proc.resetValueOwners();
+
+        IndexSet&lt;BasicBlock&gt; candidates;
+
+        for (BasicBlock* block : m_proc) {
+            if (block-&gt;size() &gt; m_maxSize || block-&gt;numSuccessors() &gt; m_maxSuccessors)
+                continue;
+
+            candidates.add(block);
+        }
+
+        // Collect the set of values that must be de-SSA'd.
+        IndexSet&lt;Value&gt; valuesToDemote;
+        for (BasicBlock* block : m_proc) {
+            for (Value* value : *block) {
+                if (value-&gt;opcode() == Phi &amp;&amp; candidates.contains(block))
+                    valuesToDemote.add(value);
+                for (Value* child : value-&gt;children()) {
+                    if (child-&gt;owner != block &amp;&amp; candidates.contains(child-&gt;owner))
+                        valuesToDemote.add(child);
+                }
+            }
+        }
+        demoteValues(m_proc, valuesToDemote);
+        if (verbose) {
+            dataLog(&quot;Procedure after value demotion:\n&quot;);
+            dataLog(m_proc);
+        }
+
+        for (BasicBlock* block : m_proc) {
+            ControlValue* jump = block-&gt;last()-&gt;as&lt;ControlValue&gt;();
+            if (jump-&gt;opcode() != Jump)
+                continue;
+
+            BasicBlock* tail = jump-&gt;successorBlock(0);
+            if (!candidates.contains(tail))
+                continue;
+
+            // We're about to change 'block'. Make sure that nobody duplicates block after this
+            // point.
+            candidates.remove(block);
+
+            if (verbose)
+                dataLog(&quot;Duplicating &quot;, *tail, &quot; into &quot;, *block, &quot;\n&quot;);
+
+            block-&gt;removeLast(m_proc);
+
+            HashMap&lt;Value*, Value*&gt; map;
+            for (Value* value : *tail) {
+                Value* clone = m_proc.clone(value);
+                for (Value*&amp; child : clone-&gt;children()) {
+                    if (Value* replacement = map.get(child))
+                        child = replacement;
+                }
+                if (value-&gt;type() != Void)
+                    map.add(value, clone);
+                block-&gt;append(clone);
+            }
+        }
+
+        m_proc.resetReachability();
+        m_proc.invalidateCFG();
+
+        if (verbose) {
+            dataLog(&quot;Procedure just before SSA conversion:\n&quot;);
+            dataLog(m_proc);
+        }
+        fixSSA(m_proc);
+    }
+    
+private:
+
+    Procedure&amp; m_proc;
+    InsertionSet m_insertionSet;
+    unsigned m_maxSize;
+    unsigned m_maxSuccessors;
+};
+
+} // anonymous namespace
+
+void duplicateTails(Procedure&amp; proc)
+{
+    PhaseScope phaseScope(proc, &quot;duplicateTails&quot;);
+    DuplicateTails duplicateTails(proc);
+    duplicateTails.run();
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3DuplicateTailsh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3DuplicateTails.h (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3DuplicateTails.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3DuplicateTails.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef B3DuplicateTails_h
+#define B3DuplicateTails_h
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+class Procedure;
+
+// Replaces jumps to tiny basic blocks with the contents of those basic blocks. Also simplifies
+// branches that are path-redundant. Does not do a fixpoint, because it does not have a good way
+// of detecting termination.
+
+void duplicateTails(Procedure&amp;);
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3DuplicateTails_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3FixSSAcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3FixSSA.cpp (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3FixSSA.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3FixSSA.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,335 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3FixSSA.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3BasicBlockInlines.h&quot;
+#include &quot;B3BreakCriticalEdges.h&quot;
+#include &quot;B3ControlValue.h&quot;
+#include &quot;B3Dominators.h&quot;
+#include &quot;B3IndexSet.h&quot;
+#include &quot;B3InsertionSetInlines.h&quot;
+#include &quot;B3MemoryValue.h&quot;
+#include &quot;B3PhaseScope.h&quot;
+#include &quot;B3ProcedureInlines.h&quot;
+#include &quot;B3SSACalculator.h&quot;
+#include &quot;B3StackSlotValue.h&quot;
+#include &quot;B3UpsilonValue.h&quot;
+#include &quot;B3ValueInlines.h&quot;
+#include &lt;wtf/CommaPrinter.h&gt;
+
+namespace JSC { namespace B3 {
+
+namespace {
+const bool verbose = false;
+} // anonymous namespace
+
+void demoteValues(Procedure&amp; proc, const IndexSet&lt;Value&gt;&amp; values)
+{
+    HashMap&lt;Value*, StackSlotValue*&gt; map;
+    HashMap&lt;Value*, StackSlotValue*&gt; phiMap;
+
+    // Create stack slots.
+    InsertionSet insertionSet(proc);
+    for (Value* value : values.values(proc.values())) {
+        StackSlotValue* stack = insertionSet.insert&lt;StackSlotValue&gt;(
+            0, value-&gt;origin(), sizeofType(value-&gt;type()), StackSlotKind::Anonymous);
+        map.add(value, stack);
+
+        if (value-&gt;opcode() == Phi) {
+            StackSlotValue* phiStack = insertionSet.insert&lt;StackSlotValue&gt;(
+                0, value-&gt;origin(), sizeofType(value-&gt;type()), StackSlotKind::Anonymous);
+            phiMap.add(value, phiStack);
+        }
+    }
+    insertionSet.execute(proc[0]);
+
+    if (verbose) {
+        dataLog(&quot;Demoting values as follows:\n&quot;);
+        dataLog(&quot;   map = &quot;);
+        CommaPrinter comma;
+        for (auto&amp; entry : map)
+            dataLog(comma, *entry.key, &quot;=&gt;&quot;, *entry.value);
+        dataLog(&quot;\n&quot;);
+        dataLog(&quot;   phiMap = &quot;);
+        comma = CommaPrinter();
+        for (auto&amp; entry : phiMap)
+            dataLog(comma, *entry.key, &quot;=&gt;&quot;, *entry.value);
+        dataLog(&quot;\n&quot;);
+    }
+
+    // Change accesses to the values to accesses to the stack slots.
+    for (BasicBlock* block : proc) {
+        for (unsigned valueIndex = 0; valueIndex &lt; block-&gt;size(); ++valueIndex) {
+            Value* value = block-&gt;at(valueIndex);
+
+            if (value-&gt;opcode() == Phi) {
+                if (StackSlotValue* stack = phiMap.get(value)) {
+                    value-&gt;replaceWithIdentity(
+                        insertionSet.insert&lt;MemoryValue&gt;(
+                            valueIndex, Load, value-&gt;type(), value-&gt;origin(), stack));
+                }
+            } else {
+                for (Value*&amp; child : value-&gt;children()) {
+                    if (StackSlotValue* stack = map.get(child)) {
+                        child = insertionSet.insert&lt;MemoryValue&gt;(
+                            valueIndex, Load, child-&gt;type(), value-&gt;origin(), stack);
+                    }
+                }
+
+                if (UpsilonValue* upsilon = value-&gt;as&lt;UpsilonValue&gt;()) {
+                    if (StackSlotValue* stack = phiMap.get(upsilon-&gt;phi())) {
+                        insertionSet.insert&lt;MemoryValue&gt;(
+                            valueIndex, Store, upsilon-&gt;origin(), upsilon-&gt;child(0), stack);
+                        value-&gt;replaceWithNop();
+                    }
+                }
+            }
+
+            if (StackSlotValue* stack = map.get(value)) {
+                insertionSet.insert&lt;MemoryValue&gt;(
+                    valueIndex + 1, Store, value-&gt;origin(), value, stack);
+            }
+        }
+        insertionSet.execute(block);
+    }
+}
+
+bool fixSSA(Procedure&amp; proc)
+{
+    // Collect the stack &quot;variables&quot;. If there aren't any, then we don't have anything to do.
+    // That's a fairly common case.
+    HashMap&lt;StackSlotValue*, Type&gt; stackVariable;
+    for (Value* value : proc.values()) {
+        if (StackSlotValue* stack = value-&gt;as&lt;StackSlotValue&gt;()) {
+            if (stack-&gt;kind() == StackSlotKind::Anonymous)
+                stackVariable.add(stack, Void);
+        }
+    }
+
+    if (stackVariable.isEmpty())
+        return false;
+
+    // Make sure that we know how to optimize all of these. We only know how to handle Load and
+    // Store on anonymous variables.
+    for (Value* value : proc.values()) {
+        auto reject = [&amp;] (Value* value) {
+            if (StackSlotValue* stack = value-&gt;as&lt;StackSlotValue&gt;())
+                stackVariable.remove(stack);
+        };
+        
+        auto handleAccess = [&amp;] (Value* access, Type type) {
+            StackSlotValue* stack = access-&gt;lastChild()-&gt;as&lt;StackSlotValue&gt;();
+            if (!stack)
+                return;
+            
+            if (value-&gt;as&lt;MemoryValue&gt;()-&gt;offset()) {
+                stackVariable.remove(stack);
+                return;
+            }
+
+            auto result = stackVariable.find(stack);
+            if (result == stackVariable.end())
+                return;
+            if (result-&gt;value == Void) {
+                result-&gt;value = type;
+                return;
+            }
+            if (result-&gt;value == type)
+                return;
+            stackVariable.remove(result);
+        };
+        
+        switch (value-&gt;opcode()) {
+        case Load:
+            // We're OK with loads from stack variables at an offset of zero.
+            handleAccess(value, value-&gt;type());
+            break;
+        case Store:
+            // We're OK with stores to stack variables, but not storing stack variables.
+            reject(value-&gt;child(0));
+            handleAccess(value, value-&gt;child(0)-&gt;type());
+            break;
+        default:
+            for (Value* child : value-&gt;children())
+                reject(child);
+            break;
+        }
+    }
+
+    Vector&lt;StackSlotValue*&gt; deadValues;
+    for (auto&amp; entry : stackVariable) {
+        if (entry.value == Void)
+            deadValues.append(entry.key);
+    }
+
+    for (StackSlotValue* deadValue : deadValues) {
+        deadValue-&gt;replaceWithNop();
+        stackVariable.remove(deadValue);
+    }
+
+    if (stackVariable.isEmpty())
+        return false;
+
+    // We know that we have variables to optimize, so do that now.
+    breakCriticalEdges(proc);
+
+    SSACalculator ssa(proc);
+
+    // Create a SSACalculator::Variable for every stack variable.
+    Vector&lt;StackSlotValue*&gt; variableToStack;
+    HashMap&lt;StackSlotValue*, SSACalculator::Variable*&gt; stackToVariable;
+
+    for (auto&amp; entry : stackVariable) {
+        StackSlotValue* stack = entry.key;
+        SSACalculator::Variable* variable = ssa.newVariable();
+        RELEASE_ASSERT(variable-&gt;index() == variableToStack.size());
+        variableToStack.append(stack);
+        stackToVariable.add(stack, variable);
+    }
+
+    // Create Defs for all of the stores to the stack variable.
+    for (BasicBlock* block : proc) {
+        for (Value* value : *block) {
+            if (value-&gt;opcode() != Store)
+                continue;
+
+            StackSlotValue* stack = value-&gt;child(1)-&gt;as&lt;StackSlotValue&gt;();
+            if (!stack)
+                continue;
+
+            if (SSACalculator::Variable* variable = stackToVariable.get(stack))
+                ssa.newDef(variable, block, value-&gt;child(0));
+        }
+    }
+
+    // Decide where Phis are to be inserted. This creates them but does not insert them.
+    ssa.computePhis(
+        [&amp;] (SSACalculator::Variable* variable, BasicBlock* block) -&gt; Value* {
+            StackSlotValue* stack = variableToStack[variable-&gt;index()];
+            Value* phi = proc.add&lt;Value&gt;(Phi, stackVariable.get(stack), stack-&gt;origin());
+            if (verbose) {
+                dataLog(
+                    &quot;Adding Phi for &quot;, pointerDump(stack), &quot; at &quot;, *block, &quot;: &quot;,
+                    deepDump(proc, phi), &quot;\n&quot;);
+            }
+            return phi;
+        });
+
+    // Now perform the conversion.
+    InsertionSet insertionSet(proc);
+    HashMap&lt;StackSlotValue*, Value*&gt; mapping;
+    for (BasicBlock* block : proc.blocksInPreOrder()) {
+        mapping.clear();
+
+        for (auto&amp; entry : stackToVariable) {
+            StackSlotValue* stack = entry.key;
+            SSACalculator::Variable* variable = entry.value;
+
+            SSACalculator::Def* def = ssa.reachingDefAtHead(block, variable);
+            if (def)
+                mapping.set(stack, def-&gt;value());
+        }
+
+        for (SSACalculator::Def* phiDef : ssa.phisForBlock(block)) {
+            StackSlotValue* stack = variableToStack[phiDef-&gt;variable()-&gt;index()];
+
+            insertionSet.insertValue(0, phiDef-&gt;value());
+            mapping.set(stack, phiDef-&gt;value());
+        }
+
+        for (unsigned valueIndex = 0; valueIndex &lt; block-&gt;size(); ++valueIndex) {
+            Value* value = block-&gt;at(valueIndex);
+            value-&gt;performSubstitution();
+
+            switch (value-&gt;opcode()) {
+            case Load: {
+                if (StackSlotValue* stack = value-&gt;child(0)-&gt;as&lt;StackSlotValue&gt;()) {
+                    if (Value* replacement = mapping.get(stack))
+                        value-&gt;replaceWithIdentity(replacement);
+                }
+                break;
+            }
+                
+            case Store: {
+                if (StackSlotValue* stack = value-&gt;child(1)-&gt;as&lt;StackSlotValue&gt;()) {
+                    if (stackToVariable.contains(stack)) {
+                        mapping.set(stack, value-&gt;child(0));
+                        value-&gt;replaceWithNop();
+                    }
+                }
+                break;
+            }
+
+            default:
+                break;
+            }
+        }
+
+        unsigned upsilonInsertionPoint = block-&gt;size() - 1;
+        Origin upsilonOrigin = block-&gt;last()-&gt;origin();
+        for (BasicBlock* successorBlock : block-&gt;successorBlocks()) {
+            for (SSACalculator::Def* phiDef : ssa.phisForBlock(successorBlock)) {
+                Value* phi = phiDef-&gt;value();
+                SSACalculator::Variable* variable = phiDef-&gt;variable();
+                StackSlotValue* stack = variableToStack[variable-&gt;index()];
+
+                Value* mappedValue = mapping.get(stack);
+                if (verbose) {
+                    dataLog(
+                        &quot;Mapped value for &quot;, *stack, &quot; with successor Phi &quot;, *phi, &quot; at end of &quot;,
+                        *block, &quot;: &quot;, pointerDump(mappedValue), &quot;\n&quot;);
+                }
+                
+                if (!mappedValue)
+                    mappedValue = insertionSet.insertBottom(upsilonInsertionPoint, phi);
+                
+                insertionSet.insert&lt;UpsilonValue&gt;(
+                    upsilonInsertionPoint, upsilonOrigin, mappedValue, phi);
+            }
+        }
+
+        insertionSet.execute(block);
+    }
+
+    // Finally, kill the stack slots.
+    for (StackSlotValue* stack : variableToStack)
+        stack-&gt;replaceWithNop();
+
+    if (verbose) {
+        dataLog(&quot;B3 after SSA conversion:\n&quot;);
+        dataLog(proc);
+    }
+
+    return true;
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3FixSSAh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3FixSSA.h (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3FixSSA.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3FixSSA.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef B3FixSSA_h
+#define B3FixSSA_h
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3IndexSet.h&quot;
+#include &quot;B3Value.h&quot;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC { namespace B3 {
+
+class Procedure;
+
+// Turns all mentions of the given values into accesses to anonymous stack slots. This is meant
+// to be used from phases that don't like SSA for whatever reason.
+void demoteValues(Procedure&amp;, const IndexSet&lt;Value&gt;&amp;);
+
+// This fixes SSA for you. Use this after you have done demoteValues() and you have performed
+// whatever evil transformation you needed.
+bool fixSSA(Procedure&amp;);
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3FixSSA_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3FoldPathConstantscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.cpp (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,265 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3FoldPathConstants.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3BasicBlockInlines.h&quot;
+#include &quot;B3ControlValue.h&quot;
+#include &quot;B3Dominators.h&quot;
+#include &quot;B3InsertionSetInlines.h&quot;
+#include &quot;B3PhaseScope.h&quot;
+#include &quot;B3ProcedureInlines.h&quot;
+#include &quot;B3SwitchValue.h&quot;
+#include &quot;B3ValueInlines.h&quot;
+
+namespace JSC { namespace B3 {
+
+namespace {
+
+const bool verbose = false;
+
+class FoldPathConstants {
+public:
+    FoldPathConstants(Procedure&amp; proc)
+        : m_proc(proc)
+        , m_insertionSet(proc)
+    {
+    }
+
+    void run()
+    {
+        bool changed = false;
+
+        if (verbose)
+            dataLog(&quot;B3 before folding path constants: \n&quot;, m_proc, &quot;\n&quot;);
+        
+        // Find all of the values that are the subject of a branch or switch. For any successor
+        // that we dominate, install a value override at that block.
+
+        HashMap&lt;Value*, Vector&lt;Override&gt;&gt; overrides;
+
+        Dominators&amp; dominators = m_proc.dominators();
+        
+        auto addOverride = [&amp;] (
+            BasicBlock* from, Value* value, const Override&amp; override) {
+
+            if (override.block-&gt;numPredecessors() != 1)
+                return;
+            ASSERT(override.block-&gt;predecessor(0) == from);
+
+            Vector&lt;Override&gt;&amp; forValue =
+                overrides.add(value, Vector&lt;Override&gt;()).iterator-&gt;value;
+
+            if (!ASSERT_DISABLED) {
+                for (const Override&amp; otherOverride : forValue)
+                    ASSERT_UNUSED(otherOverride, otherOverride.block != override.block);
+            }
+
+            if (verbose)
+                dataLog(&quot;Overriding &quot;, *value, &quot; from &quot;, *from, &quot;: &quot;, override, &quot;\n&quot;);
+            
+            forValue.append(override);
+        };
+        
+        for (BasicBlock* block : m_proc) {
+            ControlValue* branch = block-&gt;last()-&gt;as&lt;ControlValue&gt;();
+            switch (branch-&gt;opcode()) {
+            case Branch:
+                addOverride(
+                    block, branch-&gt;child(0),
+                    Override::nonZero(branch-&gt;successorBlock(0)));
+                addOverride(
+                    block, branch-&gt;child(0),
+                    Override::constant(branch-&gt;successorBlock(1), 0));
+                break;
+            case Switch:
+                for (const SwitchCase&amp; switchCase : *branch-&gt;as&lt;SwitchValue&gt;()) {
+                    addOverride(
+                        block, branch-&gt;child(0),
+                        Override::constant(switchCase.targetBlock(), switchCase.caseValue()));
+                }
+                break;
+            default:
+                break;
+            }
+        }
+
+        // Install the constants in the override blocks. We use one-shot insertion sets because
+        // each block will get at most one thing inserted into it anyway.
+        for (auto&amp; entry : overrides) {
+            for (Override&amp; override : entry.value) {
+                if (!override.hasValue)
+                    continue;
+                override.valueNode =
+                    m_insertionSet.insertIntConstant(0, entry.key, override.value);
+                m_insertionSet.execute(override.block);
+            }
+        }
+
+        // Replace all uses of a value that has an override with that override, if appropriate.
+        // Certain instructions get special treatment.
+        auto getOverride = [&amp;] (BasicBlock* block, Value* value) -&gt; Override {
+            auto iter = overrides.find(value);
+            if (iter == overrides.end())
+                return Override();
+
+            Vector&lt;Override&gt;&amp; forValue = iter-&gt;value;
+            Override result;
+            for (Override&amp; override : forValue) {
+                if (dominators.dominates(override.block, block)
+                    &amp;&amp; override.isBetterThan(result))
+                    result = override;
+            }
+
+            if (verbose)
+                dataLog(&quot;In block &quot;, *block, &quot; getting override for &quot;, *value, &quot;: &quot;, result, &quot;\n&quot;);
+
+            return result;
+        };
+        
+        for (BasicBlock* block : m_proc) {
+            for (unsigned valueIndex = 0; valueIndex &lt; block-&gt;size(); ++valueIndex) {
+                Value* value = block-&gt;at(valueIndex);
+
+                switch (value-&gt;opcode()) {
+                case Branch: {
+                    ControlValue* branch = value-&gt;as&lt;ControlValue&gt;();
+                    if (getOverride(block, branch-&gt;child(0)).isNonZero) {
+                        branch-&gt;convertToJump(branch-&gt;taken().block());
+                        changed = true;
+                    }
+                    break;
+                }
+
+                case Equal: {
+                    if (value-&gt;child(1)-&gt;isInt(0)
+                        &amp;&amp; getOverride(block, value-&gt;child(0)).isNonZero) {
+                        value-&gt;replaceWithIdentity(
+                            m_insertionSet.insertIntConstant(valueIndex, value, 0));
+                    }
+                    break;
+                }
+
+                case NotEqual: {
+                    if (value-&gt;child(1)-&gt;isInt(0)
+                        &amp;&amp; getOverride(block, value-&gt;child(0)).isNonZero) {
+                        value-&gt;replaceWithIdentity(
+                            m_insertionSet.insertIntConstant(valueIndex, value, 1));
+                    }
+                    break;
+                }
+
+                default:
+                    break;
+                }
+
+                for (Value*&amp; child : value-&gt;children()) {
+                    Override override = getOverride(block, child);
+                    if (override.valueNode)
+                        child = override.valueNode;
+                }
+            }
+        }
+
+        if (changed) {
+            m_proc.resetReachability();
+            m_proc.invalidateCFG();
+        }
+    }
+    
+private:
+    struct Override {
+        Override()
+        {
+        }
+
+        static Override constant(BasicBlock* block, int64_t value)
+        {
+            Override result;
+            result.block = block;
+            result.hasValue = true;
+            result.value = value;
+            if (value)
+                result.isNonZero = true;
+            return result;
+        }
+
+        static Override nonZero(BasicBlock* block)
+        {
+            Override result;
+            result.block = block;
+            result.isNonZero = true;
+            return result;
+        }
+
+        bool isBetterThan(const Override&amp; override)
+        {
+            if (hasValue &amp;&amp; !override.hasValue)
+                return true;
+            if (isNonZero &amp;&amp; !override.isNonZero)
+                return true;
+            return false;
+        }
+
+        void dump(PrintStream&amp; out) const
+        {
+            out.print(&quot;{block = &quot;, pointerDump(block), &quot;, value = &quot;);
+            if (hasValue)
+                out.print(value);
+            else
+                out.print(&quot;&lt;none&gt;&quot;);
+            out.print(&quot;, isNonZero = &quot;, isNonZero);
+            if (valueNode)
+                out.print(&quot;, valueNode = &quot;, *valueNode);
+            out.print(&quot;}&quot;);
+        }
+
+        BasicBlock* block { nullptr };
+        bool hasValue { false };
+        bool isNonZero { false };
+        int64_t value { 0 };
+        Value* valueNode { nullptr };
+    };
+
+    Procedure&amp; m_proc;
+    InsertionSet m_insertionSet;
+};
+
+} // anonymous namespace
+
+void foldPathConstants(Procedure&amp; proc)
+{
+    PhaseScope phaseScope(proc, &quot;foldPathConstants&quot;);
+    FoldPathConstants foldPathConstants(proc);
+    foldPathConstants.run();
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3FoldPathConstantsh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.h (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3FoldPathConstants.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef B3FoldPathConstants_h
+#define B3FoldPathConstants_h
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+class Procedure;
+
+// Does very basic simplification of uses of values that were branched on by a dominating branch.
+
+void foldPathConstants(Procedure&amp;);
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3FoldPathConstants_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Generatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Generate.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Generate.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Generate.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -32,6 +32,8 @@
</span><span class="cx"> #include &quot;AirGenerate.h&quot;
</span><span class="cx"> #include &quot;AirInstInlines.h&quot;
</span><span class="cx"> #include &quot;B3Common.h&quot;
</span><ins>+#include &quot;B3DuplicateTails.h&quot;
+#include &quot;B3FoldPathConstants.h&quot;
</ins><span class="cx"> #include &quot;B3LegalizeMemoryOffsets.h&quot;
</span><span class="cx"> #include &quot;B3LowerMacros.h&quot;
</span><span class="cx"> #include &quot;B3LowerMacrosAfterOptimizations.h&quot;
</span><span class="lines">@@ -73,11 +75,19 @@
</span><span class="cx">     if (shouldValidateIR())
</span><span class="cx">         validate(procedure);
</span><span class="cx"> 
</span><ins>+    if (optLevel &gt;= 1) {
+        reduceDoubleToFloat(procedure);
+        reduceStrength(procedure);
+        duplicateTails(procedure);
+        foldPathConstants(procedure);
+        
+        // FIXME: Add more optimizations here.
+        // https://bugs.webkit.org/show_bug.cgi?id=150507
+    }
+
</ins><span class="cx">     lowerMacros(procedure);
</span><span class="cx"> 
</span><span class="cx">     if (optLevel &gt;= 1) {
</span><del>-        reduceDoubleToFloat(procedure);
-
</del><span class="cx">         reduceStrength(procedure);
</span><span class="cx">         
</span><span class="cx">         // FIXME: Add more optimizations here.
</span><span class="lines">@@ -85,9 +95,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     lowerMacrosAfterOptimizations(procedure);
</span><del>-
</del><span class="cx">     legalizeMemoryOffsets(procedure);
</span><del>-
</del><span class="cx">     moveConstants(procedure);
</span><span class="cx"> 
</span><span class="cx">     if (shouldValidateIR())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3IndexSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3IndexSet.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3IndexSet.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3IndexSet.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx">     template&lt;typename CollectionType&gt;
</span><span class="cx">     class Iterable {
</span><span class="cx">     public:
</span><del>-        Iterable(const CollectionType&amp; collection, const IndexSet&amp; set)
</del><ins>+        Iterable(const CollectionType&amp; collection, const BitVector&amp; set)
</ins><span class="cx">             : m_collection(collection)
</span><span class="cx">             , m_set(set)
</span><span class="cx">         {
</span><span class="lines">@@ -122,7 +122,7 @@
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx">         const CollectionType&amp; m_collection;
</span><del>-        const IndexSet&amp; m_set;
</del><ins>+        const BitVector&amp; m_set;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     // For basic blocks, you do:
</span><span class="lines">@@ -133,7 +133,7 @@
</span><span class="cx">     template&lt;typename CollectionType&gt;
</span><span class="cx">     Iterable&lt;CollectionType&gt; values(const CollectionType&amp; collection) const
</span><span class="cx">     {
</span><del>-        return Iterable&lt;CollectionType&gt;(collection);
</del><ins>+        return Iterable&lt;CollectionType&gt;(collection, indices());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     const BitVector&amp; indices() const { return m_set; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3InsertionSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -45,6 +45,16 @@
</span><span class="cx">     return insertIntConstant(index, likeValue-&gt;origin(), likeValue-&gt;type(), value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* InsertionSet::insertBottom(size_t index, Origin origin, Type type)
+{
+    return insertValue(index, m_procedure.addBottom(origin, type));
+}
+
+Value* InsertionSet::insertBottom(size_t index, Value* likeValue)
+{
+    return insertBottom(index, likeValue-&gt;origin(), likeValue-&gt;type());
+}
+
</ins><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="trunkSourceJavaScriptCoreb3B3InsertionSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3InsertionSet.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3InsertionSet.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3InsertionSet.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -67,6 +67,9 @@
</span><span class="cx">     Value* insertIntConstant(size_t index, Origin, Type, int64_t value);
</span><span class="cx">     Value* insertIntConstant(size_t index, Value* likeValue, int64_t value);
</span><span class="cx"> 
</span><ins>+    Value* insertBottom(size_t index, Origin, Type);
+    Value* insertBottom(size_t index, Value*);
+
</ins><span class="cx">     void execute(BasicBlock*);
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -88,6 +88,8 @@
</span><span class="cx">             switch (value-&gt;opcode()) {
</span><span class="cx">             case Phi: {
</span><span class="cx">                 m_phiToTmp[value] = m_code.newTmp(Arg::typeForB3Type(value-&gt;type()));
</span><ins>+                if (verbose)
+                    dataLog(&quot;Phi tmp for &quot;, *value, &quot;: &quot;, m_phiToTmp[value], &quot;\n&quot;);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case B3::StackSlot: {
</span><span class="lines">@@ -306,6 +308,8 @@
</span><span class="cx">                 realTmp = m_code.newTmp(Arg::typeForB3Type(value-&gt;type()));
</span><span class="cx">                 if (m_procedure.isFastConstant(value-&gt;key()))
</span><span class="cx">                     m_code.addFastTmp(realTmp);
</span><ins>+                if (verbose)
+                    dataLog(&quot;Tmp for &quot;, *value, &quot;: &quot;, realTmp, &quot;\n&quot;);
</ins><span class="cx">             }
</span><span class="cx">             tmp = realTmp;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3MemoryValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3MemoryValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3MemoryValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3MemoryValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -61,6 +61,11 @@
</span><span class="cx">         out.print(comma, &quot;offset = &quot;, m_offset);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* MemoryValue::cloneImpl() const
+{
+    return new MemoryValue(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3MemoryValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3MemoryValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3MemoryValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3MemoryValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -65,6 +65,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp; comma, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3OriginDumpcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3OriginDump.cpp (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3OriginDump.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3OriginDump.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3OriginDump.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3Procedure.h&quot;
+
+namespace JSC { namespace B3 {
+
+void OriginDump::dump(PrintStream&amp; out) const
+{
+    if (m_proc)
+        m_proc-&gt;printOrigin(out, m_origin);
+    else
+        out.print(m_origin);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3OriginDumph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3OriginDump.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3OriginDump.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3OriginDump.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,25 +29,23 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;B3Origin.h&quot;
</span><del>-#include &quot;B3Procedure.h&quot;
</del><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><ins>+class Procedure;
+
</ins><span class="cx"> class OriginDump {
</span><span class="cx"> public:
</span><del>-    OriginDump(const Procedure&amp; proc, Origin origin)
</del><ins>+    OriginDump(const Procedure* proc, Origin origin)
</ins><span class="cx">         : m_proc(proc)
</span><span class="cx">         , m_origin(origin)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void dump(PrintStream&amp; out) const
-    {
-        m_proc.printOrigin(out, m_origin);
-    }
</del><ins>+    void dump(PrintStream&amp; out) const;
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    const Procedure&amp; m_proc;
</del><ins>+    const Procedure* m_proc;
</ins><span class="cx">     Origin m_origin;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3PatchpointValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3PatchpointValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -44,6 +44,11 @@
</span><span class="cx">         out.print(comma, &quot;numFPScratchRegisters = &quot;, numFPScratchRegisters);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* PatchpointValue::cloneImpl() const
+{
+    return new PatchpointValue(*this);
+}
+
</ins><span class="cx"> PatchpointValue::PatchpointValue(unsigned index, Type type, Origin origin)
</span><span class="cx">     : Base(index, CheckedOpcode, Patchpoint, type, origin)
</span><span class="cx">     , effects(Effects::forCall())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3PatchpointValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3PatchpointValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -65,6 +65,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -68,6 +68,16 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* Procedure::clone(Value* value)
+{
+    std::unique_ptr&lt;Value&gt; clone(value-&gt;cloneImpl());
+    Value* result = clone.get();
+    clone-&gt;m_index = addValueIndex();
+    clone-&gt;owner = nullptr;
+    m_values[clone-&gt;m_index] = WTFMove(clone);
+    return result;
+}
+
</ins><span class="cx"> Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
</span><span class="cx"> {
</span><span class="cx">     switch (type) {
</span><span class="lines">@@ -90,6 +100,16 @@
</span><span class="cx">     return addIntConstant(likeValue-&gt;origin(), likeValue-&gt;type(), value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* Procedure::addBottom(Origin origin, Type type)
+{
+    return addIntConstant(origin, type, 0);
+}
+
+Value* Procedure::addBottom(Value* value)
+{
+    return addBottom(value-&gt;origin(), value-&gt;type());
+}
+
</ins><span class="cx"> Value* Procedure::addBoolConstant(Origin origin, TriState triState)
</span><span class="cx"> {
</span><span class="cx">     int32_t value = 0;
</span><span class="lines">@@ -165,7 +185,7 @@
</span><span class="cx"> 
</span><span class="cx"> void Procedure::deleteValue(Value* value)
</span><span class="cx"> {
</span><del>-    ASSERT(m_values[value-&gt;index()].get() == value);
</del><ins>+    RELEASE_ASSERT(m_values[value-&gt;index()].get() == value);
</ins><span class="cx">     m_valueIndexFreeList.append(value-&gt;index());
</span><span class="cx">     m_values[value-&gt;index()] = nullptr;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -76,9 +76,14 @@
</span><span class="cx">     template&lt;typename ValueType, typename... Arguments&gt;
</span><span class="cx">     ValueType* add(Arguments...);
</span><span class="cx"> 
</span><ins>+    Value* clone(Value*);
+
</ins><span class="cx">     Value* addIntConstant(Origin, Type, int64_t value);
</span><span class="cx">     Value* addIntConstant(Value*, int64_t value);
</span><span class="cx"> 
</span><ins>+    Value* addBottom(Origin, Type);
+    Value* addBottom(Value*);
+
</ins><span class="cx">     // Returns null for MixedTriState.
</span><span class="cx">     Value* addBoolConstant(Origin, TriState);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;B3BasicBlockInlines.h&quot;
</span><ins>+#include &quot;B3BlockInsertionSet.h&quot;
</ins><span class="cx"> #include &quot;B3ControlValue.h&quot;
</span><span class="cx"> #include &quot;B3Dominators.h&quot;
</span><span class="cx"> #include &quot;B3IndexSet.h&quot;
</span><span class="lines">@@ -258,6 +259,7 @@
</span><span class="cx">     ReduceStrength(Procedure&amp; proc)
</span><span class="cx">         : m_proc(proc)
</span><span class="cx">         , m_insertionSet(proc)
</span><ins>+        , m_blockInsertionSet(proc)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -286,6 +288,11 @@
</span><span class="cx">                 m_block = block;
</span><span class="cx">                 
</span><span class="cx">                 for (m_index = 0; m_index &lt; block-&gt;size(); ++m_index) {
</span><ins>+                    if (verbose) {
+                        dataLog(
+                            &quot;Looking at &quot;, *block, &quot; #&quot;, m_index, &quot;: &quot;,
+                            deepDump(m_proc, block-&gt;at(m_index)), &quot;\n&quot;);
+                    }
</ins><span class="cx">                     m_value = m_block-&gt;at(m_index);
</span><span class="cx">                     m_value-&gt;performSubstitution();
</span><span class="cx">                     
</span><span class="lines">@@ -295,6 +302,13 @@
</span><span class="cx">                 m_insertionSet.execute(m_block);
</span><span class="cx">             }
</span><span class="cx"> 
</span><ins>+            if (m_blockInsertionSet.execute()) {
+                m_proc.resetReachability();
+                m_proc.invalidateCFG();
+                m_dominators = &amp;m_proc.dominators(); // Recompute if necessary.
+                m_changedCFG = true;
+            }
+            
</ins><span class="cx">             simplifyCFG();
</span><span class="cx"> 
</span><span class="cx">             if (m_changedCFG) {
</span><span class="lines">@@ -1387,6 +1401,51 @@
</span><span class="cx">                 &amp;&amp; checkValue-&gt;child(0)-&gt;child(1)-&gt;isInt(0)) {
</span><span class="cx">                 checkValue-&gt;child(0) = checkValue-&gt;child(0)-&gt;child(0);
</span><span class="cx">                 m_changed = true;
</span><ins>+            }
+
+            // If we are checking some bounded-size SSA expression that leads to a Select that
+            // has a constant as one of its results, then turn the Select into a Branch and split
+            // the code between the Check and the Branch. For example, this:
+            //
+            //     @a = Select(@p, @x, 42)
+            //     @b = Add(@a, 35)
+            //     Check(@b)
+            //
+            // becomes this:
+            //
+            //     Branch(@p, #truecase, #falsecase)
+            //
+            //   BB#truecase:
+            //     @b_truecase = Add(@x, 35)
+            //     Check(@b_truecase)
+            //     Upsilon(@x, ^a)
+            //     Upsilon(@b_truecase, ^b)
+            //     Jump(#continuation)
+            //
+            //   BB#falsecase:
+            //     @b_falsecase = Add(42, 35)
+            //     Check(@b_falsecase)
+            //     Upsilon(42, ^a)
+            //     Upsilon(@b_falsecase, ^b)
+            //     Jump(#continuation)
+            //
+            //   BB#continuation:
+            //     @a = Phi()
+            //     @b = Phi()
+            //
+            // The goal of this optimization is to kill a lot of code in one of those basic
+            // blocks. This is pretty much guaranteed since one of those blocks will replace all
+            // uses of the Select with a constant, and that constant will be transitively used
+            // from the check.
+            static const unsigned selectSpecializationBound = 3;
+            Value* select = findRecentNodeMatching(
+                m_value-&gt;child(0), selectSpecializationBound,
+                [&amp;] (Value* value) -&gt; bool {
+                    return value-&gt;opcode() == Select
+                        &amp;&amp; (value-&gt;child(1)-&gt;isConstant() &amp;&amp; value-&gt;child(2)-&gt;isConstant());
+                });
+            if (select) {
+                specializeSelect(select);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             break;
</span><span class="lines">@@ -1458,6 +1517,148 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Find a node that:
+    //     - functor(node) returns true.
+    //     - it's reachable from the given node via children.
+    //     - it's in the last &quot;bound&quot; slots in the current basic block.
+    // This algorithm is optimized under the assumption that the bound is small.
+    template&lt;typename Functor&gt;
+    Value* findRecentNodeMatching(Value* start, unsigned bound, const Functor&amp; functor)
+    {
+        unsigned startIndex = bound &lt; m_index ? m_index - bound : 0;
+        Value* result = nullptr;
+        start-&gt;walk(
+            [&amp;] (Value* value) -&gt; Value::WalkStatus {
+                bool found = false;
+                for (unsigned i = startIndex; i &lt;= m_index; ++i) {
+                    if (m_block-&gt;at(i) == value)
+                        found = true;
+                }
+                if (!found)
+                    return Value::IgnoreChildren;
+
+                if (functor(value)) {
+                    result = value;
+                    return Value::Stop;
+                }
+
+                return Value::Continue;
+            });
+        return result;
+    }
+
+    // This specializes a sequence of code up to a Select. This doesn't work when we're at a
+    // terminal. It would be cool to fix that eventually. The main problem is that instead of
+    // splitting the block, we should just insert the then/else blocks. We'll have to create
+    // double the Phis and double the Upsilons. It'll probably be the sort of optimization that
+    // we want to do only after we've done loop optimizations, since this will *definitely*
+    // obscure things. In fact, even this simpler form of select specialization will possibly
+    // obscure other optimizations. It would be great to have two modes of strength reduction,
+    // one that does obscuring optimizations and runs late, and another that does not do
+    // obscuring optimizations and runs early.
+    // FIXME: Make select specialization handle branches.
+    // FIXME: Have a form of strength reduction that does no obscuring optimizations and runs
+    // early.
+    void specializeSelect(Value* source)
+    {
+        if (verbose)
+            dataLog(&quot;Specializing select: &quot;, deepDump(m_proc, source), &quot;\n&quot;);
+
+        // This mutates startIndex to account for the fact that m_block got the front of it
+        // chopped off.
+        BasicBlock* predecessor =
+            m_blockInsertionSet.splitForward(m_block, m_index, &amp;m_insertionSet);
+
+        // Splitting will commit the insertion set, which changes the exact position of the
+        // source. That's why we do the search after splitting.
+        unsigned startIndex = UINT_MAX;
+        for (unsigned i = predecessor-&gt;size(); i--;) {
+            if (predecessor-&gt;at(i) == source) {
+                startIndex = i;
+                break;
+            }
+        }
+        
+        RELEASE_ASSERT(startIndex != UINT_MAX);
+
+        // By BasicBlock convention, caseIndex == 0 =&gt; then, caseIndex == 1 =&gt; else.
+        static const unsigned numCases = 2;
+        BasicBlock* cases[numCases];
+        for (unsigned i = 0; i &lt; numCases; ++i)
+            cases[i] = m_blockInsertionSet.insertBefore(m_block);
+
+        HashMap&lt;Value*, Value*&gt; mappings[2];
+
+        // Save things we want to know about the source.
+        Value* predicate = source-&gt;child(0);
+
+        for (unsigned i = 0; i &lt; numCases; ++i)
+            mappings[i].add(source, source-&gt;child(1 + i));
+
+        auto cloneValue = [&amp;] (Value* value) {
+            ASSERT(value != source);
+
+            for (unsigned i = 0; i &lt; numCases; ++i) {
+                Value* clone = m_proc.clone(value);
+                for (Value*&amp; child : clone-&gt;children()) {
+                    if (Value* newChild = mappings[i].get(child))
+                        child = newChild;
+                }
+                if (value-&gt;type() != Void)
+                    mappings[i].add(value, clone);
+
+                cases[i]-&gt;append(clone);
+                if (value-&gt;type() != Void)
+                    cases[i]-&gt;appendNew&lt;UpsilonValue&gt;(m_proc, value-&gt;origin(), clone, value);
+            }
+
+            value-&gt;replaceWithPhi();
+        };
+
+        // The jump that the splitter inserted is of no use to us.
+        predecessor-&gt;removeLast(m_proc);
+
+        // Hance the source, it's special.
+        for (unsigned i = 0; i &lt; numCases; ++i) {
+            cases[i]-&gt;appendNew&lt;UpsilonValue&gt;(
+                m_proc, source-&gt;origin(), source-&gt;child(1 + i), source);
+        }
+        source-&gt;replaceWithPhi();
+        m_insertionSet.insertValue(m_index, source);
+
+        // Now handle all values between the source and the check.
+        for (unsigned i = startIndex + 1; i &lt; predecessor-&gt;size(); ++i) {
+            Value* value = predecessor-&gt;at(i);
+            value-&gt;owner = nullptr;
+
+            cloneValue(value);
+
+            if (value-&gt;type() != Void)
+                m_insertionSet.insertValue(m_index, value);
+            else
+                m_proc.deleteValue(value);
+        }
+
+        // Finally, deal with the check.
+        cloneValue(m_value);
+
+        // Remove the values from the predecessor.
+        predecessor-&gt;values().resize(startIndex);
+        
+        predecessor-&gt;appendNew&lt;ControlValue&gt;(
+            m_proc, Branch, source-&gt;origin(), predicate,
+            FrequentedBlock(cases[0]), FrequentedBlock(cases[1]));
+
+        for (unsigned i = 0; i &lt; numCases; ++i) {
+            cases[i]-&gt;appendNew&lt;ControlValue&gt;(
+                m_proc, Jump, m_value-&gt;origin(), FrequentedBlock(m_block));
+        }
+
+        m_changed = true;
+
+        predecessor-&gt;updatePredecessorsAfter();
+    }
+
</ins><span class="cx">     // Turn this: Add(constant, value)
</span><span class="cx">     // Into this: Add(value, constant)
</span><span class="cx">     //
</span><span class="lines">@@ -1836,6 +2037,7 @@
</span><span class="cx"> 
</span><span class="cx">     Procedure&amp; m_proc;
</span><span class="cx">     InsertionSet m_insertionSet;
</span><ins>+    BlockInsertionSet m_blockInsertionSet;
</ins><span class="cx">     BasicBlock* m_block { nullptr };
</span><span class="cx">     unsigned m_index { 0 };
</span><span class="cx">     Value* m_value { nullptr };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3SSACalculatorcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3SSACalculator.cpp (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3SSACalculator.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3SSACalculator.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,150 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;B3SSACalculator.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3BasicBlockInlines.h&quot;
+#include &lt;wtf/CommaPrinter.h&gt;
+#include &lt;wtf/ListDump.h&gt;
+
+namespace JSC { namespace B3 {
+
+void SSACalculator::Variable::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;var&quot;, m_index);
+}
+
+void SSACalculator::Variable::dumpVerbose(PrintStream&amp; out) const
+{
+    dump(out);
+    if (!m_blocksWithDefs.isEmpty()) {
+        out.print(&quot;(defs: &quot;);
+        CommaPrinter comma;
+        for (BasicBlock* block : m_blocksWithDefs)
+            out.print(comma, *block);
+        out.print(&quot;)&quot;);
+    }
+}
+
+void SSACalculator::Def::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;def(&quot;, *m_variable, &quot;, &quot;, *m_block, &quot;, &quot;, pointerDump(m_value), &quot;)&quot;);
+}
+
+SSACalculator::SSACalculator(Procedure&amp; proc)
+    : m_data(proc.size())
+    , m_proc(proc)
+{
+}
+
+SSACalculator::~SSACalculator()
+{
+}
+
+void SSACalculator::reset()
+{
+    m_variables.clear();
+    m_defs.clear();
+    m_phis.clear();
+    for (unsigned blockIndex = m_data.size(); blockIndex--;) {
+        m_data[blockIndex].m_defs.clear();
+        m_data[blockIndex].m_phis.clear();
+    }
+}
+
+SSACalculator::Variable* SSACalculator::newVariable()
+{
+    return &amp;m_variables.alloc(Variable(m_variables.size()));
+}
+
+SSACalculator::Def* SSACalculator::newDef(Variable* variable, BasicBlock* block, Value* value)
+{
+    Def* def = m_defs.add(Def(variable, block, value));
+    auto result = m_data[block].m_defs.add(variable, def);
+    if (result.isNewEntry)
+        variable-&gt;m_blocksWithDefs.append(block);
+    else
+        result.iterator-&gt;value = def;
+    return def;
+}
+
+SSACalculator::Def* SSACalculator::nonLocalReachingDef(BasicBlock* block, Variable* variable)
+{
+    return reachingDefAtTail(m_dominators-&gt;idom(block), variable);
+}
+
+SSACalculator::Def* SSACalculator::reachingDefAtTail(BasicBlock* block, Variable* variable)
+{
+    for (; block; block = m_dominators-&gt;idom(block)) {
+        if (Def* def = m_data[block].m_defs.get(variable))
+            return def;
+    }
+    return nullptr;
+}
+
+void SSACalculator::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;&lt;Variables: [&quot;);
+    CommaPrinter comma;
+    for (unsigned i = 0; i &lt; m_variables.size(); ++i) {
+        out.print(comma);
+        m_variables[i].dumpVerbose(out);
+    }
+    out.print(&quot;], Defs: [&quot;);
+    comma = CommaPrinter();
+    for (Def* def : const_cast&lt;SSACalculator*&gt;(this)-&gt;m_defs)
+        out.print(comma, *def);
+    out.print(&quot;], Phis: [&quot;);
+    comma = CommaPrinter();
+    for (Def* def : const_cast&lt;SSACalculator*&gt;(this)-&gt;m_phis)
+        out.print(comma, *def);
+    out.print(&quot;], Block data: [&quot;);
+    comma = CommaPrinter();
+    for (unsigned blockIndex = 0; blockIndex &lt; m_proc.size(); ++blockIndex) {
+        BasicBlock* block = m_proc[blockIndex];
+        if (!block)
+            continue;
+        
+        out.print(comma, *block, &quot;=&gt;(&quot;);
+        out.print(&quot;Defs: {&quot;);
+        CommaPrinter innerComma;
+        for (auto entry : m_data[block].m_defs)
+            out.print(innerComma, *entry.key, &quot;-&gt;&quot;, *entry.value);
+        out.print(&quot;}, Phis: {&quot;);
+        innerComma = CommaPrinter();
+        for (Def* def : m_data[block].m_phis)
+            out.print(innerComma, *def);
+        out.print(&quot;})&quot;);
+    }
+    out.print(&quot;]&gt;&quot;);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3SSACalculatorh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3SSACalculator.h (0 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3SSACalculator.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3SSACalculator.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -0,0 +1,171 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef B3SSACalculator_h
+#define B3SSACalculator_h
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3Dominators.h&quot;
+#include &quot;B3IndexMap.h&quot;
+#include &quot;B3ProcedureInlines.h&quot;
+#include &lt;wtf/Bag.h&gt;
+#include &lt;wtf/SegmentedVector.h&gt;
+
+namespace JSC { namespace B3 {
+
+// SSACalculator provides a reusable tool for building SSA's. It's modeled after
+// DFG::SSACalculator.
+
+class SSACalculator {
+public:
+    SSACalculator(Procedure&amp;);
+    ~SSACalculator();
+
+    void reset();
+
+    class Variable {
+    public:
+        unsigned index() const { return m_index; }
+        
+        void dump(PrintStream&amp;) const;
+        void dumpVerbose(PrintStream&amp;) const;
+        
+    private:
+        friend class SSACalculator;
+        
+        Variable()
+            : m_index(UINT_MAX)
+        {
+        }
+        
+        Variable(unsigned index)
+            : m_index(index)
+        {
+        }
+
+        Vector&lt;BasicBlock*, 4&gt; m_blocksWithDefs;
+        unsigned m_index;
+    };
+
+    class Def {
+    public:
+        Variable* variable() const { return m_variable; }
+        BasicBlock* block() const { return m_block; }
+        
+        Value* value() const { return m_value; }
+        
+        void dump(PrintStream&amp;) const;
+        
+    private:
+        friend class SSACalculator;
+        
+        Def()
+            : m_variable(nullptr)
+            , m_block(nullptr)
+            , m_value(nullptr)
+        {
+        }
+        
+        Def(Variable* variable, BasicBlock* block, Value* value)
+            : m_variable(variable)
+            , m_block(block)
+            , m_value(value)
+        {
+        }
+        
+        Variable* m_variable;
+        BasicBlock* m_block;
+        Value* m_value;
+    };
+
+    Variable* newVariable();
+    Def* newDef(Variable*, BasicBlock*, Value*);
+
+    Variable* variable(unsigned index) { return &amp;m_variables[index]; }
+
+    template&lt;typename Functor&gt;
+    void computePhis(const Functor&amp; functor)
+    {
+        m_dominators = &amp;m_proc.dominators();
+        for (Variable&amp; variable : m_variables) {
+            m_dominators-&gt;forAllBlocksInPrunedIteratedDominanceFrontierOf(
+                variable.m_blocksWithDefs,
+                [&amp;] (BasicBlock* block) -&gt; bool {
+                    Value* phi = functor(&amp;variable, block);
+                    if (!phi)
+                        return false;
+
+                    BlockData&amp; data = m_data[block];
+                    Def* phiDef = m_phis.add(Def(&amp;variable, block, phi));
+                    data.m_phis.append(phiDef);
+
+                    data.m_defs.add(&amp;variable, phiDef);
+                    return true;
+                });
+        }
+    }
+
+    const Vector&lt;Def*&gt;&amp; phisForBlock(BasicBlock* block)
+    {
+        return m_data[block].m_phis;
+    }
+    
+    // Ignores defs within the given block; it assumes that you've taken care of those
+    // yourself.
+    Def* nonLocalReachingDef(BasicBlock*, Variable*);
+    Def* reachingDefAtHead(BasicBlock* block, Variable* variable)
+    {
+        return nonLocalReachingDef(block, variable);
+    }
+    
+    // Considers the def within the given block, but only works at the tail of the block.
+    Def* reachingDefAtTail(BasicBlock*, Variable*);
+    
+    void dump(PrintStream&amp;) const;
+    
+private:
+    SegmentedVector&lt;Variable&gt; m_variables;
+    Bag&lt;Def&gt; m_defs;
+    
+    Bag&lt;Def&gt; m_phis;
+    
+    struct BlockData {
+        HashMap&lt;Variable*, Def*&gt; m_defs;
+        Vector&lt;Def*&gt; m_phis;
+    };
+    
+    IndexMap&lt;BasicBlock, BlockData&gt; m_data;
+
+    Dominators* m_dominators { nullptr };
+    Procedure&amp; m_proc;
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3SSACalculator_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackSlotKindh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3StackSlotKind.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -36,9 +36,8 @@
</span><span class="cx">     // slot.
</span><span class="cx">     Locked,
</span><span class="cx"> 
</span><del>-    // These stack slots could share space with other stack slots, provided that they aren't live
-    // at the same time. The compiler still has to do escape analysis, since these can be escaped
-    // explicitly in IR.
</del><ins>+    // These stack slots behave like variables. Undefined behavior happens if you store less than
+    // the width of the slot.
</ins><span class="cx">     Anonymous
</span><span class="cx"> 
</span><span class="cx">     // FIXME: We should add a third mode, which means that the stack slot will be read asynchronously
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackSlotValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackSlotValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackSlotValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3StackSlotValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -39,6 +39,11 @@
</span><span class="cx">     out.print(comma, &quot;byteSize = &quot;, m_byteSize, &quot;, kind = &quot;, m_kind);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* StackSlotValue::cloneImpl() const
+{
+    return new StackSlotValue(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3StackSlotValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3StackSlotValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3StackSlotValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3StackSlotValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -59,6 +59,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class Air::StackSlot;
</span><span class="cx">     friend class Procedure;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3SwitchValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3SwitchValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -63,6 +63,11 @@
</span><span class="cx">     out.print(comma, &quot;fallThrough = &quot;, fallThrough());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* SwitchValue::cloneImpl() const
+{
+    return new SwitchValue(*this);
+}
+
</ins><span class="cx"> SwitchValue::SwitchValue(
</span><span class="cx">     unsigned index, Origin origin, Value* child, const FrequentedBlock&amp; fallThrough)
</span><span class="cx">     : ControlValue(index, Switch, Void, origin, child)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3SwitchValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3SwitchValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3SwitchValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3SwitchValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -116,6 +116,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3UpsilonValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3UpsilonValue.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3UpsilonValue.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3UpsilonValue.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -45,6 +45,11 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* UpsilonValue::cloneImpl() const
+{
+    return new UpsilonValue(*this);
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3UpsilonValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3UpsilonValue.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -49,6 +49,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span><span class="cx"> 
</span><ins>+    Value* cloneImpl() const override;
+
</ins><span class="cx"> private:
</span><span class="cx">     friend class Procedure;
</span><span class="cx"> 
</span><span class="lines">@@ -59,10 +61,8 @@
</span><span class="cx">         : Value(index, CheckedOpcode, Upsilon, Void, origin, value)
</span><span class="cx">         , m_phi(phi)
</span><span class="cx">     {
</span><del>-        if (phi) {
</del><ins>+        if (phi)
</ins><span class="cx">             ASSERT(value-&gt;type() == phi-&gt;type());
</span><del>-            ASSERT(phi-&gt;opcode() == Phi);
-        }
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Value* m_phi;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Validatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Validate.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -352,6 +352,7 @@
</span><span class="cx">             case Upsilon:
</span><span class="cx">                 VALIDATE(value-&gt;numChildren() == 1, (&quot;At &quot;, *value));
</span><span class="cx">                 VALIDATE(value-&gt;as&lt;UpsilonValue&gt;()-&gt;phi(), (&quot;At &quot;, *value));
</span><ins>+                VALIDATE(value-&gt;as&lt;UpsilonValue&gt;()-&gt;phi()-&gt;opcode() == Phi, (&quot;At &quot;, *value));
</ins><span class="cx">                 VALIDATE(value-&gt;child(0)-&gt;type() == value-&gt;as&lt;UpsilonValue&gt;()-&gt;phi()-&gt;type(), (&quot;At &quot;, *value));
</span><span class="cx">                 VALIDATE(valueInProc.contains(value-&gt;as&lt;UpsilonValue&gt;()-&gt;phi()), (&quot;At &quot;, *value));
</span><span class="cx">                 break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Value.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -89,18 +89,42 @@
</span><span class="cx">     this-&gt;owner = owner;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Value::replaceWithPhi()
+{
+    if (m_type == Void) {
+        replaceWithNop();
+        return;
+    }
+    
+    unsigned index = m_index;
+    Origin origin = m_origin;
+    BasicBlock* owner = this-&gt;owner;
+    Type type = m_type;
+
+    this-&gt;Value::~Value();
+
+    new (this) Value(index, Phi, type, origin);
+
+    this-&gt;owner = owner;
+}
+
</ins><span class="cx"> void Value::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     out.print(dumpPrefix, m_index);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Value* Value::cloneImpl() const
+{
+    return new Value(*this);
+}
+
</ins><span class="cx"> void Value::dumpChildren(CommaPrinter&amp; comma, PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     for (Value* child : children())
</span><span class="cx">         out.print(comma, pointerDump(child));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Value::deepDump(const Procedure&amp; proc, PrintStream&amp; out) const
</del><ins>+void Value::deepDump(const Procedure* proc, PrintStream&amp; out) const
</ins><span class="cx"> {
</span><span class="cx">     out.print(m_type, &quot; &quot;, *this, &quot; = &quot;, m_opcode);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3Value.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -42,10 +42,10 @@
</span><span class="cx"> 
</span><span class="cx"> class BasicBlock;
</span><span class="cx"> class CheckValue;
</span><ins>+class PhiChildren;
</ins><span class="cx"> class Procedure;
</span><span class="cx"> 
</span><span class="cx"> class JS_EXPORT_PRIVATE Value {
</span><del>-    WTF_MAKE_NONCOPYABLE(Value);
</del><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     typedef Vector&lt;Value*, 3&gt; AdjacencyList;
</span><span class="lines">@@ -84,9 +84,10 @@
</span><span class="cx"> 
</span><span class="cx">     void replaceWithIdentity(Value*);
</span><span class="cx">     void replaceWithNop();
</span><ins>+    void replaceWithPhi();
</ins><span class="cx"> 
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><del>-    void deepDump(const Procedure&amp;, PrintStream&amp;) const;
</del><ins>+    void deepDump(const Procedure*, PrintStream&amp;) const;
</ins><span class="cx"> 
</span><span class="cx">     // This is how you cast Values. For example, if you want to do something provided that we have a
</span><span class="cx">     // ArgumentRegValue, you can do:
</span><span class="lines">@@ -204,7 +205,22 @@
</span><span class="cx">     // of Identity's.
</span><span class="cx">     void performSubstitution();
</span><span class="cx"> 
</span><ins>+    // Walk the ancestors of this value (i.e. the graph of things it transitively uses). This
+    // either walks phis or not, depending on whether PhiChildren is null. Your callback gets
+    // called with the signature:
+    //
+    //     (Value*) -&gt; WalkStatus
+    enum WalkStatus {
+        Continue,
+        IgnoreChildren,
+        Stop
+    };
+    template&lt;typename Functor&gt;
+    void walk(const Functor&amp; functor, PhiChildren* = nullptr);
+
</ins><span class="cx"> protected:
</span><ins>+    virtual Value* cloneImpl() const;
+    
</ins><span class="cx">     virtual void dumpChildren(CommaPrinter&amp;, PrintStream&amp;) const;
</span><span class="cx">     virtual void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const;
</span><span class="cx"> 
</span><span class="lines">@@ -220,6 +236,9 @@
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     enum CheckedOpcodeTag { CheckedOpcode };
</span><ins>+
+    Value(const Value&amp;) = default;
+    Value&amp; operator=(const Value&amp;) = default;
</ins><span class="cx">     
</span><span class="cx">     // Instantiate values via Procedure.
</span><span class="cx">     // This form requires specifying the type explicitly:
</span><span class="lines">@@ -315,7 +334,7 @@
</span><span class="cx"> 
</span><span class="cx"> class DeepValueDump {
</span><span class="cx"> public:
</span><del>-    DeepValueDump(const Procedure&amp; proc, const Value* value)
</del><ins>+    DeepValueDump(const Procedure* proc, const Value* value)
</ins><span class="cx">         : m_proc(proc)
</span><span class="cx">         , m_value(value)
</span><span class="cx">     {
</span><span class="lines">@@ -330,14 +349,18 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    const Procedure&amp; m_proc;
</del><ins>+    const Procedure* m_proc;
</ins><span class="cx">     const Value* m_value;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline DeepValueDump deepDump(const Procedure&amp; proc, const Value* value)
</span><span class="cx"> {
</span><del>-    return DeepValueDump(proc, value);
</del><ins>+    return DeepValueDump(&amp;proc, value);
</ins><span class="cx"> }
</span><ins>+inline DeepValueDump deepDump(const Value* value)
+{
+    return DeepValueDump(nullptr, value);
+}
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ValueInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ValueInlines.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ValueInlines.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ValueInlines.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -34,8 +34,10 @@
</span><span class="cx"> #include &quot;B3ConstDoubleValue.h&quot;
</span><span class="cx"> #include &quot;B3ConstFloatValue.h&quot;
</span><span class="cx"> #include &quot;B3PatchpointValue.h&quot;
</span><ins>+#include &quot;B3PhiChildren.h&quot;
</ins><span class="cx"> #include &quot;B3Procedure.h&quot;
</span><span class="cx"> #include &quot;B3Value.h&quot;
</span><ins>+#include &lt;wtf/GraphNodeWorklist.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><span class="lines">@@ -204,6 +206,29 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;typename Functor&gt;
+void Value::walk(const Functor&amp; functor, PhiChildren* phiChildren)
+{
+    GraphNodeWorklist&lt;Value*&gt; worklist;
+    worklist.push(this);
+    while (Value* value = worklist.pop()) {
+        WalkStatus status = functor(value);
+        switch (status) {
+        case Continue:
+            if (value-&gt;opcode() == Phi) {
+                if (phiChildren)
+                    worklist.pushAll(phiChildren-&gt;at(value).values());
+            } else
+                worklist.pushAll(value-&gt;children());
+            break;
+        case IgnoreChildren:
+            break;
+        case Stop:
+            return;
+        }
+    }
+}
+
</ins><span class="cx"> } } // namespace JSC::B3
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ValueKeycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ValueKey.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ValueKey.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ValueKey.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -35,6 +35,19 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><ins>+ValueKey ValueKey::intConstant(Type type, int64_t value)
+{
+    switch (type) {
+    case Int32:
+        return ValueKey(Const32, Int32, value);
+    case Int64:
+        return ValueKey(Const64, Int64, value);
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+        return ValueKey();
+    }
+}
+
</ins><span class="cx"> void ValueKey::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     out.print(m_type, &quot; &quot;, m_opcode, &quot;(&quot;, u.indices[0], &quot;, &quot;, u.indices[1], &quot;, &quot;, u.indices[2], &quot;)&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ValueKeyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ValueKey.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ValueKey.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/B3ValueKey.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -85,6 +85,8 @@
</span><span class="cx">         u.floatValue = value;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static ValueKey intConstant(Type type, int64_t value);
+
</ins><span class="cx">     Opcode opcode() const { return m_opcode; }
</span><span class="cx">     Type type() const { return m_type; }
</span><span class="cx">     unsigned childIndex(unsigned index) const { return u.indices[index]; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirCode.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirCode.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/air/AirCode.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;AirArg.h&quot;
</ins><span class="cx"> #include &quot;AirBasicBlock.h&quot;
</span><span class="cx"> #include &quot;AirSpecial.h&quot;
</span><span class="cx"> #include &quot;AirStackSlot.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirIteratedRegisterCoalescingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/air/AirIteratedRegisterCoalescing.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -53,9 +53,10 @@
</span><span class="cx"> template&lt;typename IndexType&gt;
</span><span class="cx"> class AbstractColoringAllocator {
</span><span class="cx"> public:
</span><del>-    AbstractColoringAllocator(const Vector&lt;Reg&gt;&amp; regsInPriorityOrder, IndexType lastPrecoloredRegisterIndex, unsigned tmpArraySize)
</del><ins>+    AbstractColoringAllocator(const Vector&lt;Reg&gt;&amp; regsInPriorityOrder, IndexType lastPrecoloredRegisterIndex, unsigned tmpArraySize, const HashSet&lt;unsigned&gt;&amp; unspillableTmp)
</ins><span class="cx">         : m_regsInPriorityOrder(regsInPriorityOrder)
</span><span class="cx">         , m_lastPrecoloredRegisterIndex(lastPrecoloredRegisterIndex)
</span><ins>+        , m_unspillableTmps(unspillableTmp)
</ins><span class="cx">     {
</span><span class="cx">         initializeDegrees(tmpArraySize);
</span><span class="cx"> 
</span><span class="lines">@@ -90,7 +91,7 @@
</span><span class="cx">                 continue;
</span><span class="cx"> 
</span><span class="cx">             if (degree &gt;= m_regsInPriorityOrder.size())
</span><del>-                m_spillWorklist.add(i);
</del><ins>+                addToSpill(i);
</ins><span class="cx">             else if (!m_moveList[i].isEmpty())
</span><span class="cx">                 m_freezeWorklist.add(i);
</span><span class="cx">             else
</span><span class="lines">@@ -98,6 +99,14 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void addToSpill(unsigned toSpill)
+    {
+        if (m_unspillableTmps.contains(toSpill))
+            return;
+
+        m_spillWorklist.add(toSpill);
+    }
+
</ins><span class="cx">     // Low-degree vertex can always be colored: just pick any of the color taken by any
</span><span class="cx">     // other adjacent verices.
</span><span class="cx">     // The &quot;Simplify&quot; phase takes a low-degree out of the interference graph to simplify it.
</span><span class="lines">@@ -361,7 +370,7 @@
</span><span class="cx">         });
</span><span class="cx"> 
</span><span class="cx">         if (m_degrees[u] &gt;= m_regsInPriorityOrder.size() &amp;&amp; m_freezeWorklist.remove(u))
</span><del>-            m_spillWorklist.add(u);
</del><ins>+            addToSpill(u);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool canBeSafelyCoalesced(IndexType u, IndexType v)
</span><span class="lines">@@ -625,6 +634,8 @@
</span><span class="cx"> 
</span><span class="cx">     // The mapping of Tmp to their alias for Moves that are always coalescing regardless of spilling.
</span><span class="cx">     Vector&lt;IndexType, 0, UnsafeVectorOverflow&gt; m_coalescedTmpsAtSpill;
</span><ins>+    
+    const HashSet&lt;unsigned&gt;&amp; m_unspillableTmps;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> // This perform all the tasks that are specific to certain register type.
</span><span class="lines">@@ -632,11 +643,10 @@
</span><span class="cx"> class ColoringAllocator : public AbstractColoringAllocator&lt;unsigned&gt; {
</span><span class="cx"> public:
</span><span class="cx">     ColoringAllocator(Code&amp; code, TmpWidth&amp; tmpWidth, const UseCounts&lt;Tmp&gt;&amp; useCounts, const HashSet&lt;unsigned&gt;&amp; unspillableTmp)
</span><del>-        : AbstractColoringAllocator&lt;unsigned&gt;(regsInPriorityOrder(type), AbsoluteTmpMapper&lt;type&gt;::lastMachineRegisterIndex(), tmpArraySize(code))
</del><ins>+        : AbstractColoringAllocator&lt;unsigned&gt;(regsInPriorityOrder(type), AbsoluteTmpMapper&lt;type&gt;::lastMachineRegisterIndex(), tmpArraySize(code), unspillableTmp)
</ins><span class="cx">         , m_code(code)
</span><span class="cx">         , m_tmpWidth(tmpWidth)
</span><span class="cx">         , m_useCounts(useCounts)
</span><del>-        , m_unspillableTmps(unspillableTmp)
</del><span class="cx">     {
</span><span class="cx">         initializePrecoloredTmp();
</span><span class="cx">         build();
</span><span class="lines">@@ -927,11 +937,9 @@
</span><span class="cx"> 
</span><span class="cx">         auto iterator = m_spillWorklist.begin();
</span><span class="cx"> 
</span><del>-        while (iterator != m_spillWorklist.end() &amp;&amp; m_unspillableTmps.contains(*iterator))
-            ++iterator;
</del><ins>+        RELEASE_ASSERT_WITH_MESSAGE(iterator != m_spillWorklist.end(), &quot;selectSpill() called when there was no spill.&quot;);
+        RELEASE_ASSERT_WITH_MESSAGE(!m_unspillableTmps.contains(*iterator), &quot;trying to spill unspillable tmp&quot;);
</ins><span class="cx"> 
</span><del>-        RELEASE_ASSERT_WITH_MESSAGE(iterator != m_spillWorklist.end(), &quot;It is not possible to color the Air graph with the number of available registers.&quot;);
-
</del><span class="cx">         // Higher score means more desirable to spill. Lower scores maximize the likelihood that a tmp
</span><span class="cx">         // gets a register.
</span><span class="cx">         auto score = [&amp;] (Tmp tmp) -&gt; double {
</span><span class="lines">@@ -945,12 +953,15 @@
</span><span class="cx"> 
</span><span class="cx">             // All else being equal, the score should be inversely related to the number of warm uses and
</span><span class="cx">             // defs.
</span><del>-            const UseCounts&lt;Tmp&gt;::Counts&amp; counts = m_useCounts[tmp];
-            double uses = counts.numWarmUses + counts.numDefs;
</del><ins>+            const UseCounts&lt;Tmp&gt;::Counts* counts = m_useCounts[tmp];
+            if (!counts)
+                return std::numeric_limits&lt;double&gt;::infinity();
+            
+            double uses = counts-&gt;numWarmUses + counts-&gt;numDefs;
</ins><span class="cx"> 
</span><span class="cx">             // If it's a constant, then it's not as bad to spill. We can rematerialize it in many
</span><span class="cx">             // cases.
</span><del>-            if (counts.numConstDefs == counts.numDefs)
</del><ins>+            if (counts-&gt;numConstDefs == counts-&gt;numDefs)
</ins><span class="cx">                 uses /= 2;
</span><span class="cx"> 
</span><span class="cx">             return degree / uses;
</span><span class="lines">@@ -961,11 +972,9 @@
</span><span class="cx"> 
</span><span class="cx">         ++iterator;
</span><span class="cx">         for (;iterator != m_spillWorklist.end(); ++iterator) {
</span><del>-            if (m_unspillableTmps.contains(*iterator))
-                continue;
-
</del><span class="cx">             double tmpScore = score(AbsoluteTmpMapper&lt;type&gt;::tmpFromAbsoluteIndex(*iterator));
</span><span class="cx">             if (tmpScore &gt; maxScore) {
</span><ins>+                ASSERT(!m_unspillableTmps.contains(*iterator));
</ins><span class="cx">                 victimIterator = iterator;
</span><span class="cx">                 maxScore = tmpScore;
</span><span class="cx">             }
</span><span class="lines">@@ -1058,7 +1067,6 @@
</span><span class="cx">     TmpWidth&amp; m_tmpWidth;
</span><span class="cx">     // FIXME: spilling should not type specific. It is only a side effect of using UseCounts.
</span><span class="cx">     const UseCounts&lt;Tmp&gt;&amp; m_useCounts;
</span><del>-    const HashSet&lt;unsigned&gt;&amp; m_unspillableTmps;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class IteratedRegisterCoalescing {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirUseCountsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/air/AirUseCounts.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -97,11 +97,12 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    const Counts&amp; operator[](const Thing&amp; arg) const
</del><ins>+    const Counts* operator[](const Thing&amp; arg) const
</ins><span class="cx">     {
</span><del>-        auto iterator = m_counts.find(arg);
-        ASSERT(iterator != m_counts.end());
-        return iterator-&gt;value;
</del><ins>+        auto iter = m_counts.find(arg);
+        if (iter == m_counts.end())
+            return nullptr;
+        return &amp;iter-&gt;value;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     void dump(PrintStream&amp; out) const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -9065,6 +9065,121 @@
</span><span class="cx">     CHECK(invoke&lt;intptr_t&gt;(*code, 43, 642462, 32533) == 32533);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testCheckSelect()
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+
+    CheckValue* check = root-&gt;appendNew&lt;CheckValue&gt;(
+        proc, Check, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(
+            proc, Add, Origin(),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, Select, Origin(),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, BitAnd, Origin(),
+                    root-&gt;appendNew&lt;Value&gt;(
+                        proc, Trunc, Origin(),
+                        root-&gt;appendNew&lt;ArgumentRegValue&gt;(
+                            proc, Origin(), GPRInfo::argumentGPR0)),
+                    root-&gt;appendNew&lt;Const32Value&gt;(proc, Origin(), 0xff)),
+                root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), -42),
+                root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), 35)),
+            root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), 42)));
+    unsigned generationCount = 0;
+    check-&gt;setGenerator(
+        [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp;) {
+            AllowMacroScratchRegisterUsage allowScratch(jit);
+
+            generationCount++;
+            jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
+            jit.emitFunctionEpilogue();
+            jit.ret();
+        });
+    
+    root-&gt;appendNew&lt;ControlValue&gt;(
+        proc, Return, Origin(),
+        root-&gt;appendNew&lt;Const32Value&gt;(proc, Origin(), 0));
+
+    auto code = compile(proc);
+    CHECK(generationCount == 1);
+    CHECK(invoke&lt;int&gt;(*code, true) == 0);
+    CHECK(invoke&lt;int&gt;(*code, false) == 666);
+}
+
+void testCheckSelectCheckSelect()
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+
+    CheckValue* check = root-&gt;appendNew&lt;CheckValue&gt;(
+        proc, Check, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(
+            proc, Add, Origin(),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, Select, Origin(),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, BitAnd, Origin(),
+                    root-&gt;appendNew&lt;Value&gt;(
+                        proc, Trunc, Origin(),
+                        root-&gt;appendNew&lt;ArgumentRegValue&gt;(
+                            proc, Origin(), GPRInfo::argumentGPR0)),
+                    root-&gt;appendNew&lt;Const32Value&gt;(proc, Origin(), 0xff)),
+                root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), -42),
+                root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), 35)),
+            root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), 42)));
+
+    unsigned generationCount = 0;
+    check-&gt;setGenerator(
+        [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp;) {
+            AllowMacroScratchRegisterUsage allowScratch(jit);
+
+            generationCount++;
+            jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
+            jit.emitFunctionEpilogue();
+            jit.ret();
+        });
+    
+    CheckValue* check2 = root-&gt;appendNew&lt;CheckValue&gt;(
+        proc, Check, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(
+            proc, Add, Origin(),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, Select, Origin(),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, BitAnd, Origin(),
+                    root-&gt;appendNew&lt;Value&gt;(
+                        proc, Trunc, Origin(),
+                        root-&gt;appendNew&lt;ArgumentRegValue&gt;(
+                            proc, Origin(), GPRInfo::argumentGPR1)),
+                    root-&gt;appendNew&lt;Const32Value&gt;(proc, Origin(), 0xff)),
+                root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), -43),
+                root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), 36)),
+            root-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), 43)));
+
+    unsigned generationCount2 = 0;
+    check2-&gt;setGenerator(
+        [&amp;] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp;) {
+            AllowMacroScratchRegisterUsage allowScratch(jit);
+
+            generationCount2++;
+            jit.move(CCallHelpers::TrustedImm32(667), GPRInfo::returnValueGPR);
+            jit.emitFunctionEpilogue();
+            jit.ret();
+        });
+    
+    root-&gt;appendNew&lt;ControlValue&gt;(
+        proc, Return, Origin(),
+        root-&gt;appendNew&lt;Const32Value&gt;(proc, Origin(), 0));
+
+    auto code = compile(proc);
+    CHECK(generationCount == 1);
+    CHECK(generationCount2 == 1);
+    CHECK(invoke&lt;int&gt;(*code, true, true) == 0);
+    CHECK(invoke&lt;int&gt;(*code, false, true) == 666);
+    CHECK(invoke&lt;int&gt;(*code, true, false) == 667);
+}
+
</ins><span class="cx"> void testPowDoubleByIntegerLoop(double xOperand, int32_t yOperand)
</span><span class="cx"> {
</span><span class="cx">     Procedure proc;
</span><span class="lines">@@ -10074,8 +10189,6 @@
</span><span class="cx">     RUN(testBranchLoad16Z());
</span><span class="cx"> 
</span><span class="cx">     RUN(testComplex(64, 128));
</span><del>-    RUN(testComplex(64, 256));
-    RUN(testComplex(64, 384));
</del><span class="cx">     RUN(testComplex(4, 128));
</span><span class="cx">     RUN(testComplex(4, 256));
</span><span class="cx">     RUN(testComplex(4, 384));
</span><span class="lines">@@ -10524,6 +10637,8 @@
</span><span class="cx">     RUN(testSelectFold(42));
</span><span class="cx">     RUN(testSelectFold(43));
</span><span class="cx">     RUN(testSelectInvert());
</span><ins>+    RUN(testCheckSelect());
+    RUN(testCheckSelectCheckSelect());
</ins><span class="cx">     RUN_BINARY(testPowDoubleByIntegerLoop, floatingPointOperands&lt;double&gt;(), int64Operands());
</span><span class="cx"> 
</span><span class="cx">     RUN(testTruncOrHigh());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -344,6 +344,8 @@
</span><span class="cx">     v(double, rareBlockPenalty, 0.001, nullptr) \
</span><span class="cx">     v(bool, airSpillsEverything, false, nullptr) \
</span><span class="cx">     v(bool, logAirRegisterPressure, false, nullptr) \
</span><ins>+    v(unsigned, maxB3TailDupBlockSize, 3, nullptr) \
+    v(unsigned, maxB3TailDupBlockSuccessors, 3, nullptr) \
</ins><span class="cx">     \
</span><span class="cx">     v(bool, useDollarVM, false, &quot;installs the $vm debugging tool in global objects&quot;) \
</span><span class="cx">     v(optionString, functionOverrides, nullptr, &quot;file with debugging overrides for function bodies&quot;) \
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/WTF/ChangeLog        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2016-01-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        B3 should have basic path specialization
+        https://bugs.webkit.org/show_bug.cgi?id=153200
+
+        Reviewed by Benjamin Poulain.
+
+        * wtf/GraphNodeWorklist.h:
+        (WTF::GraphNodeWorklist::push):
+        (WTF::GraphNodeWorklist::pushAll):
+        (WTF::GraphNodeWorklist::isEmpty):
+        (WTF::GraphNodeWorklist::notEmpty):
+
</ins><span class="cx"> 2016-01-20  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Refactor AtomicStringKeyedMRUCache to be a generic LRU cache
</span></span></pre></div>
<a id="trunkSourceWTFwtfGraphNodeWorklisth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/GraphNodeWorklist.h (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/GraphNodeWorklist.h        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Source/WTF/wtf/GraphNodeWorklist.h        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -45,6 +45,13 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    template&lt;typename Iterable&gt;
+    void pushAll(const Iterable&amp; iterable)
+    {
+        for (Node node : iterable)
+            push(node);
+    }
+
</ins><span class="cx">     bool isEmpty() const { return m_stack.isEmpty(); }
</span><span class="cx">     bool notEmpty() const { return !m_stack.isEmpty(); }
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkToolsScriptsdisplayprofileroutput"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/display-profiler-output (195394 => 195395)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/display-profiler-output        2016-01-21 02:13:21 UTC (rev 195394)
+++ trunk/Tools/Scripts/display-profiler-output        2016-01-21 03:12:55 UTC (rev 195395)
</span><span class="lines">@@ -535,7 +535,7 @@
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><del>-def summary(mode)
</del><ins>+def summary(mode, order)
</ins><span class="cx">     remaining = screenWidth
</span><span class="cx">     
</span><span class="cx">     # Figure out how many columns we need for the code block names, and for counts
</span><span class="lines">@@ -618,7 +618,14 @@
</span><span class="cx">     puts
</span><span class="cx">     $bytecodes.sort {
</span><span class="cx">         | a, b |
</span><del>-        b.totalMaxTopExecutionCount &lt;=&gt; a.totalMaxTopExecutionCount
</del><ins>+        case order
+        when :bytecode
+            b.totalMaxTopExecutionCount &lt;=&gt; a.totalMaxTopExecutionCount
+        when :machine
+            b.totalMaxBottomExecutionCount &lt;=&gt; a.totalMaxBottomExecutionCount
+        else
+            raise
+        end
</ins><span class="cx">     }.each {
</span><span class="cx">         | bytecode |
</span><span class="cx">         print(center(bytecode.name(hashCols), hashCols))
</span><span class="lines">@@ -738,9 +745,13 @@
</span><span class="cx">     when &quot;quit&quot;, &quot;q&quot;, &quot;exit&quot;
</span><span class="cx">         exit 0
</span><span class="cx">     when &quot;summary&quot;, &quot;s&quot;
</span><del>-        summary(:summary)
</del><ins>+        summary(:summary, :bytecode)
</ins><span class="cx">     when &quot;full&quot;, &quot;f&quot;
</span><del>-        summary(:full)
</del><ins>+        if args[0] and (args[0] == &quot;m&quot; or args[0] == &quot;machine&quot;)
+            summary(:full, :machine)
+        else
+            summary(:full, :bytecode)
+        end
</ins><span class="cx">     when &quot;source&quot;
</span><span class="cx">         if args.length != 1
</span><span class="cx">             puts &quot;Usage: source &lt;code block hash&gt;&quot;
</span></span></pre>
</div>
</div>

</body>
</html>