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

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

<h3>Log Message</h3>
<pre>B3 should be able to compile a program with ChillDiv
https://bugs.webkit.org/show_bug.cgi?id=151114

Reviewed by Benjamin Poulain.

Source/JavaScriptCore:

This change is about a lot more than ChillDiv. I picked that as the next thing to lower
because I knew that it would force me to come up with a sensible idiom for doing
stepwise lowerings that require breaking basic blocks. The idea is that you want to
write a loop that iterates forward over the program, which turns some operations that
currently are just single Values into an entire little sub-CFGs. That requires splitting
the block that contained the original Value. That's tricky if you then want to keep
iterating: the index of the Value you were last looking at has now changed and your
InsertionSets are now invalid.

This introduces an idiom that handles this. It's BlockInsertionSet::splitBefore(). The
idea is that it uses the current block before the split as the continuation after the
split. When you call splitBefore(), you pass it your loop index and your InsertionSet
(if applicable). It makes sure that it changes those auxiliary things in such a way that
you can keep looping.

This uncovered some bugs, since this is the first time that we're compiling cross edges.

Because ChillDiv is really a division, I also had to write a bunch of code to support
the ordinary B3 Div. While doing that, I realized that there was asymmetry to that
constness of the Value constant folding methods, so I fixed that as well.

* JavaScriptCore.xcodeproj/project.pbxproj:
* assembler/MacroAssemblerX86Common.h:
(JSC::MacroAssemblerX86Common::mul32):
(JSC::MacroAssemblerX86Common::x86ConvertToDoubleWord32):
(JSC::MacroAssemblerX86Common::x86Div32):
(JSC::MacroAssemblerX86Common::neg32):
* assembler/MacroAssemblerX86_64.h:
(JSC::MacroAssemblerX86_64::mul64):
(JSC::MacroAssemblerX86_64::x86ConvertToQuadWord64):
(JSC::MacroAssemblerX86_64::x86Div64):
(JSC::MacroAssemblerX86_64::neg64):
* assembler/X86Assembler.h:
(JSC::X86Assembler::idivl_r):
(JSC::X86Assembler::idivq_r):
(JSC::X86Assembler::cmpl_rr):
(JSC::X86Assembler::cdq):
(JSC::X86Assembler::cdqq):
(JSC::X86Assembler::fstps):
* b3/B3BasicBlock.cpp:
(JSC::B3::BasicBlock::append):
(JSC::B3::BasicBlock::replaceLast):
(JSC::B3::BasicBlock::appendIntConstant):
(JSC::B3::BasicBlock::replaceSuccessor):
(JSC::B3::BasicBlock::addPredecessor):
(JSC::B3::BasicBlock::replacePredecessor):
(JSC::B3::BasicBlock::updatePredecessors):
(JSC::B3::BasicBlock::dump):
* b3/B3BasicBlock.h:
(JSC::B3::BasicBlock::values):
(JSC::B3::BasicBlock::numPredecessors):
(JSC::B3::BasicBlock::predecessor):
(JSC::B3::BasicBlock::frequency):
* b3/B3BasicBlockInlines.h:
(JSC::B3::BasicBlock::appendNew):
(JSC::B3::BasicBlock::replaceLastWithNew):
(JSC::B3::BasicBlock::numSuccessors):
* b3/B3BasicBlockUtils.h:
(JSC::B3::replacePredecessor):
(JSC::B3::updatePredecessors):
(JSC::B3::resetReachability):
* b3/B3BlockInsertionSet.cpp: Added.
(JSC::B3::BlockInsertionSet::BlockInsertionSet):
(JSC::B3::BlockInsertionSet::~BlockInsertionSet):
(JSC::B3::BlockInsertionSet::insert):
(JSC::B3::BlockInsertionSet::insertBefore):
(JSC::B3::BlockInsertionSet::splitForward):
(JSC::B3::BlockInsertionSet::execute):
* b3/B3BlockInsertionSet.h: Added.
* b3/B3Common.h:
(JSC::B3::isRepresentableAs):
(JSC::B3::chillDiv):
* b3/B3Const32Value.cpp:
(JSC::B3::Const32Value::addConstant):
(JSC::B3::Const32Value::subConstant):
(JSC::B3::Const32Value::divConstant):
(JSC::B3::Const32Value::bitAndConstant):
(JSC::B3::Const32Value::bitOrConstant):
(JSC::B3::Const32Value::bitXorConstant):
(JSC::B3::Const32Value::shlConstant):
(JSC::B3::Const32Value::sShrConstant):
(JSC::B3::Const32Value::zShrConstant):
(JSC::B3::Const32Value::equalConstant):
(JSC::B3::Const32Value::notEqualConstant):
(JSC::B3::Const32Value::lessThanConstant):
(JSC::B3::Const32Value::greaterThanConstant):
(JSC::B3::Const32Value::lessEqualConstant):
(JSC::B3::Const32Value::greaterEqualConstant):
(JSC::B3::Const32Value::aboveConstant):
(JSC::B3::Const32Value::belowConstant):
(JSC::B3::Const32Value::aboveEqualConstant):
(JSC::B3::Const32Value::belowEqualConstant):
* b3/B3Const32Value.h:
* b3/B3Const64Value.cpp:
(JSC::B3::Const64Value::addConstant):
(JSC::B3::Const64Value::subConstant):
(JSC::B3::Const64Value::divConstant):
(JSC::B3::Const64Value::bitAndConstant):
(JSC::B3::Const64Value::bitOrConstant):
(JSC::B3::Const64Value::bitXorConstant):
(JSC::B3::Const64Value::shlConstant):
(JSC::B3::Const64Value::sShrConstant):
(JSC::B3::Const64Value::zShrConstant):
(JSC::B3::Const64Value::equalConstant):
(JSC::B3::Const64Value::notEqualConstant):
(JSC::B3::Const64Value::lessThanConstant):
(JSC::B3::Const64Value::greaterThanConstant):
(JSC::B3::Const64Value::lessEqualConstant):
(JSC::B3::Const64Value::greaterEqualConstant):
(JSC::B3::Const64Value::aboveConstant):
(JSC::B3::Const64Value::belowConstant):
(JSC::B3::Const64Value::aboveEqualConstant):
(JSC::B3::Const64Value::belowEqualConstant):
* b3/B3Const64Value.h:
* b3/B3ConstDoubleValue.cpp:
(JSC::B3::ConstDoubleValue::addConstant):
(JSC::B3::ConstDoubleValue::subConstant):
(JSC::B3::ConstDoubleValue::divConstant):
(JSC::B3::ConstDoubleValue::equalConstant):
(JSC::B3::ConstDoubleValue::notEqualConstant):
(JSC::B3::ConstDoubleValue::lessThanConstant):
(JSC::B3::ConstDoubleValue::greaterThanConstant):
(JSC::B3::ConstDoubleValue::lessEqualConstant):
(JSC::B3::ConstDoubleValue::greaterEqualConstant):
* b3/B3ConstDoubleValue.h:
* b3/B3ControlValue.cpp:
(JSC::B3::ControlValue::~ControlValue):
(JSC::B3::ControlValue::replaceSuccessor):
(JSC::B3::ControlValue::convertToJump):
* b3/B3ControlValue.h:
* b3/B3Generate.cpp:
(JSC::B3::generateToAir):
* b3/B3GenericFrequentedBlock.h:
(JSC::B3::GenericFrequentedBlock::block):
(JSC::B3::GenericFrequentedBlock::frequency):
(JSC::B3::GenericFrequentedBlock::dump):
* b3/B3InsertionSet.cpp:
(JSC::B3::InsertionSet::insertIntConstant):
(JSC::B3::InsertionSet::execute):
* b3/B3InsertionSet.h:
* b3/B3LowerMacros.cpp: Added.
(JSC::B3::lowerMacros):
* b3/B3LowerMacros.h: Added.
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::lower):
* b3/B3Opcode.h:
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::addBlock):
(JSC::B3::Procedure::addIntConstant):
(JSC::B3::Procedure::addBoolConstant):
(JSC::B3::Procedure::resetValueOwners):
* b3/B3Procedure.h:
(JSC::B3::Procedure::takeByproducts):
* b3/B3ReduceStrength.cpp:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::addConstant):
(JSC::B3::Value::subConstant):
(JSC::B3::Value::divConstant):
(JSC::B3::Value::bitAndConstant):
(JSC::B3::Value::bitOrConstant):
(JSC::B3::Value::bitXorConstant):
(JSC::B3::Value::shlConstant):
(JSC::B3::Value::sShrConstant):
(JSC::B3::Value::zShrConstant):
(JSC::B3::Value::equalConstant):
(JSC::B3::Value::notEqualConstant):
(JSC::B3::Value::lessThanConstant):
(JSC::B3::Value::greaterThanConstant):
(JSC::B3::Value::lessEqualConstant):
(JSC::B3::Value::greaterEqualConstant):
(JSC::B3::Value::aboveConstant):
(JSC::B3::Value::belowConstant):
(JSC::B3::Value::aboveEqualConstant):
(JSC::B3::Value::belowEqualConstant):
* b3/B3Value.h:
* b3/air/AirGenerate.cpp:
(JSC::B3::Air::generate):
* b3/air/AirInstInlines.h:
(JSC::B3::Air::isUrshift64Valid):
(JSC::B3::Air::isX86DivHelperValid):
(JSC::B3::Air::isX86ConvertToDoubleWord32Valid):
(JSC::B3::Air::isX86ConvertToDoubleWord64Valid):
(JSC::B3::Air::isX86Div32Valid):
(JSC::B3::Air::isX86Div64Valid):
* b3/air/AirOpcode.opcodes:
* b3/air/AirSimplifyCFG.cpp:
(JSC::B3::Air::simplifyCFG):
* b3/testb3.cpp:
(JSC::B3::testCallFunctionWithHellaDoubleArguments):
(JSC::B3::testChillDiv):
(JSC::B3::testChillDivTwice):
(JSC::B3::testChillDiv64):
(JSC::B3::run):
* dfg/DFGBlockInsertionSet.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileArithDiv):
(JSC::DFG::SpeculativeJIT::compileArithMod):
* jit/JITArithmetic.cpp:
(JSC::JIT::emit_op_mod):
* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emit_op_mod):
* wasm/WASMFunctionCompiler.h:
(JSC::WASMFunctionCompiler::buildBinaryI32):

Source/WTF:

Needed to beef up some compiler algorithms. All of the hardening was about making them
work with objects that have move semantics but not copy semantics. This arises in B3
basic block insertion sets.

* wtf/BubbleSort.h:
(WTF::bubbleSort):
* wtf/Insertion.h:
(WTF::Insertion::Insertion):
(WTF::Insertion::index):
(WTF::Insertion::element):
(WTF::Insertion::operator&lt;):
(WTF::executeInsertions):</pre>

<h3>Modified Paths</h3>
<ul>
<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="#trunkSourceJavaScriptCoreassemblerMacroAssemblerX86Commonh">trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerMacroAssemblerX86_64h">trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerX86Assemblerh">trunk/Source/JavaScriptCore/assembler/X86Assembler.h</a></li>
<li><a href="#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="#trunkSourceJavaScriptCoreb3B3BasicBlockUtilsh">trunk/Source/JavaScriptCore/b3/B3BasicBlockUtils.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Commonh">trunk/Source/JavaScriptCore/b3/B3Common.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="#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="#trunkSourceJavaScriptCoreb3B3GenericFrequentedBlockh">trunk/Source/JavaScriptCore/b3/B3GenericFrequentedBlock.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="#trunkSourceJavaScriptCoreb3B3Opcodeh">trunk/Source/JavaScriptCore/b3/B3Opcode.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="#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="#trunkSourceJavaScriptCoreb3airAirGeneratecpp">trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirInstInlinesh">trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirOpcodeopcodes">trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airAirSimplifyCFGcpp">trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGBlockInsertionSeth">trunk/Source/JavaScriptCore/dfg/DFGBlockInsertionSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITArithmeticcpp">trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITArithmetic32_64cpp">trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionCompilerh">trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfBubbleSorth">trunk/Source/WTF/wtf/BubbleSort.h</a></li>
<li><a href="#trunkSourceWTFwtfInsertionh">trunk/Source/WTF/wtf/Insertion.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreb3B3BlockInsertionSetcpp">trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3BlockInsertionSeth">trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerMacroscpp">trunk/Source/JavaScriptCore/b3/B3LowerMacros.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3LowerMacrosh">trunk/Source/JavaScriptCore/b3/B3LowerMacros.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -1,3 +1,215 @@
</span><ins>+2015-11-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        B3 should be able to compile a program with ChillDiv
+        https://bugs.webkit.org/show_bug.cgi?id=151114
+
+        Reviewed by Benjamin Poulain.
+
+        This change is about a lot more than ChillDiv. I picked that as the next thing to lower
+        because I knew that it would force me to come up with a sensible idiom for doing
+        stepwise lowerings that require breaking basic blocks. The idea is that you want to
+        write a loop that iterates forward over the program, which turns some operations that
+        currently are just single Values into an entire little sub-CFGs. That requires splitting
+        the block that contained the original Value. That's tricky if you then want to keep
+        iterating: the index of the Value you were last looking at has now changed and your
+        InsertionSets are now invalid.
+
+        This introduces an idiom that handles this. It's BlockInsertionSet::splitBefore(). The
+        idea is that it uses the current block before the split as the continuation after the
+        split. When you call splitBefore(), you pass it your loop index and your InsertionSet
+        (if applicable). It makes sure that it changes those auxiliary things in such a way that
+        you can keep looping.
+
+        This uncovered some bugs, since this is the first time that we're compiling cross edges.
+
+        Because ChillDiv is really a division, I also had to write a bunch of code to support
+        the ordinary B3 Div. While doing that, I realized that there was asymmetry to that
+        constness of the Value constant folding methods, so I fixed that as well.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * assembler/MacroAssemblerX86Common.h:
+        (JSC::MacroAssemblerX86Common::mul32):
+        (JSC::MacroAssemblerX86Common::x86ConvertToDoubleWord32):
+        (JSC::MacroAssemblerX86Common::x86Div32):
+        (JSC::MacroAssemblerX86Common::neg32):
+        * assembler/MacroAssemblerX86_64.h:
+        (JSC::MacroAssemblerX86_64::mul64):
+        (JSC::MacroAssemblerX86_64::x86ConvertToQuadWord64):
+        (JSC::MacroAssemblerX86_64::x86Div64):
+        (JSC::MacroAssemblerX86_64::neg64):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::idivl_r):
+        (JSC::X86Assembler::idivq_r):
+        (JSC::X86Assembler::cmpl_rr):
+        (JSC::X86Assembler::cdq):
+        (JSC::X86Assembler::cdqq):
+        (JSC::X86Assembler::fstps):
+        * b3/B3BasicBlock.cpp:
+        (JSC::B3::BasicBlock::append):
+        (JSC::B3::BasicBlock::replaceLast):
+        (JSC::B3::BasicBlock::appendIntConstant):
+        (JSC::B3::BasicBlock::replaceSuccessor):
+        (JSC::B3::BasicBlock::addPredecessor):
+        (JSC::B3::BasicBlock::replacePredecessor):
+        (JSC::B3::BasicBlock::updatePredecessors):
+        (JSC::B3::BasicBlock::dump):
+        * b3/B3BasicBlock.h:
+        (JSC::B3::BasicBlock::values):
+        (JSC::B3::BasicBlock::numPredecessors):
+        (JSC::B3::BasicBlock::predecessor):
+        (JSC::B3::BasicBlock::frequency):
+        * b3/B3BasicBlockInlines.h:
+        (JSC::B3::BasicBlock::appendNew):
+        (JSC::B3::BasicBlock::replaceLastWithNew):
+        (JSC::B3::BasicBlock::numSuccessors):
+        * b3/B3BasicBlockUtils.h:
+        (JSC::B3::replacePredecessor):
+        (JSC::B3::updatePredecessors):
+        (JSC::B3::resetReachability):
+        * b3/B3BlockInsertionSet.cpp: Added.
+        (JSC::B3::BlockInsertionSet::BlockInsertionSet):
+        (JSC::B3::BlockInsertionSet::~BlockInsertionSet):
+        (JSC::B3::BlockInsertionSet::insert):
+        (JSC::B3::BlockInsertionSet::insertBefore):
+        (JSC::B3::BlockInsertionSet::splitForward):
+        (JSC::B3::BlockInsertionSet::execute):
+        * b3/B3BlockInsertionSet.h: Added.
+        * b3/B3Common.h:
+        (JSC::B3::isRepresentableAs):
+        (JSC::B3::chillDiv):
+        * b3/B3Const32Value.cpp:
+        (JSC::B3::Const32Value::addConstant):
+        (JSC::B3::Const32Value::subConstant):
+        (JSC::B3::Const32Value::divConstant):
+        (JSC::B3::Const32Value::bitAndConstant):
+        (JSC::B3::Const32Value::bitOrConstant):
+        (JSC::B3::Const32Value::bitXorConstant):
+        (JSC::B3::Const32Value::shlConstant):
+        (JSC::B3::Const32Value::sShrConstant):
+        (JSC::B3::Const32Value::zShrConstant):
+        (JSC::B3::Const32Value::equalConstant):
+        (JSC::B3::Const32Value::notEqualConstant):
+        (JSC::B3::Const32Value::lessThanConstant):
+        (JSC::B3::Const32Value::greaterThanConstant):
+        (JSC::B3::Const32Value::lessEqualConstant):
+        (JSC::B3::Const32Value::greaterEqualConstant):
+        (JSC::B3::Const32Value::aboveConstant):
+        (JSC::B3::Const32Value::belowConstant):
+        (JSC::B3::Const32Value::aboveEqualConstant):
+        (JSC::B3::Const32Value::belowEqualConstant):
+        * b3/B3Const32Value.h:
+        * b3/B3Const64Value.cpp:
+        (JSC::B3::Const64Value::addConstant):
+        (JSC::B3::Const64Value::subConstant):
+        (JSC::B3::Const64Value::divConstant):
+        (JSC::B3::Const64Value::bitAndConstant):
+        (JSC::B3::Const64Value::bitOrConstant):
+        (JSC::B3::Const64Value::bitXorConstant):
+        (JSC::B3::Const64Value::shlConstant):
+        (JSC::B3::Const64Value::sShrConstant):
+        (JSC::B3::Const64Value::zShrConstant):
+        (JSC::B3::Const64Value::equalConstant):
+        (JSC::B3::Const64Value::notEqualConstant):
+        (JSC::B3::Const64Value::lessThanConstant):
+        (JSC::B3::Const64Value::greaterThanConstant):
+        (JSC::B3::Const64Value::lessEqualConstant):
+        (JSC::B3::Const64Value::greaterEqualConstant):
+        (JSC::B3::Const64Value::aboveConstant):
+        (JSC::B3::Const64Value::belowConstant):
+        (JSC::B3::Const64Value::aboveEqualConstant):
+        (JSC::B3::Const64Value::belowEqualConstant):
+        * b3/B3Const64Value.h:
+        * b3/B3ConstDoubleValue.cpp:
+        (JSC::B3::ConstDoubleValue::addConstant):
+        (JSC::B3::ConstDoubleValue::subConstant):
+        (JSC::B3::ConstDoubleValue::divConstant):
+        (JSC::B3::ConstDoubleValue::equalConstant):
+        (JSC::B3::ConstDoubleValue::notEqualConstant):
+        (JSC::B3::ConstDoubleValue::lessThanConstant):
+        (JSC::B3::ConstDoubleValue::greaterThanConstant):
+        (JSC::B3::ConstDoubleValue::lessEqualConstant):
+        (JSC::B3::ConstDoubleValue::greaterEqualConstant):
+        * b3/B3ConstDoubleValue.h:
+        * b3/B3ControlValue.cpp:
+        (JSC::B3::ControlValue::~ControlValue):
+        (JSC::B3::ControlValue::replaceSuccessor):
+        (JSC::B3::ControlValue::convertToJump):
+        * b3/B3ControlValue.h:
+        * b3/B3Generate.cpp:
+        (JSC::B3::generateToAir):
+        * b3/B3GenericFrequentedBlock.h:
+        (JSC::B3::GenericFrequentedBlock::block):
+        (JSC::B3::GenericFrequentedBlock::frequency):
+        (JSC::B3::GenericFrequentedBlock::dump):
+        * b3/B3InsertionSet.cpp:
+        (JSC::B3::InsertionSet::insertIntConstant):
+        (JSC::B3::InsertionSet::execute):
+        * b3/B3InsertionSet.h:
+        * b3/B3LowerMacros.cpp: Added.
+        (JSC::B3::lowerMacros):
+        * b3/B3LowerMacros.h: Added.
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::lower):
+        * b3/B3Opcode.h:
+        * b3/B3Procedure.cpp:
+        (JSC::B3::Procedure::addBlock):
+        (JSC::B3::Procedure::addIntConstant):
+        (JSC::B3::Procedure::addBoolConstant):
+        (JSC::B3::Procedure::resetValueOwners):
+        * b3/B3Procedure.h:
+        (JSC::B3::Procedure::takeByproducts):
+        * b3/B3ReduceStrength.cpp:
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::addConstant):
+        (JSC::B3::Value::subConstant):
+        (JSC::B3::Value::divConstant):
+        (JSC::B3::Value::bitAndConstant):
+        (JSC::B3::Value::bitOrConstant):
+        (JSC::B3::Value::bitXorConstant):
+        (JSC::B3::Value::shlConstant):
+        (JSC::B3::Value::sShrConstant):
+        (JSC::B3::Value::zShrConstant):
+        (JSC::B3::Value::equalConstant):
+        (JSC::B3::Value::notEqualConstant):
+        (JSC::B3::Value::lessThanConstant):
+        (JSC::B3::Value::greaterThanConstant):
+        (JSC::B3::Value::lessEqualConstant):
+        (JSC::B3::Value::greaterEqualConstant):
+        (JSC::B3::Value::aboveConstant):
+        (JSC::B3::Value::belowConstant):
+        (JSC::B3::Value::aboveEqualConstant):
+        (JSC::B3::Value::belowEqualConstant):
+        * b3/B3Value.h:
+        * b3/air/AirGenerate.cpp:
+        (JSC::B3::Air::generate):
+        * b3/air/AirInstInlines.h:
+        (JSC::B3::Air::isUrshift64Valid):
+        (JSC::B3::Air::isX86DivHelperValid):
+        (JSC::B3::Air::isX86ConvertToDoubleWord32Valid):
+        (JSC::B3::Air::isX86ConvertToDoubleWord64Valid):
+        (JSC::B3::Air::isX86Div32Valid):
+        (JSC::B3::Air::isX86Div64Valid):
+        * b3/air/AirOpcode.opcodes:
+        * b3/air/AirSimplifyCFG.cpp:
+        (JSC::B3::Air::simplifyCFG):
+        * b3/testb3.cpp:
+        (JSC::B3::testCallFunctionWithHellaDoubleArguments):
+        (JSC::B3::testChillDiv):
+        (JSC::B3::testChillDivTwice):
+        (JSC::B3::testChillDiv64):
+        (JSC::B3::run):
+        * dfg/DFGBlockInsertionSet.h:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileArithDiv):
+        (JSC::DFG::SpeculativeJIT::compileArithMod):
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emit_op_mod):
+        * jit/JITArithmetic32_64.cpp:
+        (JSC::JIT::emit_op_mod):
+        * wasm/WASMFunctionCompiler.h:
+        (JSC::WASMFunctionCompiler::buildBinaryI32):
+
</ins><span class="cx"> 2015-11-10  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Air should allocate registers
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -300,6 +300,10 @@
</span><span class="cx">                 0F338E141BF0276C0013C88F /* B3ValueKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E081BF0276C0013C88F /* B3ValueKey.cpp */; };
</span><span class="cx">                 0F338E151BF0276C0013C88F /* B3ValueKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E091BF0276C0013C88F /* B3ValueKey.h */; };
</span><span class="cx">                 0F338E161BF0276C0013C88F /* B3ValueKeyInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */; };
</span><ins>+                0F338E1B1BF286EA0013C88F /* B3BlockInsertionSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */; };
+                0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */; };
+                0F338E1D1BF286EA0013C88F /* B3LowerMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */; };
+                0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */; };
</ins><span class="cx">                 0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
</span><span class="cx">                 0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; };
</span><span class="cx">                 0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */; };
</span><span class="lines">@@ -2343,6 +2347,10 @@
</span><span class="cx">                 0F338E081BF0276C0013C88F /* B3ValueKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3ValueKey.cpp; path = b3/B3ValueKey.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F338E091BF0276C0013C88F /* B3ValueKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ValueKey.h; path = b3/B3ValueKey.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F338E0A1BF0276C0013C88F /* B3ValueKeyInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ValueKeyInlines.h; path = b3/B3ValueKeyInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3BlockInsertionSet.cpp; path = b3/B3BlockInsertionSet.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3BlockInsertionSet.h; path = b3/B3BlockInsertionSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3LowerMacros.cpp; path = b3/B3LowerMacros.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3LowerMacros.h; path = b3/B3LowerMacros.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoint.cpp; path = llint/LLIntEntrypoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4442,6 +4450,8 @@
</span><span class="cx">                                 0FEC84B71BDACDAC0080FF74 /* B3BasicBlock.h */,
</span><span class="cx">                                 0FEC84B81BDACDAC0080FF74 /* B3BasicBlockInlines.h */,
</span><span class="cx">                                 0FEC84B91BDACDAC0080FF74 /* B3BasicBlockUtils.h */,
</span><ins>+                                0F338E171BF286EA0013C88F /* B3BlockInsertionSet.cpp */,
+                                0F338E181BF286EA0013C88F /* B3BlockInsertionSet.h */,
</ins><span class="cx">                                 0FEC84BA1BDACDAC0080FF74 /* B3BlockWorklist.h */,
</span><span class="cx">                                 0F338DF71BE96AA80013C88F /* B3CCallValue.cpp */,
</span><span class="cx">                                 0F338DF81BE96AA80013C88F /* B3CCallValue.h */,
</span><span class="lines">@@ -4483,6 +4493,8 @@
</span><span class="cx">                                 0FEC85B41BE1462F0080FF74 /* B3InsertionSet.cpp */,
</span><span class="cx">                                 0FEC85B51BE1462F0080FF74 /* B3InsertionSet.h */,
</span><span class="cx">                                 0FEC85B61BE1462F0080FF74 /* B3InsertionSetInlines.h */,
</span><ins>+                                0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */,
+                                0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */,
</ins><span class="cx">                                 0FEC84D31BDACDAC0080FF74 /* B3LowerToAir.cpp */,
</span><span class="cx">                                 0FEC84D41BDACDAC0080FF74 /* B3LowerToAir.h */,
</span><span class="cx">                                 0FEC84D51BDACDAC0080FF74 /* B3MemoryValue.cpp */,
</span><span class="lines">@@ -6680,6 +6692,7 @@
</span><span class="cx">                                 0FEC85381BDACDAC0080FF74 /* B3SwitchCase.h in Headers */,
</span><span class="cx">                                 0FEC853A1BDACDAC0080FF74 /* B3SwitchValue.h in Headers */,
</span><span class="cx">                                 0F4570411BE584CA0062A629 /* B3TimingScope.h in Headers */,
</span><ins>+                                0F338E1E1BF286EA0013C88F /* B3LowerMacros.h in Headers */,
</ins><span class="cx">                                 0FEC853C1BDACDAC0080FF74 /* B3Type.h in Headers */,
</span><span class="cx">                                 0FEC853E1BDACDAC0080FF74 /* B3UpsilonValue.h in Headers */,
</span><span class="cx">                                 0FEC85401BDACDAC0080FF74 /* B3UseCounts.h in Headers */,
</span><span class="lines">@@ -6779,6 +6792,7 @@
</span><span class="cx">                                 C2239D1916262BDD005AC5FD /* CopyVisitorInlines.h in Headers */,
</span><span class="cx">                                 C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */,
</span><span class="cx">                                 C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */,
</span><ins>+                                0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */,
</ins><span class="cx">                                 C4F4B6F31A05C944005CAB76 /* cpp_generator_templates.py in Headers */,
</span><span class="cx">                                 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
</span><span class="cx">                                 9959E92B1BD17FA4001AA413 /* cssmin.py in Headers */,
</span><span class="lines">@@ -8324,6 +8338,7 @@
</span><span class="cx">                                 147F39C6107EC37600427A48 /* DatePrototype.cpp in Sources */,
</span><span class="cx">                                 14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */,
</span><span class="cx">                                 149559EE0DDCDDF700648087 /* DebuggerCallFrame.cpp in Sources */,
</span><ins>+                                0F338E1D1BF286EA0013C88F /* B3LowerMacros.cpp in Sources */,
</ins><span class="cx">                                 0F2D4DDD19832D34007D4B19 /* DebuggerScope.cpp in Sources */,
</span><span class="cx">                                 2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */,
</span><span class="cx">                                 0FC712DE17CD8779008CC93C /* DeferredCompilationCallback.cpp in Sources */,
</span><span class="lines">@@ -8496,6 +8511,7 @@
</span><span class="cx">                                 0FEA0A1E1708B00700BB722C /* FTLAbstractHeapRepository.cpp in Sources */,
</span><span class="cx">                                 0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
</span><span class="cx">                                 0FEA0A09170513DB00BB722C /* FTLCapabilities.cpp in Sources */,
</span><ins>+                                0F338E1B1BF286EA0013C88F /* B3BlockInsertionSet.cpp in Sources */,
</ins><span class="cx">                                 0FEA0A271709623B00BB722C /* FTLCommonValues.cpp in Sources */,
</span><span class="cx">                                 0FEA0A0B170513DB00BB722C /* FTLCompile.cpp in Sources */,
</span><span class="cx">                                 0FE95F7918B5694700B531FB /* FTLDataSection.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerX86Commonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -247,6 +247,30 @@
</span><span class="cx">         m_assembler.imull_i32r(src, imm.m_value, dest);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void x86ConvertToDoubleWord32()
+    {
+        m_assembler.cdq();
+    }
+
+    void x86ConvertToDoubleWord32(RegisterID eax, RegisterID edx)
+    {
+        ASSERT_UNUSED(eax, eax == X86Registers::eax);
+        ASSERT_UNUSED(edx, edx == X86Registers::edx);
+        x86ConvertToDoubleWord32();
+    }
+
+    void x86Div32(RegisterID denominator)
+    {
+        m_assembler.idivl_r(denominator);
+    }
+
+    void x86Div32(RegisterID eax, RegisterID edx, RegisterID denominator)
+    {
+        ASSERT_UNUSED(eax, eax == X86Registers::eax);
+        ASSERT_UNUSED(edx, edx == X86Registers::edx);
+        x86Div32(denominator);
+    }
+
</ins><span class="cx">     void neg32(RegisterID srcDest)
</span><span class="cx">     {
</span><span class="cx">         m_assembler.negl_r(srcDest);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerMacroAssemblerX86_64h"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -386,6 +386,30 @@
</span><span class="cx">         m_assembler.imulq_rr(src, dest);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    void x86ConvertToQuadWord64()
+    {
+        m_assembler.cqo();
+    }
+
+    void x86ConvertToQuadWord64(RegisterID rax, RegisterID rdx)
+    {
+        ASSERT_UNUSED(rax, rax == X86Registers::eax);
+        ASSERT_UNUSED(rdx, rdx == X86Registers::edx);
+        x86ConvertToQuadWord64();
+    }
+
+    void x86Div64(RegisterID denominator)
+    {
+        m_assembler.idivq_r(denominator);
+    }
+
+    void x86Div64(RegisterID rax, RegisterID rdx, RegisterID denominator)
+    {
+        ASSERT_UNUSED(rax, rax == X86Registers::eax);
+        ASSERT_UNUSED(rdx, rdx == X86Registers::edx);
+        x86Div64(denominator);
+    }
+
</ins><span class="cx">     void neg64(RegisterID dest)
</span><span class="cx">     {
</span><span class="cx">         m_assembler.negq_r(dest);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerX86Assemblerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/X86Assembler.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/X86Assembler.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/assembler/X86Assembler.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -962,6 +962,13 @@
</span><span class="cx">         m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if CPU(X86_64)
+    void idivq_r(RegisterID dst)
+    {
+        m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
+    }
+#endif // CPU(X86_64)
+
</ins><span class="cx">     // Comparisons:
</span><span class="cx"> 
</span><span class="cx">     void cmpl_rr(RegisterID src, RegisterID dst)
</span><span class="lines">@@ -1294,6 +1301,13 @@
</span><span class="cx">         m_formatter.oneByteOp(OP_CDQ);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if CPU(X86_64)
+    void cqo()
+    {
+        m_formatter.oneByteOp64(OP_CDQ);
+    }
+#endif
+
</ins><span class="cx">     void fstps(int offset, RegisterID base)
</span><span class="cx">     {
</span><span class="cx">         m_formatter.oneByteOp(OP_ESCAPE_D9, ESCAPE_D9_FSTP_singleReal, base, offset);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BasicBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3BasicBlock.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -28,9 +28,11 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;B3BasicBlockInlines.h&quot;
</ins><span class="cx"> #include &quot;B3BasicBlockUtils.h&quot;
</span><ins>+#include &quot;B3ControlValue.h&quot;
</ins><span class="cx"> #include &quot;B3Procedure.h&quot;
</span><del>-#include &quot;B3Value.h&quot;
</del><ins>+#include &quot;B3ValueInlines.h&quot;
</ins><span class="cx"> #include &lt;wtf/ListDump.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="lines">@@ -52,6 +54,29 @@
</span><span class="cx">     m_values.append(value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BasicBlock::replaceLast(Procedure&amp; proc, Value* value)
+{
+    proc.deleteValue(last());
+    last() = value;
+}
+
+Value* BasicBlock::appendIntConstant(Procedure&amp; proc, Origin origin, Type type, int64_t value)
+{
+    Value* result = proc.addIntConstant(origin, type, value);
+    append(result);
+    return result;
+}
+
+Value* BasicBlock::appendIntConstant(Procedure&amp; proc, Value* likeValue, int64_t value)
+{
+    return appendIntConstant(proc, likeValue-&gt;origin(), likeValue-&gt;type(), value);
+}
+
+bool BasicBlock::replaceSuccessor(BasicBlock* from, BasicBlock* to)
+{
+    return last()-&gt;as&lt;ControlValue&gt;()-&gt;replaceSuccessor(from, to);
+}
+
</ins><span class="cx"> bool BasicBlock::addPredecessor(BasicBlock* block)
</span><span class="cx"> {
</span><span class="cx">     return B3::addPredecessor(this, block);
</span><span class="lines">@@ -67,6 +92,11 @@
</span><span class="cx">     return B3::replacePredecessor(this, from, to);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BasicBlock::updatePredecessorsAfter()
+{
+    B3::updatePredecessorsAfter(this);
+}
+
</ins><span class="cx"> void BasicBlock::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><span class="cx">     out.print(dumpPrefix, m_index);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BasicBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3BasicBlock.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BasicBlock.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3BasicBlock.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -29,11 +29,14 @@
</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;B3Origin.h&quot;
</ins><span class="cx"> #include &quot;B3SuccessorCollection.h&quot;
</span><ins>+#include &quot;B3Type.h&quot;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><ins>+class BlockInsertionSet;
</ins><span class="cx"> class InsertionSet;
</span><span class="cx"> class Procedure;
</span><span class="cx"> class Value;
</span><span class="lines">@@ -68,10 +71,17 @@
</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 replaceLast(Procedure&amp;, Value*);
</ins><span class="cx"> 
</span><span class="cx">     template&lt;typename ValueType, typename... Arguments&gt;
</span><span class="cx">     ValueType* appendNew(Procedure&amp;, Arguments...);
</span><span class="cx"> 
</span><ins>+    Value* appendIntConstant(Procedure&amp;, Origin, Type, int64_t value);
+    Value* appendIntConstant(Procedure&amp;, Value* likeValue, int64_t value);
+    
+    template&lt;typename ValueType, typename... Arguments&gt;
+    ValueType* replaceLastWithNew(Procedure&amp;, Arguments...);
+
</ins><span class="cx">     unsigned numSuccessors() const;
</span><span class="cx">     const FrequentedBlock&amp; successor(unsigned index) const;
</span><span class="cx">     FrequentedBlock&amp; successor(unsigned index);
</span><span class="lines">@@ -83,6 +93,8 @@
</span><span class="cx">     SuccessorCollection&lt;BasicBlock, SuccessorList&gt; successorBlocks();
</span><span class="cx">     SuccessorCollection&lt;const BasicBlock, const SuccessorList&gt; successorBlocks() const;
</span><span class="cx"> 
</span><ins>+    bool replaceSuccessor(BasicBlock* from, BasicBlock* to);
+
</ins><span class="cx">     unsigned numPredecessors() const { return m_predecessors.size(); }
</span><span class="cx">     BasicBlock* predecessor(unsigned index) const { return m_predecessors[index]; }
</span><span class="cx">     BasicBlock*&amp; predecessor(unsigned index) { return m_predecessors[index]; }
</span><span class="lines">@@ -94,12 +106,16 @@
</span><span class="cx">     bool removePredecessor(BasicBlock*);
</span><span class="cx">     bool replacePredecessor(BasicBlock* from, BasicBlock* to);
</span><span class="cx"> 
</span><ins>+    // Update predecessors starting with the successors of this block.
+    void updatePredecessorsAfter();
+
</ins><span class="cx">     double frequency() const { return m_frequency; }
</span><span class="cx"> 
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx">     void deepDump(PrintStream&amp;) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    friend class BlockInsertionSet;
</ins><span class="cx">     friend class InsertionSet;
</span><span class="cx">     friend class Procedure;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BasicBlockInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3BasicBlockInlines.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -42,6 +42,14 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;typename ValueType, typename... Arguments&gt;
+ValueType* BasicBlock::replaceLastWithNew(Procedure&amp; procedure, Arguments... arguments)
+{
+    ValueType* result = procedure.add&lt;ValueType&gt;(arguments...);
+    replaceLast(procedure, result);
+    return result;
+}
+
</ins><span class="cx"> inline unsigned BasicBlock::numSuccessors() const
</span><span class="cx"> {
</span><span class="cx">     return last()-&gt;as&lt;ControlValue&gt;()-&gt;numSuccessors();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BasicBlockUtilsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3BasicBlockUtils.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BasicBlockUtils.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3BasicBlockUtils.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -71,6 +71,20 @@
</span><span class="cx">     return changed;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;typename BasicBlock&gt;
+void updatePredecessorsAfter(BasicBlock* root)
+{
+    Vector&lt;BasicBlock*, 16&gt; worklist;
+    worklist.append(root);
+    while (!worklist.isEmpty()) {
+        BasicBlock* block = worklist.takeLast();
+        for (BasicBlock* successor : block-&gt;successorBlocks()) {
+            if (addPredecessor(successor, block))
+                worklist.append(successor);
+        }
+    }
+}
+
</ins><span class="cx"> // This recomputes predecessors and removes blocks that aren't reachable.
</span><span class="cx"> template&lt;typename BasicBlock, typename DeleteFunctor&gt;
</span><span class="cx"> void resetReachability(
</span><span class="lines">@@ -82,14 +96,7 @@
</span><span class="cx">             block-&gt;predecessors().resize(0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    GraphNodeWorklist&lt;BasicBlock*, IndexSet&lt;BasicBlock&gt;&gt; worklist;
-    worklist.push(blocks[0].get());
-    while (BasicBlock* block = worklist.pop()) {
-        for (BasicBlock* successor : block-&gt;successorBlocks()) {
-            addPredecessor(successor, block);
-            worklist.push(successor);
-        }
-    }
</del><ins>+    updatePredecessorsAfter(blocks[0].get());
</ins><span class="cx"> 
</span><span class="cx">     for (unsigned i = 1; i &lt; blocks.size(); ++i) {
</span><span class="cx">         if (!blocks[i])
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BlockInsertionSetcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.cpp (0 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -0,0 +1,129 @@
</span><ins>+/*
+ * Copyright (C) 2015 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;B3BlockInsertionSet.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3BasicBlockInlines.h&quot;
+#include &quot;B3InsertionSet.h&quot;
+#include &quot;B3ProcedureInlines.h&quot;
+#include &lt;wtf/BubbleSort.h&gt;
+
+namespace JSC { namespace B3 {
+
+BlockInsertionSet::BlockInsertionSet(Procedure &amp;proc)
+    : m_proc(proc)
+{
+}
+
+BlockInsertionSet::~BlockInsertionSet() { }
+
+void BlockInsertionSet::insert(BlockInsertion&amp;&amp; insertion)
+{
+    m_insertions.append(WTF::move(insertion));
+}
+
+BasicBlock* BlockInsertionSet::insert(unsigned index, double frequency)
+{
+    std::unique_ptr&lt;BasicBlock&gt; block(new BasicBlock(UINT_MAX, frequency));
+    BasicBlock* result = block.get();
+    insert(BlockInsertion(index, WTF::move(block)));
+    return result;
+}
+
+BasicBlock* BlockInsertionSet::insertBefore(BasicBlock* before, double frequency)
+{
+    return insert(before-&gt;index(), frequency == frequency ? frequency : before-&gt;frequency());
+}
+
+BasicBlock* BlockInsertionSet::splitForward(
+    BasicBlock* block, unsigned&amp; valueIndex, InsertionSet* insertionSet, double frequency)
+{
+    Value* value = block-&gt;at(valueIndex);
+
+    // Create a new block that will go just before 'block', and make it contain everything prior
+    // to 'valueIndex'.
+    BasicBlock* result = insertBefore(block, frequency);
+    result-&gt;m_values.resize(valueIndex + 1);
+    for (unsigned i = valueIndex; i--;)
+        result-&gt;m_values[i] = block-&gt;m_values[i];
+
+    // Make the new block jump to 'block'.
+    result-&gt;m_values[valueIndex] =
+        m_proc.add&lt;ControlValue&gt;(Jump, value-&gt;origin(), FrequentedBlock(block));
+
+    // If we had inserted things into 'block' before this, execute those insertions now.
+    if (insertionSet)
+        insertionSet-&gt;execute(result);
+
+    // Remove everything prior to 'valueIndex' from 'block', since those things are now in the
+    // new block.
+    block-&gt;m_values.remove(0, valueIndex);
+
+    // This is being used in a forward loop over 'block'. Update the index of the loop so that
+    // it can continue to the next block.
+    valueIndex = 0;
+
+    // Fixup the predecessors of 'block'. They now must jump to the new block.
+    result-&gt;predecessors() = WTF::move(block-&gt;predecessors());
+    block-&gt;addPredecessor(result);
+    for (BasicBlock* predecessor : result-&gt;predecessors())
+        predecessor-&gt;replaceSuccessor(block, result);
+
+    return result;
+}
+
+bool BlockInsertionSet::execute()
+{
+    if (m_insertions.isEmpty())
+        return false;
+    
+    // We allow insertions to be given to us in any order. So, we need to sort them before
+    // running WTF::executeInsertions. We strongly prefer a stable sort and we want it to be
+    // fast, so we use bubble sort.
+    bubbleSort(m_insertions.begin(), m_insertions.end());
+
+    executeInsertions(m_proc.m_blocks, m_insertions);
+    
+    // Prune out empty entries. This isn't strictly necessary but it's
+    // healthy to keep the block list from growing.
+    m_proc.m_blocks.removeAllMatching(
+        [&amp;] (std::unique_ptr&lt;BasicBlock&gt;&amp; blockPtr) -&gt; bool {
+            return !blockPtr;
+        });
+    
+    // Make sure that the blocks know their new indices.
+    for (unsigned i = 0; i &lt; m_proc.m_blocks.size(); ++i)
+        m_proc.m_blocks[i]-&gt;m_index = i;
+    
+    return true;
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3BlockInsertionSeth"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h (0 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3BlockInsertionSet.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+/*
+ * Copyright (C) 2015 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 B3BlockInsertionSet_h
+#define B3BlockInsertionSet_h
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3Procedure.h&quot;
+#include &lt;wtf/Insertion.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC { namespace B3 {
+
+class InsertionSet;
+
+typedef WTF::Insertion&lt;std::unique_ptr&lt;BasicBlock&gt;&gt; BlockInsertion;
+
+class BlockInsertionSet {
+public:
+    BlockInsertionSet(Procedure&amp;);
+    ~BlockInsertionSet();
+    
+    void insert(BlockInsertion&amp;&amp;);
+
+    // Insert a new block at a given index.
+    BasicBlock* insert(unsigned index, double frequency = PNaN);
+
+    // Inserts a new block before the given block. Usually you will not pass the frequency
+    // argument. Passing PNaN causes us to just use the frequency of the 'before' block. That's
+    // usually what you want.
+    BasicBlock* insertBefore(BasicBlock* before, double frequency = PNaN);
+
+    // A helper to split a block when forward iterating over it. It creates a new block to hold
+    // everything before the instruction at valueIndex. The current block is left with
+    // everything at and after valueIndex. If the optional InsertionSet is provided, it will get
+    // executed on the newly created block - this makes sense if you had previously inserted
+    // things into the original block, since the newly created block will be indexed identically
+    // 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:
+    //
+    // for (unsigned valueIndex = 0; valueIndex &lt; block-&gt;size(); ++valueIndex) {
+    //     Value* value = block-&gt;at(valueIndex);
+    //     if (value-&gt;opcode() == Foo) {
+    //         BasicBlock* predecessor =
+    //             m_blockInsertionSet.splitForward(block, valueIndex, &amp;m_insertionSet);
+    //         ... // Now you can append to predecessor, insert new blocks before 'block', and
+    //         ... // you can use m_insertionSet to insert more thing before 'value'.
+    //         predecessor-&gt;updatePredecessorsAfter();
+    //     }
+    // }
+    //
+    // Note how usually this idiom ends in a all to updatePredecessorsAftter(), which ensures
+    // that the predecessors involved in any of the new control flow that you've created are up
+    // to date.
+    BasicBlock* splitForward(
+        BasicBlock*, unsigned&amp; valueIndex, InsertionSet* = nullptr,
+        double frequency = PNaN);
+    
+    bool execute();
+
+private:
+    Procedure&amp; m_proc;
+    Vector&lt;BlockInsertion, 8&gt; m_insertions;
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3BlockInsertionSet_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Commonh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Common.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Common.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Common.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -94,6 +94,24 @@
</span><span class="cx">     return isRepresentableAsImpl&lt;ResultType, double, int64_t&gt;(value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline int32_t chillDiv(int32_t num, int32_t den)
+{
+    if (!den)
+        return 0;
+    if (den == -1 &amp;&amp; num == std::numeric_limits&lt;int32_t&gt;::min())
+        return num;
+    return num / den;
+}
+
+inline int64_t chillDiv(int64_t num, int64_t den)
+{
+    if (!den)
+        return 0;
+    if (den == -1 &amp;&amp; num == std::numeric_limits&lt;int64_t&gt;::min())
+        return num;
+    return num / den;
+}
+
</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="trunkSourceJavaScriptCoreb3B3Const32Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Const32Value.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -47,126 +47,133 @@
</span><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), m_value + other);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const32Value::addConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const32Value::addConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), m_value + other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const32Value::subConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const32Value::subConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), m_value - other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const32Value::bitAndConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const32Value::divConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><ins>+    return proc.add&lt;Const32Value&gt;(origin(), chillDiv(m_value, other-&gt;asInt32()));
+}
+
+Value* Const32Value::bitAndConstant(Procedure&amp; proc, const Value* other) const
+{
+    if (!other-&gt;hasInt32())
+        return nullptr;
</ins><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), m_value &amp; other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const32Value::bitOrConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const32Value::bitOrConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), m_value | other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const32Value::bitXorConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const32Value::bitXorConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), m_value ^ other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const32Value::shlConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const32Value::shlConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), m_value &lt;&lt; (other-&gt;asInt32() &amp; 31));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const32Value::sShrConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const32Value::sShrConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), m_value &gt;&gt; (other-&gt;asInt32() &amp; 31));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const32Value::zShrConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const32Value::zShrConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const32Value&gt;(origin(), static_cast&lt;int32_t&gt;(static_cast&lt;uint32_t&gt;(m_value) &gt;&gt; (other-&gt;asInt32() &amp; 31)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::equalConstant(Value* other) const
</del><ins>+TriState Const32Value::equalConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value == other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::notEqualConstant(Value* other) const
</del><ins>+TriState Const32Value::notEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value != other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::lessThanConstant(Value* other) const
</del><ins>+TriState Const32Value::lessThanConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &lt; other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::greaterThanConstant(Value* other) const
</del><ins>+TriState Const32Value::greaterThanConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &gt; other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::lessEqualConstant(Value* other) const
</del><ins>+TriState Const32Value::lessEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &lt;= other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::greaterEqualConstant(Value* other) const
</del><ins>+TriState Const32Value::greaterEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &gt;= other-&gt;asInt32());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::aboveConstant(Value* other) const
</del><ins>+TriState Const32Value::aboveConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(static_cast&lt;uint32_t&gt;(m_value) &gt; static_cast&lt;uint32_t&gt;(other-&gt;asInt32()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::belowConstant(Value* other) const
</del><ins>+TriState Const32Value::belowConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(static_cast&lt;uint32_t&gt;(m_value) &lt; static_cast&lt;uint32_t&gt;(other-&gt;asInt32()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::aboveEqualConstant(Value* other) const
</del><ins>+TriState Const32Value::aboveEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(static_cast&lt;uint32_t&gt;(m_value) &gt;= static_cast&lt;uint32_t&gt;(other-&gt;asInt32()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const32Value::belowEqualConstant(Value* other) const
</del><ins>+TriState Const32Value::belowEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return MixedTriState;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const32Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const32Value.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const32Value.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Const32Value.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -42,25 +42,26 @@
</span><span class="cx"> 
</span><span class="cx">     Value* negConstant(Procedure&amp;) const override;
</span><span class="cx">     Value* addConstant(Procedure&amp;, int32_t other) const override;
</span><del>-    Value* addConstant(Procedure&amp;, Value* other) const override;
-    Value* subConstant(Procedure&amp;, Value* other) const override;
-    Value* bitAndConstant(Procedure&amp;, Value* other) const override;
-    Value* bitOrConstant(Procedure&amp;, Value* other) const override;
-    Value* bitXorConstant(Procedure&amp;, Value* other) const override;
-    Value* shlConstant(Procedure&amp;, Value* other) const override;
-    Value* sShrConstant(Procedure&amp;, Value* other) const override;
-    Value* zShrConstant(Procedure&amp;, Value* other) const override;
</del><ins>+    Value* addConstant(Procedure&amp;, const Value* other) const override;
+    Value* subConstant(Procedure&amp;, const Value* other) const override;
+    Value* divConstant(Procedure&amp;, const Value* other) const override;
+    Value* bitAndConstant(Procedure&amp;, const Value* other) const override;
+    Value* bitOrConstant(Procedure&amp;, const Value* other) const override;
+    Value* bitXorConstant(Procedure&amp;, const Value* other) const override;
+    Value* shlConstant(Procedure&amp;, const Value* other) const override;
+    Value* sShrConstant(Procedure&amp;, const Value* other) const override;
+    Value* zShrConstant(Procedure&amp;, const Value* other) const override;
</ins><span class="cx"> 
</span><del>-    TriState equalConstant(Value* other) const override;
-    TriState notEqualConstant(Value* other) const override;
-    TriState lessThanConstant(Value* other) const override;
-    TriState greaterThanConstant(Value* other) const override;
-    TriState lessEqualConstant(Value* other) const override;
-    TriState greaterEqualConstant(Value* other) const override;
-    TriState aboveConstant(Value* other) const override;
-    TriState belowConstant(Value* other) const override;
-    TriState aboveEqualConstant(Value* other) const override;
-    TriState belowEqualConstant(Value* other) const override;
</del><ins>+    TriState equalConstant(const Value* other) const override;
+    TriState notEqualConstant(const Value* other) const override;
+    TriState lessThanConstant(const Value* other) const override;
+    TriState greaterThanConstant(const Value* other) const override;
+    TriState lessEqualConstant(const Value* other) const override;
+    TriState greaterEqualConstant(const Value* other) const override;
+    TriState aboveConstant(const Value* other) const override;
+    TriState belowConstant(const Value* other) const override;
+    TriState aboveEqualConstant(const Value* other) const override;
+    TriState belowEqualConstant(const Value* other) const override;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const64Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Const64Value.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -47,126 +47,133 @@
</span><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), m_value + static_cast&lt;int64_t&gt;(other));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const64Value::addConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const64Value::addConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), m_value + other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const64Value::subConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const64Value::subConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), m_value - other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const64Value::bitAndConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const64Value::divConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return nullptr;
</span><ins>+    return proc.add&lt;Const64Value&gt;(origin(), chillDiv(m_value, other-&gt;asInt64()));
+}
+
+Value* Const64Value::bitAndConstant(Procedure&amp; proc, const Value* other) const
+{
+    if (!other-&gt;hasInt64())
+        return nullptr;
</ins><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), m_value &amp; other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const64Value::bitOrConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const64Value::bitOrConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), m_value | other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const64Value::bitXorConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const64Value::bitXorConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), m_value ^ other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const64Value::shlConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const64Value::shlConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), m_value &lt;&lt; (other-&gt;asInt32() &amp; 63));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const64Value::sShrConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const64Value::sShrConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), m_value &gt;&gt; (other-&gt;asInt32() &amp; 63));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Const64Value::zShrConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* Const64Value::zShrConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt32())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;Const64Value&gt;(origin(), static_cast&lt;int64_t&gt;(static_cast&lt;uint64_t&gt;(m_value) &gt;&gt; (other-&gt;asInt32() &amp; 63)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::equalConstant(Value* other) const
</del><ins>+TriState Const64Value::equalConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value == other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::notEqualConstant(Value* other) const
</del><ins>+TriState Const64Value::notEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value != other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::lessThanConstant(Value* other) const
</del><ins>+TriState Const64Value::lessThanConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &lt; other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::greaterThanConstant(Value* other) const
</del><ins>+TriState Const64Value::greaterThanConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &gt; other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::lessEqualConstant(Value* other) const
</del><ins>+TriState Const64Value::lessEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &lt;= other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::greaterEqualConstant(Value* other) const
</del><ins>+TriState Const64Value::greaterEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &gt;= other-&gt;asInt64());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::aboveConstant(Value* other) const
</del><ins>+TriState Const64Value::aboveConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(static_cast&lt;uint64_t&gt;(m_value) &gt; static_cast&lt;uint64_t&gt;(other-&gt;asInt64()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::belowConstant(Value* other) const
</del><ins>+TriState Const64Value::belowConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(static_cast&lt;uint64_t&gt;(m_value) &lt; static_cast&lt;uint64_t&gt;(other-&gt;asInt64()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::aboveEqualConstant(Value* other) const
</del><ins>+TriState Const64Value::aboveEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(static_cast&lt;uint64_t&gt;(m_value) &gt;= static_cast&lt;uint64_t&gt;(other-&gt;asInt64()));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Const64Value::belowEqualConstant(Value* other) const
</del><ins>+TriState Const64Value::belowEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasInt64())
</span><span class="cx">         return MixedTriState;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Const64Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Const64Value.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Const64Value.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Const64Value.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -42,25 +42,26 @@
</span><span class="cx"> 
</span><span class="cx">     Value* negConstant(Procedure&amp;) const override;
</span><span class="cx">     Value* addConstant(Procedure&amp;, int32_t other) const override;
</span><del>-    Value* addConstant(Procedure&amp;, Value* other) const override;
-    Value* subConstant(Procedure&amp;, Value* other) const override;
-    Value* bitAndConstant(Procedure&amp;, Value* other) const override;
-    Value* bitOrConstant(Procedure&amp;, Value* other) const override;
-    Value* bitXorConstant(Procedure&amp;, Value* other) const override;
-    Value* shlConstant(Procedure&amp;, Value* other) const override;
-    Value* sShrConstant(Procedure&amp;, Value* other) const override;
-    Value* zShrConstant(Procedure&amp;, Value* other) const override;
</del><ins>+    Value* addConstant(Procedure&amp;, const Value* other) const override;
+    Value* subConstant(Procedure&amp;, const Value* other) const override;
+    Value* divConstant(Procedure&amp;, const Value* other) const override;
+    Value* bitAndConstant(Procedure&amp;, const Value* other) const override;
+    Value* bitOrConstant(Procedure&amp;, const Value* other) const override;
+    Value* bitXorConstant(Procedure&amp;, const Value* other) const override;
+    Value* shlConstant(Procedure&amp;, const Value* other) const override;
+    Value* sShrConstant(Procedure&amp;, const Value* other) const override;
+    Value* zShrConstant(Procedure&amp;, const Value* other) const override;
</ins><span class="cx"> 
</span><del>-    TriState equalConstant(Value* other) const override;
-    TriState notEqualConstant(Value* other) const override;
-    TriState lessThanConstant(Value* other) const override;
-    TriState greaterThanConstant(Value* other) const override;
-    TriState lessEqualConstant(Value* other) const override;
-    TriState greaterEqualConstant(Value* other) const override;
-    TriState aboveConstant(Value* other) const override;
-    TriState belowConstant(Value* other) const override;
-    TriState aboveEqualConstant(Value* other) const override;
-    TriState belowEqualConstant(Value* other) const override;
</del><ins>+    TriState equalConstant(const Value* other) const override;
+    TriState notEqualConstant(const Value* other) const override;
+    TriState lessThanConstant(const Value* other) const override;
+    TriState greaterThanConstant(const Value* other) const override;
+    TriState lessEqualConstant(const Value* other) const override;
+    TriState greaterEqualConstant(const Value* other) const override;
+    TriState aboveConstant(const Value* other) const override;
+    TriState belowConstant(const Value* other) const override;
+    TriState aboveEqualConstant(const Value* other) const override;
+    TriState belowEqualConstant(const Value* other) const override;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstDoubleValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -47,56 +47,63 @@
</span><span class="cx">     return proc.add&lt;ConstDoubleValue&gt;(origin(), m_value + static_cast&lt;double&gt;(other));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* ConstDoubleValue::addConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* ConstDoubleValue::addConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasDouble())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;ConstDoubleValue&gt;(origin(), m_value + other-&gt;asDouble());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* ConstDoubleValue::subConstant(Procedure&amp; proc, Value* other) const
</del><ins>+Value* ConstDoubleValue::subConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasDouble())
</span><span class="cx">         return nullptr;
</span><span class="cx">     return proc.add&lt;ConstDoubleValue&gt;(origin(), m_value - other-&gt;asDouble());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState ConstDoubleValue::equalConstant(Value* other) const
</del><ins>+Value* ConstDoubleValue::divConstant(Procedure&amp; proc, const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasDouble())
</span><ins>+        return nullptr;
+    return proc.add&lt;ConstDoubleValue&gt;(origin(), m_value / other-&gt;asDouble());
+}
+
+TriState ConstDoubleValue::equalConstant(const Value* other) const
+{
+    if (!other-&gt;hasDouble())
</ins><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value == other-&gt;asDouble());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState ConstDoubleValue::notEqualConstant(Value* other) const
</del><ins>+TriState ConstDoubleValue::notEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasDouble())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value != other-&gt;asDouble());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState ConstDoubleValue::lessThanConstant(Value* other) const
</del><ins>+TriState ConstDoubleValue::lessThanConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasDouble())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &lt; other-&gt;asDouble());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState ConstDoubleValue::greaterThanConstant(Value* other) const
</del><ins>+TriState ConstDoubleValue::greaterThanConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasDouble())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &gt; other-&gt;asDouble());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState ConstDoubleValue::lessEqualConstant(Value* other) const
</del><ins>+TriState ConstDoubleValue::lessEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasDouble())
</span><span class="cx">         return MixedTriState;
</span><span class="cx">     return triState(m_value &lt;= other-&gt;asDouble());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState ConstDoubleValue::greaterEqualConstant(Value* other) const
</del><ins>+TriState ConstDoubleValue::greaterEqualConstant(const Value* other) const
</ins><span class="cx"> {
</span><span class="cx">     if (!other-&gt;hasDouble())
</span><span class="cx">         return MixedTriState;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ConstDoubleValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3ConstDoubleValue.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -40,17 +40,18 @@
</span><span class="cx">     
</span><span class="cx">     double value() const { return m_value; }
</span><span class="cx"> 
</span><del>-    Value* negConstant(Procedure&amp; proc) const override;
-    Value* addConstant(Procedure&amp; proc, int32_t other) const override;
-    Value* addConstant(Procedure&amp; proc, Value* other) const override;
-    Value* subConstant(Procedure&amp; proc, Value* other) const override;
</del><ins>+    Value* negConstant(Procedure&amp;) const override;
+    Value* addConstant(Procedure&amp;, int32_t other) const override;
+    Value* addConstant(Procedure&amp;, const Value* other) const override;
+    Value* subConstant(Procedure&amp;, const Value* other) const override;
+    Value* divConstant(Procedure&amp;, const Value* other) const override;
</ins><span class="cx"> 
</span><del>-    TriState equalConstant(Value* other) const override;
-    TriState notEqualConstant(Value* other) const override;
-    TriState lessThanConstant(Value* other) const override;
-    TriState greaterThanConstant(Value* other) const override;
-    TriState lessEqualConstant(Value* other) const override;
-    TriState greaterEqualConstant(Value* other) const override;
</del><ins>+    TriState equalConstant(const Value* other) const override;
+    TriState notEqualConstant(const Value* other) const override;
+    TriState lessThanConstant(const Value* other) const override;
+    TriState greaterThanConstant(const Value* other) const override;
+    TriState lessEqualConstant(const Value* other) const override;
+    TriState greaterEqualConstant(const Value* other) const override;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ControlValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3ControlValue.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -36,15 +36,30 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ControlValue::convertToJump(const FrequentedBlock&amp; destination)
</del><ins>+bool ControlValue::replaceSuccessor(BasicBlock* from, BasicBlock* to)
</ins><span class="cx"> {
</span><ins>+    bool result = false;
+    for (FrequentedBlock&amp; successor : m_successors) {
+        if (successor.block() == from) {
+            successor.block() = to;
+            result = true;
+
+            // Keep looping because it's valid for a successor to be mentioned multiple times,
+            // like if multiple switch cases have the same target.
+        }
+    }
+    return result;
+}
+
+void ControlValue::convertToJump(BasicBlock* destination)
+{
</ins><span class="cx">     unsigned index = this-&gt;index();
</span><span class="cx">     Origin origin = this-&gt;origin();
</span><span class="cx">     BasicBlock* owner = this-&gt;owner;
</span><span class="cx"> 
</span><span class="cx">     this-&gt;ControlValue::~ControlValue();
</span><span class="cx"> 
</span><del>-    new (this) ControlValue(index, Jump, origin, destination);
</del><ins>+    new (this) ControlValue(index, Jump, origin, FrequentedBlock(destination));
</ins><span class="cx"> 
</span><span class="cx">     this-&gt;owner = owner;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ControlValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ControlValue.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ControlValue.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3ControlValue.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -64,6 +64,8 @@
</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>+    bool replaceSuccessor(BasicBlock* from, BasicBlock* to);
+
</ins><span class="cx">     const FrequentedBlock&amp; taken() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(opcode() == Jump || opcode() == Branch);
</span><span class="lines">@@ -85,7 +87,7 @@
</span><span class="cx">         return successor(1);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void convertToJump(const FrequentedBlock&amp; destination);
</del><ins>+    void convertToJump(BasicBlock* destination);
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&amp;, PrintStream&amp;) const override;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Generatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Generate.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Generate.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Generate.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -32,6 +32,7 @@
</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;B3LowerMacros.h&quot;
</ins><span class="cx"> #include &quot;B3LowerToAir.h&quot;
</span><span class="cx"> #include &quot;B3MoveConstants.h&quot;
</span><span class="cx"> #include &quot;B3Procedure.h&quot;
</span><span class="lines">@@ -66,6 +67,8 @@
</span><span class="cx">         dataLog(procedure);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    lowerMacros(procedure);
+
</ins><span class="cx">     reduceStrength(procedure);
</span><span class="cx">     
</span><span class="cx">     // FIXME: Add more optimizations here.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3GenericFrequentedBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3GenericFrequentedBlock.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3GenericFrequentedBlock.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3GenericFrequentedBlock.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -65,6 +65,7 @@
</span><span class="cx">     BasicBlock* block() const { return m_block; }
</span><span class="cx">     BasicBlock*&amp; block() { return m_block; }
</span><span class="cx">     FrequencyClass frequency() const { return m_frequency; }
</span><ins>+    FrequencyClass&amp; frequency() { return m_frequency; }
</ins><span class="cx"> 
</span><span class="cx">     void dump(PrintStream&amp; out) const
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3InsertionSetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -29,10 +29,22 @@
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;B3BasicBlock.h&quot;
</span><ins>+#include &quot;B3ProcedureInlines.h&quot;
+#include &quot;B3ValueInlines.h&quot;
</ins><span class="cx"> #include &lt;wtf/BubbleSort.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><ins>+Value* InsertionSet::insertIntConstant(size_t index, Origin origin, Type type, int64_t value)
+{
+    return insertValue(index, m_procedure.addIntConstant(origin, type, value));
+}
+
+Value* InsertionSet::insertIntConstant(size_t index, Value* likeValue, int64_t value)
+{
+    return insertIntConstant(index, likeValue-&gt;origin(), likeValue-&gt;type(), value);
+}
+
</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 (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3InsertionSet.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3InsertionSet.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -28,6 +28,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(B3_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;B3Origin.h&quot;
+#include &quot;B3Type.h&quot;
</ins><span class="cx"> #include &lt;wtf/Insertion.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -62,6 +64,9 @@
</span><span class="cx">     template&lt;typename ValueType, typename... Arguments&gt;
</span><span class="cx">     Value* insert(size_t index, Arguments... arguments);
</span><span class="cx"> 
</span><ins>+    Value* insertIntConstant(size_t index, Origin, Type, int64_t value);
+    Value* insertIntConstant(size_t index, Value* likeValue, int64_t value);
+
</ins><span class="cx">     void execute(BasicBlock*);
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerMacroscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/b3/B3LowerMacros.cpp (0 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerMacros.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3LowerMacros.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -0,0 +1,212 @@
</span><ins>+/*
+ * Copyright (C) 2015 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;B3LowerMacros.h&quot;
+
+#if ENABLE(B3_JIT)
+
+#include &quot;B3BasicBlockInlines.h&quot;
+#include &quot;B3BlockInsertionSet.h&quot;
+#include &quot;B3ControlValue.h&quot;
+#include &quot;B3InsertionSetInlines.h&quot;
+#include &quot;B3PhaseScope.h&quot;
+#include &quot;B3ProcedureInlines.h&quot;
+#include &quot;B3UpsilonValue.h&quot;
+#include &quot;B3ValueInlines.h&quot;
+
+namespace JSC { namespace B3 {
+
+namespace {
+
+class LowerMacros {
+public:
+    LowerMacros(Procedure&amp; proc)
+        : m_proc(proc)
+        , m_blockInsertionSet(proc)
+        , m_insertionSet(proc)
+    {
+    }
+
+    bool run()
+    {
+        for (BasicBlock* block : m_proc) {
+            m_block = block;
+            processCurrentBlock();
+        }
+        m_changed |= m_blockInsertionSet.execute();
+        if (m_changed)
+            m_proc.resetReachability();
+        return m_changed;
+    }
+    
+private:
+    void processCurrentBlock()
+    {
+        for (m_index = 0; m_index &lt; m_block-&gt;size(); ++m_index) {
+            m_value = m_block-&gt;at(m_index);
+            switch (m_value-&gt;opcode()) {
+            case ChillDiv: {
+                // ARM supports this instruction natively.
+                if (isARM64())
+                    break;
+
+                m_changed = true;
+
+                // We implement &quot;res = ChillDiv(num, den)&quot; as follows:
+                //
+                //     if (den + 1 &lt;=_unsigned 1) {
+                //         if (!den) {
+                //             res = 0;
+                //             goto done;
+                //         }
+                //         if (num == -2147483648) {
+                //             res = num;
+                //             goto done;
+                //         }
+                //     }
+                //     res = num / dev;
+                // done:
+
+                Value* num = m_value-&gt;child(0);
+                Value* den = m_value-&gt;child(1);
+
+                Value* one =
+                    m_insertionSet.insertIntConstant(m_index, m_value, 1);
+                Value* isDenOK = m_insertionSet.insert&lt;Value&gt;(
+                    m_index, Above, m_value-&gt;origin(),
+                    m_insertionSet.insert&lt;Value&gt;(m_index, Add, m_value-&gt;origin(), den, one),
+                    one);
+
+                BasicBlock* before =
+                    m_blockInsertionSet.splitForward(m_block, m_index, &amp;m_insertionSet);
+
+                BasicBlock* normalDivCase = m_blockInsertionSet.insertBefore(m_block);
+                BasicBlock* shadyDenCase = m_blockInsertionSet.insertBefore(m_block);
+                BasicBlock* zeroDenCase = m_blockInsertionSet.insertBefore(m_block);
+                BasicBlock* neg1DenCase = m_blockInsertionSet.insertBefore(m_block);
+                BasicBlock* intMinCase = m_blockInsertionSet.insertBefore(m_block);
+
+                before-&gt;replaceLastWithNew&lt;ControlValue&gt;(
+                    m_proc, Branch, m_value-&gt;origin(), isDenOK,
+                    FrequentedBlock(normalDivCase, FrequencyClass::Normal),
+                    FrequentedBlock(shadyDenCase, FrequencyClass::Rare));
+
+                UpsilonValue* normalResult = normalDivCase-&gt;appendNew&lt;UpsilonValue&gt;(
+                    m_proc, m_value-&gt;origin(),
+                    normalDivCase-&gt;appendNew&lt;Value&gt;(m_proc, Div, m_value-&gt;origin(), num, den));
+                normalDivCase-&gt;appendNew&lt;ControlValue&gt;(
+                    m_proc, Jump, m_value-&gt;origin(), FrequentedBlock(m_block));
+
+                shadyDenCase-&gt;appendNew&lt;ControlValue&gt;(
+                    m_proc, Branch, m_value-&gt;origin(), den,
+                    FrequentedBlock(neg1DenCase, FrequencyClass::Normal),
+                    FrequentedBlock(zeroDenCase, FrequencyClass::Rare));
+
+                UpsilonValue* zeroResult = zeroDenCase-&gt;appendNew&lt;UpsilonValue&gt;(
+                    m_proc, m_value-&gt;origin(),
+                    zeroDenCase-&gt;appendIntConstant(m_proc, m_value, 0));
+                zeroDenCase-&gt;appendNew&lt;ControlValue&gt;(
+                    m_proc, Jump, m_value-&gt;origin(), FrequentedBlock(m_block));
+
+                int64_t badNumeratorConst;
+                switch (m_value-&gt;type()) {
+                case Int32:
+                    badNumeratorConst = std::numeric_limits&lt;int32_t&gt;::min();
+                    break;
+                case Int64:
+                    badNumeratorConst = std::numeric_limits&lt;int64_t&gt;::min();
+                    break;
+                default:
+                    ASSERT_NOT_REACHED();
+                    badNumeratorConst = 0;
+                }
+
+                Value* badNumerator =
+                    neg1DenCase-&gt;appendIntConstant(m_proc, m_value, badNumeratorConst);
+
+                neg1DenCase-&gt;appendNew&lt;ControlValue&gt;(
+                    m_proc, Branch, m_value-&gt;origin(),
+                    neg1DenCase-&gt;appendNew&lt;Value&gt;(
+                        m_proc, Equal, m_value-&gt;origin(), num, badNumerator),
+                    FrequentedBlock(intMinCase, FrequencyClass::Rare),
+                    FrequentedBlock(normalDivCase, FrequencyClass::Normal));
+
+                UpsilonValue* intMinResult = intMinCase-&gt;appendNew&lt;UpsilonValue&gt;(
+                    m_proc, m_value-&gt;origin(), badNumerator);
+                intMinCase-&gt;appendNew&lt;ControlValue&gt;(
+                    m_proc, Jump, m_value-&gt;origin(), FrequentedBlock(m_block));
+
+                Value* phi = m_insertionSet.insert&lt;Value&gt;(
+                    m_index, Phi, m_value-&gt;type(), m_value-&gt;origin());
+                normalResult-&gt;setPhi(phi);
+                zeroResult-&gt;setPhi(phi);
+                intMinResult-&gt;setPhi(phi);
+
+                m_value-&gt;replaceWithIdentity(phi);
+                before-&gt;updatePredecessorsAfter();
+                break;
+            }
+
+            // FIXME: Implement Switch.
+            // https://bugs.webkit.org/show_bug.cgi?id=151115
+
+            default:
+                break;
+            }
+        }
+        m_insertionSet.execute(m_block);
+    }
+    
+    Procedure&amp; m_proc;
+    BlockInsertionSet m_blockInsertionSet;
+    InsertionSet m_insertionSet;
+    BasicBlock* m_block;
+    unsigned m_index;
+    Value* m_value;
+    bool m_changed { false };
+};
+
+bool lowerMacrosImpl(Procedure&amp; proc)
+{
+    LowerMacros lowerMacros(proc);
+    return lowerMacros.run();
+}
+
+} // anonymous namespace
+
+bool lowerMacros(Procedure&amp; proc)
+{
+    PhaseScope phaseScope(proc, &quot;lowerMacros&quot;);
+    bool result = lowerMacrosImpl(proc);
+    if (shouldValidateIR())
+        RELEASE_ASSERT(!lowerMacrosImpl(proc));
+    return result;
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerMacroshfromrev192294trunkSourceJavaScriptCoreb3B3InsertionSetcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/b3/B3LowerMacros.h (from rev 192294, trunk/Source/JavaScriptCore/b3/B3InsertionSet.cpp) (0 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerMacros.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/b3/B3LowerMacros.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2015 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 B3LowerMacros_h
+#define B3LowerMacros_h
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+class Procedure;
+
+// Lowers high-level operations that it's easier to deal with once they are broken up. Currently
+// this includes Switch and ChillDiv.
+
+bool lowerMacros(Procedure&amp;);
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3LowerMacros_h
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3LowerToAircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -1233,6 +1233,40 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case Div: {
+            if (isInt(m_value-&gt;type())) {
+                Tmp eax = Tmp(X86Registers::eax);
+                Tmp edx = Tmp(X86Registers::edx);
+
+                Air::Opcode convertToDoubleWord;
+                Air::Opcode div;
+                switch (m_value-&gt;type()) {
+                case Int32:
+                    convertToDoubleWord = X86ConvertToDoubleWord32;
+                    div = X86Div32;
+                    break;
+                case Int64:
+                    convertToDoubleWord = X86ConvertToQuadWord64;
+                    div = X86Div64;
+                    break;
+                default:
+                    RELEASE_ASSERT_NOT_REACHED();
+                    return;
+                }
+                
+                append(Move, tmp(m_value-&gt;child(0)), eax);
+                append(convertToDoubleWord, eax, edx);
+                append(div, eax, edx, tmp(m_value-&gt;child(1)));
+                append(Move, eax, tmp(m_value));
+                return;
+            }
+
+            // FIXME: Support doubles.
+            // https://bugs.webkit.org/show_bug.cgi?id=150991
+            RELEASE_ASSERT_NOT_REACHED();
+            return;
+        }
+
</ins><span class="cx">         case BitAnd: {
</span><span class="cx">             appendBinOp&lt;And32, And64, Air::Oops, Commutative&gt;(
</span><span class="cx">                 m_value-&gt;child(0), m_value-&gt;child(1));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Opcodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Opcode.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Opcode.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Opcode.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx">     Add,
</span><span class="cx">     Sub,
</span><span class="cx">     Mul,
</span><del>-    Div,
</del><ins>+    Div, // All bets are off as to what will happen when you execute this for -2^31/-1 and x/0.
</ins><span class="cx"> 
</span><span class="cx">     // Integer math.
</span><span class="cx">     ChillDiv, // doesn't trap ever, behaves like JS (x/y)|0.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedurecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -55,23 +55,28 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Procedure::addIntConstant(Type type, int64_t value)
</del><ins>+Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
</ins><span class="cx"> {
</span><span class="cx">     switch (type) {
</span><span class="cx">     case Int32:
</span><del>-        return add&lt;Const32Value&gt;(Origin(), static_cast&lt;int32_t&gt;(value));
</del><ins>+        return add&lt;Const32Value&gt;(origin, static_cast&lt;int32_t&gt;(value));
</ins><span class="cx">     case Int64:
</span><del>-        return add&lt;Const64Value&gt;(Origin(), value);
</del><ins>+        return add&lt;Const64Value&gt;(origin, value);
</ins><span class="cx">     case Double:
</span><del>-        return add&lt;ConstDoubleValue&gt;(Origin(), static_cast&lt;double&gt;(value));
</del><ins>+        return add&lt;ConstDoubleValue&gt;(origin, static_cast&lt;double&gt;(value));
</ins><span class="cx">     default:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Procedure::addBoolConstant(TriState triState)
</del><ins>+Value* Procedure::addIntConstant(Value* likeValue, int64_t value)
</ins><span class="cx"> {
</span><ins>+    return addIntConstant(likeValue-&gt;origin(), likeValue-&gt;type(), value);
+}
+
+Value* Procedure::addBoolConstant(Origin origin, TriState triState)
+{
</ins><span class="cx">     int32_t value = 0;
</span><span class="cx">     switch (triState) {
</span><span class="cx">     case FalseTriState:
</span><span class="lines">@@ -84,7 +89,7 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return addIntConstant(Int32, value);
</del><ins>+    return addIntConstant(origin, Int32, value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Procedure::resetValueOwners()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Procedureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Procedure.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Procedure.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Procedure.h        2015-11-11 07:21:23 UTC (rev 192295)
</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;B3Origin.h&quot;
</ins><span class="cx"> #include &quot;B3Type.h&quot;
</span><span class="cx"> #include &quot;PureNaN.h&quot;
</span><span class="cx"> #include &lt;wtf/Bag.h&gt;
</span><span class="lines">@@ -40,6 +41,7 @@
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><span class="cx"> class BasicBlock;
</span><ins>+class BlockInsertionSet;
</ins><span class="cx"> class OpaqueByproducts;
</span><span class="cx"> class Value;
</span><span class="cx"> 
</span><span class="lines">@@ -56,10 +58,11 @@
</span><span class="cx">     template&lt;typename ValueType, typename... Arguments&gt;
</span><span class="cx">     ValueType* add(Arguments...);
</span><span class="cx"> 
</span><del>-    Value* addIntConstant(Type, int64_t value);
</del><ins>+    Value* addIntConstant(Origin, Type, int64_t value);
+    Value* addIntConstant(Value*, int64_t value);
</ins><span class="cx"> 
</span><span class="cx">     // Returns null for MixedTriState.
</span><del>-    Value* addBoolConstant(TriState);
</del><ins>+    Value* addBoolConstant(Origin, TriState);
</ins><span class="cx"> 
</span><span class="cx">     void resetValueOwners();
</span><span class="cx">     void resetReachability();
</span><span class="lines">@@ -216,6 +219,8 @@
</span><span class="cx">     std::unique_ptr&lt;OpaqueByproducts&gt; takeByproducts() { return WTF::move(m_byproducts); }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    friend class BlockInsertionSet;
+    
</ins><span class="cx">     JS_EXPORT_PRIVATE size_t addValueIndex();
</span><span class="cx">     
</span><span class="cx">     Vector&lt;std::unique_ptr&lt;BasicBlock&gt;&gt; m_blocks;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3ReduceStrengthcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3ReduceStrength.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -186,6 +186,16 @@
</span><span class="cx"> 
</span><span class="cx">             break;
</span><span class="cx"> 
</span><ins>+        case Div:
+        case ChillDiv:
+            // Turn this: Div(constant1, constant2)
+            // Into this: constant1 / constant2
+            // Note that this uses ChillDiv semantics. That's fine, because the rules for Div
+            // are strictly weaker: it has corner cases where it's allowed to do anything it
+            // likes.
+            replaceWithNewValue(m_value-&gt;child(0)-&gt;divConstant(m_proc, m_value-&gt;child(1)));
+            break;
+
</ins><span class="cx">         case BitAnd:
</span><span class="cx">             handleCommutativity();
</span><span class="cx"> 
</span><span class="lines">@@ -318,7 +328,7 @@
</span><span class="cx">             // Turn this: BitXor(valueX, valueX)
</span><span class="cx">             // Into this: zero-constant.
</span><span class="cx">             if (m_value-&gt;child(0) == m_value-&gt;child(1)) {
</span><del>-                replaceWithNewValue(m_proc.addIntConstant(m_value-&gt;type(), 0));
</del><ins>+                replaceWithNewValue(m_proc.addIntConstant(m_value, 0));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -446,7 +456,9 @@
</span><span class="cx">             // Turn this: Equal(const1, const2)
</span><span class="cx">             // Into this: const1 == const2
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;equalConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;equalConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case NotEqual:
</span><span class="lines">@@ -473,7 +485,9 @@
</span><span class="cx">             // Turn this: NotEqual(const1, const2)
</span><span class="cx">             // Into this: const1 != const2
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;notEqualConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;notEqualConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case LessThan:
</span><span class="lines">@@ -481,42 +495,58 @@
</span><span class="cx">             // https://bugs.webkit.org/show_bug.cgi?id=150958
</span><span class="cx"> 
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;lessThanConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;lessThanConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case GreaterThan:
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;greaterThanConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;greaterThanConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case LessEqual:
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;lessEqualConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;lessEqualConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case GreaterEqual:
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;greaterEqualConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;greaterEqualConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case Above:
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;aboveConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;aboveConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case Below:
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;belowConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;belowConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case AboveEqual:
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;aboveEqualConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;aboveEqualConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case BelowEqual:
</span><span class="cx">             replaceWithNewValue(
</span><del>-                m_proc.addBoolConstant(m_value-&gt;child(0)-&gt;belowEqualConstant(m_value-&gt;child(1))));
</del><ins>+                m_proc.addBoolConstant(
+                    m_value-&gt;origin(),
+                    m_value-&gt;child(0)-&gt;belowEqualConstant(m_value-&gt;child(1))));
</ins><span class="cx">             break;
</span><span class="cx"> 
</span><span class="cx">         case Branch: {
</span><span class="lines">@@ -553,7 +583,7 @@
</span><span class="cx">             // Into this: Jump(else)
</span><span class="cx">             if (triState == FalseTriState) {
</span><span class="cx">                 branch-&gt;taken().block()-&gt;removePredecessor(m_block);
</span><del>-                branch-&gt;convertToJump(branch-&gt;notTaken());
</del><ins>+                branch-&gt;convertToJump(branch-&gt;notTaken().block());
</ins><span class="cx">                 m_changedCFG = true;
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="lines">@@ -562,7 +592,7 @@
</span><span class="cx">             // Into this: Jump(then)
</span><span class="cx">             if (triState == TrueTriState) {
</span><span class="cx">                 branch-&gt;notTaken().block()-&gt;removePredecessor(m_block);
</span><del>-                branch-&gt;convertToJump(branch-&gt;taken());
</del><ins>+                branch-&gt;convertToJump(branch-&gt;taken().block());
</ins><span class="cx">                 m_changedCFG = true;
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="lines">@@ -631,6 +661,11 @@
</span><span class="cx"> 
</span><span class="cx">     void simplifyCFG()
</span><span class="cx">     {
</span><ins>+        if (verbose) {
+            dataLog(&quot;Before simplifyCFG:\n&quot;);
+            dataLog(m_proc);
+        }
+        
</ins><span class="cx">         // We have three easy simplification rules:
</span><span class="cx">         //
</span><span class="cx">         // 1) If a successor is a block that just jumps to another block, then jump directly to
</span><span class="lines">@@ -651,6 +686,9 @@
</span><span class="cx">         // iterations needed to kill a lot of code.
</span><span class="cx"> 
</span><span class="cx">         for (BasicBlock* block : m_proc) {
</span><ins>+            if (verbose)
+                dataLog(&quot;Considering block &quot;, *block, &quot;:\n&quot;);
+
</ins><span class="cx">             checkPredecessorValidity();
</span><span class="cx"> 
</span><span class="cx">             // We don't care about blocks that don't have successors.
</span><span class="lines">@@ -664,7 +702,15 @@
</span><span class="cx">                     &amp;&amp; successor-&gt;last()-&gt;opcode() == Jump) {
</span><span class="cx">                     BasicBlock* newSuccessor = successor-&gt;successorBlock(0);
</span><span class="cx">                     if (newSuccessor != successor) {
</span><del>-                        newSuccessor-&gt;replacePredecessor(successor, block);
</del><ins>+                        if (verbose) {
+                            dataLog(
+                                &quot;Replacing &quot;, pointerDump(block), &quot;-&gt;&quot;, pointerDump(successor),
+                                &quot; with &quot;, pointerDump(block), &quot;-&gt;&quot;, pointerDump(newSuccessor),
+                                &quot;\n&quot;);
+                        }
+                        // Note that we do not do replacePredecessor() because the block we're
+                        // skipping will still have newSuccessor as its successor.
+                        newSuccessor-&gt;addPredecessor(block);
</ins><span class="cx">                         successor = newSuccessor;
</span><span class="cx">                         m_changedCFG = true;
</span><span class="cx">                     }
</span><span class="lines">@@ -679,14 +725,18 @@
</span><span class="cx">                 if (!effects.mustExecute()) {
</span><span class="cx">                     // All of the successors must be the same.
</span><span class="cx">                     bool allSame = true;
</span><del>-                    FrequentedBlock firstSuccessor = block-&gt;successor(0);
</del><ins>+                    BasicBlock* firstSuccessor = block-&gt;successorBlock(0);
</ins><span class="cx">                     for (unsigned i = 1; i &lt; block-&gt;numSuccessors(); ++i) {
</span><del>-                        if (block-&gt;successorBlock(i) != firstSuccessor.block()) {
</del><ins>+                        if (block-&gt;successorBlock(i) != firstSuccessor) {
</ins><span class="cx">                             allSame = false;
</span><span class="cx">                             break;
</span><span class="cx">                         }
</span><span class="cx">                     }
</span><span class="cx">                     if (allSame) {
</span><ins>+                        if (verbose) {
+                            dataLog(
+                                &quot;Changing &quot;, pointerDump(block), &quot;'s terminal to a Jump.\n&quot;);
+                        }
</ins><span class="cx">                         block-&gt;last()-&gt;as&lt;ControlValue&gt;()-&gt;convertToJump(firstSuccessor);
</span><span class="cx">                         m_changedCFG = true;
</span><span class="cx">                     }
</span><span class="lines">@@ -719,6 +769,12 @@
</span><span class="cx">                     // Ensure that predecessors of block's new successors know what's up.
</span><span class="cx">                     for (BasicBlock* newSuccessor : block-&gt;successorBlocks())
</span><span class="cx">                         newSuccessor-&gt;replacePredecessor(successor, block);
</span><ins>+
+                    if (verbose) {
+                        dataLog(
+                            &quot;Merged &quot;, pointerDump(block), &quot;-&gt;&quot;, pointerDump(successor), &quot;\n&quot;);
+                    }
+                    
</ins><span class="cx">                     m_changedCFG = true;
</span><span class="cx">                 }
</span><span class="cx">             }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Validatecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Validate.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Validate.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -80,8 +80,10 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         for (Value* value : valueInProc) {
</span><del>-            for (Value* child : value-&gt;children())
</del><ins>+            for (Value* child : value-&gt;children()) {
+                VALIDATE(child, (&quot;At &quot;, *value));
</ins><span class="cx">                 VALIDATE(valueInProc.contains(child), (&quot;At &quot;, *value, &quot;-&gt;&quot;, pointerDump(child)));
</span><ins>+            }
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         HashMap&lt;BasicBlock*, HashSet&lt;BasicBlock*&gt;&gt; allPredecessors;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Value.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -124,92 +124,97 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Value::addConstant(Procedure&amp;, Value*) const
</del><ins>+Value* Value::addConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Value::subConstant(Procedure&amp;, Value*) const
</del><ins>+Value* Value::subConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Value::bitAndConstant(Procedure&amp;, Value*) const
</del><ins>+Value* Value::divConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Value::bitOrConstant(Procedure&amp;, Value*) const
</del><ins>+Value* Value::bitAndConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Value::bitXorConstant(Procedure&amp;, Value*) const
</del><ins>+Value* Value::bitOrConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Value::shlConstant(Procedure&amp;, Value*) const
</del><ins>+Value* Value::bitXorConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Value::sShrConstant(Procedure&amp;, Value*) const
</del><ins>+Value* Value::shlConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Value* Value::zShrConstant(Procedure&amp;, Value*) const
</del><ins>+Value* Value::sShrConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::equalConstant(Value*) const
</del><ins>+Value* Value::zShrConstant(Procedure&amp;, const Value*) const
</ins><span class="cx"> {
</span><ins>+    return nullptr;
+}
+
+TriState Value::equalConstant(const Value*) const
+{
</ins><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::notEqualConstant(Value*) const
</del><ins>+TriState Value::notEqualConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::lessThanConstant(Value*) const
</del><ins>+TriState Value::lessThanConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::greaterThanConstant(Value*) const
</del><ins>+TriState Value::greaterThanConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::lessEqualConstant(Value*) const
</del><ins>+TriState Value::lessEqualConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::greaterEqualConstant(Value*) const
</del><ins>+TriState Value::greaterEqualConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::aboveConstant(Value*) const
</del><ins>+TriState Value::aboveConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::belowConstant(Value*) const
</del><ins>+TriState Value::belowConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::aboveEqualConstant(Value*) const
</del><ins>+TriState Value::aboveEqualConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-TriState Value::belowEqualConstant(Value*) const
</del><ins>+TriState Value::belowEqualConstant(const Value*) const
</ins><span class="cx"> {
</span><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Valueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Value.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Value.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/B3Value.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -111,25 +111,26 @@
</span><span class="cx">     
</span><span class="cx">     virtual Value* negConstant(Procedure&amp;) const;
</span><span class="cx">     virtual Value* addConstant(Procedure&amp;, int32_t other) const;
</span><del>-    virtual Value* addConstant(Procedure&amp;, Value* other) const;
-    virtual Value* subConstant(Procedure&amp;, Value* other) const;
-    virtual Value* bitAndConstant(Procedure&amp;, Value* other) const;
-    virtual Value* bitOrConstant(Procedure&amp;, Value* other) const;
-    virtual Value* bitXorConstant(Procedure&amp;, Value* other) const;
-    virtual Value* shlConstant(Procedure&amp;, Value* other) const;
-    virtual Value* sShrConstant(Procedure&amp;, Value* other) const;
-    virtual Value* zShrConstant(Procedure&amp;, Value* other) const;
</del><ins>+    virtual Value* addConstant(Procedure&amp;, const Value* other) const;
+    virtual Value* subConstant(Procedure&amp;, const Value* other) const;
+    virtual Value* divConstant(Procedure&amp;, const Value* other) const; // This chooses ChillDiv semantics for integers.
+    virtual Value* bitAndConstant(Procedure&amp;, const Value* other) const;
+    virtual Value* bitOrConstant(Procedure&amp;, const Value* other) const;
+    virtual Value* bitXorConstant(Procedure&amp;, const Value* other) const;
+    virtual Value* shlConstant(Procedure&amp;, const Value* other) const;
+    virtual Value* sShrConstant(Procedure&amp;, const Value* other) const;
+    virtual Value* zShrConstant(Procedure&amp;, const Value* other) const;
</ins><span class="cx">     
</span><del>-    virtual TriState equalConstant(Value* other) const;
-    virtual TriState notEqualConstant(Value* other) const;
-    virtual TriState lessThanConstant(Value* other) const;
-    virtual TriState greaterThanConstant(Value* other) const;
-    virtual TriState lessEqualConstant(Value* other) const;
-    virtual TriState greaterEqualConstant(Value* other) const;
-    virtual TriState aboveConstant(Value* other) const;
-    virtual TriState belowConstant(Value* other) const;
-    virtual TriState aboveEqualConstant(Value* other) const;
-    virtual TriState belowEqualConstant(Value* other) const;
</del><ins>+    virtual TriState equalConstant(const Value* other) const;
+    virtual TriState notEqualConstant(const Value* other) const;
+    virtual TriState lessThanConstant(const Value* other) const;
+    virtual TriState greaterThanConstant(const Value* other) const;
+    virtual TriState lessEqualConstant(const Value* other) const;
+    virtual TriState greaterEqualConstant(const Value* other) const;
+    virtual TriState aboveConstant(const Value* other) const;
+    virtual TriState belowConstant(const Value* other) const;
+    virtual TriState aboveEqualConstant(const Value* other) const;
+    virtual TriState belowEqualConstant(const Value* other) const;
</ins><span class="cx"> 
</span><span class="cx">     // If the value is a comparison then this returns the inverted form of that comparison, if
</span><span class="cx">     // possible. It can be impossible for double comparisons, where for example LessThan and
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirGeneratecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/air/AirGenerate.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -121,6 +121,7 @@
</span><span class="cx"> 
</span><span class="cx">     for (BasicBlock* block : code) {
</span><span class="cx">         blockJumps[block].link(&amp;jit);
</span><ins>+        blockLabels[block] = jit.label();
</ins><span class="cx">         ASSERT(block-&gt;size() &gt;= 1);
</span><span class="cx">         for (unsigned i = 0; i &lt; block-&gt;size() - 1; ++i) {
</span><span class="cx">             CCallHelpers::Jump jump = block-&gt;at(i).generate(jit, context);
</span><span class="lines">@@ -140,8 +141,6 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         CCallHelpers::Jump jump = block-&gt;last().generate(jit, context);
</span><del>-        for (Inst&amp; inst : *block)
-            jump = inst.generate(jit, context);
</del><span class="cx">         switch (block-&gt;numSuccessors()) {
</span><span class="cx">         case 0:
</span><span class="cx">             ASSERT(!jump.isSet());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirInstInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/air/AirInstInlines.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -135,6 +135,36 @@
</span><span class="cx">     return isShiftValid(inst);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool isX86DivHelperValid(const Inst&amp; inst)
+{
+#if CPU(X86) || CPU(X86_64)
+    return inst.args[0] == Tmp(X86Registers::eax)
+        &amp;&amp; inst.args[1] == Tmp(X86Registers::edx);
+#else
+    return false;
+#endif
+}
+
+inline bool isX86ConvertToDoubleWord32Valid(const Inst&amp; inst)
+{
+    return isX86DivHelperValid(inst);
+}
+
+inline bool isX86ConvertToQuadWord64Valid(const Inst&amp; inst)
+{
+    return isX86DivHelperValid(inst);
+}
+
+inline bool isX86Div32Valid(const Inst&amp; inst)
+{
+    return isX86DivHelperValid(inst);
+}
+
+inline bool isX86Div64Valid(const Inst&amp; inst)
+{
+    return isX86DivHelperValid(inst);
+}
+
</ins><span class="cx"> } } } // namespace JSC::B3::Air
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(B3_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirOpcodeopcodes"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/air/AirOpcode.opcodes        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -96,6 +96,22 @@
</span><span class="cx"> Neg64 UD:G
</span><span class="cx">     Tmp
</span><span class="cx"> 
</span><ins>+Mul32 U:G, UD:G
+    Tmp, Tmp
+    Addr, Tmp
+
+X86ConvertToDoubleWord32 U:G, D:G
+    Tmp*, Tmp*
+
+X86ConvertToQuadWord64 U:G, D:G
+    Tmp*, Tmp*
+
+X86Div32 UD:G, UD:G, U:G
+    Tmp*, Tmp*, Tmp
+
+X86Div64 UD:G, UD:G, U:G
+    Tmp*, Tmp*, Tmp
+
</ins><span class="cx"> Lea UA:G, D:G
</span><span class="cx">     Addr, Tmp
</span><span class="cx"> 
</span><span class="lines">@@ -157,10 +173,6 @@
</span><span class="cx">     Tmp, Addr
</span><span class="cx">     Imm, Tmp
</span><span class="cx"> 
</span><del>-Mul32 U:G, UD:G
-    Tmp, Tmp
-    Addr, Tmp
-
</del><span class="cx"> # Note that Move operates over the full register size, which is either 32-bit or 64-bit depending on
</span><span class="cx"> # the platform. I'm not entirely sure that this is a good thing; it might be better to just have a
</span><span class="cx"> # Move64 instruction. OTOH, our MacroAssemblers already have this notion of &quot;move()&quot; that basically
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airAirSimplifyCFGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/air/AirSimplifyCFG.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -86,7 +86,9 @@
</span><span class="cx">                                 &quot;Replacing &quot;, pointerDump(block), &quot;-&gt;&quot;, pointerDump(successor),
</span><span class="cx">                                 &quot; with &quot;, pointerDump(block), &quot;-&gt;&quot;, pointerDump(newSuccessor), &quot;\n&quot;);
</span><span class="cx">                         }
</span><del>-                        newSuccessor-&gt;replacePredecessor(successor, block);
</del><ins>+                        // Note that we do not do replacePredecessor() because the block we're
+                        // skipping will still have newSuccessor as its successor.
+                        newSuccessor-&gt;addPredecessor(block);
</ins><span class="cx">                         successor = newSuccessor;
</span><span class="cx">                         changed = true;
</span><span class="cx">                     }
</span><span class="lines">@@ -112,6 +114,7 @@
</span><span class="cx">                             dataLog(&quot;Changing &quot;, pointerDump(block), &quot;'s terminal to a Jump.\n&quot;);
</span><span class="cx">                         block-&gt;last() = Inst(Jump, block-&gt;last().origin);
</span><span class="cx">                         block-&gt;successors().resize(1);
</span><ins>+                        block-&gt;successors()[0].frequency() = FrequencyClass::Normal;
</ins><span class="cx">                         changed = true;
</span><span class="cx">                     }
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -2859,6 +2859,108 @@
</span><span class="cx">     CHECK(compileAndRun&lt;double&gt;(proc) == functionWithHellaDoubleArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void testChillDiv(int num, int den, int res)
+{
+    // Test non-constant.
+    {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+        
+        root-&gt;appendNew&lt;ControlValue&gt;(
+            proc, Return, Origin(),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, ChillDiv, Origin(),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, Trunc, Origin(),
+                    root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0)),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, Trunc, Origin(),
+                    root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR1))));
+
+        CHECK(compileAndRun&lt;int&gt;(proc, num, den) == res);
+    }
+
+    // Test constant.
+    {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+        
+        root-&gt;appendNew&lt;ControlValue&gt;(
+            proc, Return, Origin(),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, ChillDiv, Origin(),
+                root-&gt;appendNew&lt;Const32Value&gt;(proc, Origin(), num),
+                root-&gt;appendNew&lt;Const32Value&gt;(proc, Origin(), den)));
+        
+        CHECK(compileAndRun&lt;int&gt;(proc) == res);
+    }
+}
+
+void testChillDivTwice(int num1, int den1, int num2, int den2, int res)
+{
+    Procedure proc;
+    BasicBlock* root = proc.addBlock();
+
+    root-&gt;appendNew&lt;ControlValue&gt;(
+        proc, Return, Origin(),
+        root-&gt;appendNew&lt;Value&gt;(
+            proc, Add, Origin(),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, ChillDiv, Origin(),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, Trunc, Origin(),
+                    root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0)),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, Trunc, Origin(),
+                    root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR1))),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, ChillDiv, Origin(),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, Trunc, Origin(),
+                    root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR2)),
+                root-&gt;appendNew&lt;Value&gt;(
+                    proc, Trunc, Origin(),
+                    root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR3)))));
+    
+    CHECK(compileAndRun&lt;int&gt;(proc, num1, den1, num2, den2) == res);
+}
+
+void testChillDiv64(int64_t num, int64_t den, int64_t res)
+{
+    if (!is64Bit())
+        return;
+
+    // Test non-constant.
+    {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+        
+        root-&gt;appendNew&lt;ControlValue&gt;(
+            proc, Return, Origin(),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, ChillDiv, Origin(),
+                root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR0),
+                root-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, Origin(), GPRInfo::argumentGPR1)));
+        
+        CHECK(compileAndRun&lt;int64_t&gt;(proc, num, den) == res);
+    }
+
+    // Test constant.
+    {
+        Procedure proc;
+        BasicBlock* root = proc.addBlock();
+        
+        root-&gt;appendNew&lt;ControlValue&gt;(
+            proc, Return, Origin(),
+            root-&gt;appendNew&lt;Value&gt;(
+                proc, ChillDiv, Origin(),
+                root-&gt;appendNew&lt;Const64Value&gt;(proc, Origin(), num),
+                root-&gt;appendNew&lt;Const64Value&gt;(proc, Origin(), den)));
+        
+        CHECK(compileAndRun&lt;int64_t&gt;(proc) == res);
+    }
+}
+
</ins><span class="cx"> #define RUN(test) do {                          \
</span><span class="cx">         if (!shouldRun(#test))                  \
</span><span class="cx">             break;                              \
</span><span class="lines">@@ -3337,6 +3439,26 @@
</span><span class="cx">     RUN(testCallSimpleDouble(1, 2));
</span><span class="cx">     RUN(testCallFunctionWithHellaDoubleArguments());
</span><span class="cx"> 
</span><ins>+    RUN(testChillDiv(4, 2, 2));
+    RUN(testChillDiv(1, 0, 0));
+    RUN(testChillDiv(0, 0, 0));
+    RUN(testChillDiv(1, -1, -1));
+    RUN(testChillDiv(-2147483647 - 1, 0, 0));
+    RUN(testChillDiv(-2147483647 - 1, 1, -2147483647 - 1));
+    RUN(testChillDiv(-2147483647 - 1, -1, -2147483647 - 1));
+    RUN(testChillDiv(-2147483647 - 1, 2, -1073741824));
+    RUN(testChillDiv64(4, 2, 2));
+    RUN(testChillDiv64(1, 0, 0));
+    RUN(testChillDiv64(0, 0, 0));
+    RUN(testChillDiv64(1, -1, -1));
+    RUN(testChillDiv64(-9223372036854775807ll - 1, 0, 0));
+    RUN(testChillDiv64(-9223372036854775807ll - 1, 1, -9223372036854775807ll - 1));
+    RUN(testChillDiv64(-9223372036854775807ll - 1, -1, -9223372036854775807ll - 1));
+    RUN(testChillDiv64(-9223372036854775807ll - 1, 2, -4611686018427387904));
+    RUN(testChillDivTwice(4, 2, 6, 2, 5));
+    RUN(testChillDivTwice(4, 0, 6, 2, 3));
+    RUN(testChillDivTwice(4, 2, 6, 0, 2));
+
</ins><span class="cx">     if (tasks.isEmpty())
</span><span class="cx">         usage();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGBlockInsertionSeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGBlockInsertionSet.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGBlockInsertionSet.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/dfg/DFGBlockInsertionSet.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">     void insert(size_t index, PassRefPtr&lt;BasicBlock&gt;);
</span><span class="cx">     BasicBlock* insert(size_t index, float executionCount);
</span><span class="cx">     BasicBlock* insertBefore(BasicBlock* before, float executionCount);
</span><del>-    
</del><ins>+
</ins><span class="cx">     bool execute();
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -3399,8 +3399,8 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         m_jit.move(op1GPR, eax.gpr());
</span><del>-        m_jit.assembler().cdq();
-        m_jit.assembler().idivl_r(op2GPR);
</del><ins>+        m_jit.x86ConvertToDoubleWord32();
+        m_jit.x86Div32(op2GPR);
</ins><span class="cx">             
</span><span class="cx">         if (op2TempGPR != InvalidGPRReg)
</span><span class="cx">             unlock(op2TempGPR);
</span><span class="lines">@@ -3555,8 +3555,8 @@
</span><span class="cx"> 
</span><span class="cx">                 m_jit.move(op1Gpr, eax.gpr());
</span><span class="cx">                 m_jit.move(TrustedImm32(divisor), scratchGPR);
</span><del>-                m_jit.assembler().cdq();
-                m_jit.assembler().idivl_r(scratchGPR);
</del><ins>+                m_jit.x86ConvertToDoubleWord32();
+                m_jit.x86Div32(scratchGPR);
</ins><span class="cx">                 if (shouldCheckNegativeZero(node-&gt;arithMode())) {
</span><span class="cx">                     JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
</span><span class="cx">                     speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
</span><span class="lines">@@ -3646,8 +3646,8 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         m_jit.move(op1GPR, eax.gpr());
</span><del>-        m_jit.assembler().cdq();
-        m_jit.assembler().idivl_r(op2GPR);
</del><ins>+        m_jit.x86ConvertToDoubleWord32();
+        m_jit.x86Div32(op2GPR);
</ins><span class="cx">             
</span><span class="cx">         if (op2TempGPR != InvalidGPRReg)
</span><span class="cx">             unlock(op2TempGPR);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITArithmeticcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -623,8 +623,8 @@
</span><span class="cx">     Jump denominatorNotNeg1 = branch32(NotEqual, ecx, TrustedImm32(-1));
</span><span class="cx">     addSlowCase(branch32(Equal, regT0, TrustedImm32(-2147483647-1)));
</span><span class="cx">     denominatorNotNeg1.link(this);
</span><del>-    m_assembler.cdq();
-    m_assembler.idivl_r(ecx);
</del><ins>+    x86ConvertToDoubleWord32();
+    x86Div32(ecx);
</ins><span class="cx">     Jump numeratorPositive = branch32(GreaterThanOrEqual, regT4, TrustedImm32(0));
</span><span class="cx">     addSlowCase(branchTest32(Zero, edx));
</span><span class="cx">     numeratorPositive.link(this);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITArithmetic32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -858,8 +858,8 @@
</span><span class="cx">     Jump denominatorNotNeg1 = branch32(NotEqual, regT2, TrustedImm32(-1));
</span><span class="cx">     addSlowCase(branch32(Equal, regT0, TrustedImm32(-2147483647-1)));
</span><span class="cx">     denominatorNotNeg1.link(this);
</span><del>-    m_assembler.cdq();
-    m_assembler.idivl_r(regT2);
</del><ins>+    x86ConvertToDoubleWord32();
+    x86Div32(regT2);
</ins><span class="cx">     Jump numeratorPositive = branch32(GreaterThanOrEqual, regT3, TrustedImm32(0));
</span><span class="cx">     addSlowCase(branchTest32(Zero, regT1));
</span><span class="cx">     numeratorPositive.link(this);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionCompilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -763,8 +763,8 @@
</span><span class="cx">             ASSERT(GPRInfo::regT0 == X86Registers::eax);
</span><span class="cx">             move(GPRInfo::regT1, X86Registers::ecx);
</span><span class="cx">             if (op == WASMOpExpressionI32::SDiv || op == WASMOpExpressionI32::SMod) {
</span><del>-                m_assembler.cdq();
-                m_assembler.idivl_r(X86Registers::ecx);
</del><ins>+                x86ConvertToDoubleWord32();
+                x86Div32(X86Registers::ecx);
</ins><span class="cx">             } else {
</span><span class="cx">                 ASSERT(op == WASMOpExpressionI32::UDiv || op == WASMOpExpressionI32::UMod);
</span><span class="cx">                 xor32(X86Registers::edx, X86Registers::edx);
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/WTF/ChangeLog        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2015-11-10  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        B3 should be able to compile a program with ChillDiv
+        https://bugs.webkit.org/show_bug.cgi?id=151114
+
+        Reviewed by Benjamin Poulain.
+
+        Needed to beef up some compiler algorithms. All of the hardening was about making them
+        work with objects that have move semantics but not copy semantics. This arises in B3
+        basic block insertion sets.
+
+        * wtf/BubbleSort.h:
+        (WTF::bubbleSort):
+        * wtf/Insertion.h:
+        (WTF::Insertion::Insertion):
+        (WTF::Insertion::index):
+        (WTF::Insertion::element):
+        (WTF::Insertion::operator&lt;):
+        (WTF::executeInsertions):
+
</ins><span class="cx"> 2015-11-10  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Use CROSS_PLATFORM_CONTEXT_MENUS
</span></span></pre></div>
<a id="trunkSourceWTFwtfBubbleSorth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/BubbleSort.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/BubbleSort.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/WTF/wtf/BubbleSort.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -89,8 +89,8 @@
</span><span class="cx"> {
</span><span class="cx">     bubbleSort(
</span><span class="cx">         begin, end,
</span><del>-        [] (typename std::iterator_traits&lt;IteratorType&gt;::value_type left,
-            typename std::iterator_traits&lt;IteratorType&gt;::value_type right) -&gt; bool {
</del><ins>+        [] (const typename std::iterator_traits&lt;IteratorType&gt;::value_type&amp; left,
+            const typename std::iterator_traits&lt;IteratorType&gt;::value_type&amp; right) -&gt; bool {
</ins><span class="cx">             return left &lt; right;
</span><span class="cx">         });
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWTFwtfInsertionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Insertion.h (192294 => 192295)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Insertion.h        2015-11-11 06:07:03 UTC (rev 192294)
+++ trunk/Source/WTF/wtf/Insertion.h        2015-11-11 07:21:23 UTC (rev 192295)
</span><span class="lines">@@ -32,15 +32,17 @@
</span><span class="cx"> class Insertion {
</span><span class="cx"> public:
</span><span class="cx">     Insertion() { }
</span><del>-    
-    Insertion(size_t index, T element)
</del><ins>+
+    template&lt;typename U&gt;
+    Insertion(size_t index, U&amp;&amp; element)
</ins><span class="cx">         : m_index(index)
</span><del>-        , m_element(element)
</del><ins>+        , m_element(std::forward&lt;U&gt;(element))
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     size_t index() const { return m_index; }
</span><del>-    T element() const { return m_element; }
</del><ins>+    const T&amp; element() const { return m_element; }
+    T&amp; element() { return m_element; }
</ins><span class="cx">     
</span><span class="cx">     bool operator&lt;(const Insertion&amp; other) const
</span><span class="cx">     {
</span><span class="lines">@@ -66,8 +68,8 @@
</span><span class="cx">         size_t firstIndex = insertions[indexInInsertions].index() + indexInInsertions;
</span><span class="cx">         size_t indexOffset = indexInInsertions + 1;
</span><span class="cx">         for (size_t i = lastIndex; --i &gt; firstIndex;)
</span><del>-            target[i] = target[i - indexOffset];
-        target[firstIndex] = insertions[indexInInsertions].element();
</del><ins>+            target[i] = WTF::move(target[i - indexOffset]);
+        target[firstIndex] = WTF::move(insertions[indexInInsertions].element());
</ins><span class="cx">         lastIndex = firstIndex;
</span><span class="cx">     }
</span><span class="cx">     insertions.resize(0);
</span></span></pre>
</div>
</div>

</body>
</html>