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

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

<h3>Log Message</h3>
<pre>Rationalize DFG DCE handling of nodes that perform checks that propagate through AI
https://bugs.webkit.org/show_bug.cgi?id=144186

Reviewed by Geoffrey Garen.
        
If I do ArithAdd(Int32Use, Int32Use, CheckOverflow) then AI will prove that this returns
Int32. We may later perform code simplifications based on the proof that this is Int32, and
we may kill all DFG users of this ArithAdd. Then we may prove that there is no exit site at
which the ArithAdd is live. This seems like it is sufficient to then kill the ArithAdd,
except that we still need the overflow check!

Previously we mishandled this:

- In places where we want the overflow check we need to use MustGenerate(@ArithAdd) as a hack
  to keep it alive. That's dirty and it's just indicative of a deeper issue.

- Our MovHint removal doesn't do Phantom canonicalization which essentially makes it
  powerless. This was sort of hiding the bug.

- Nodes that have checks that AI leverages should always be NodeMustGenerate. You can't kill
  something that you are relying on for subsequent simplifications.
        
This fixes MovHint removal to also canonicalize Phantoms. This also adds ModeMustGenerate to
nodes that may perform checks that are used by AI to guarantee the result type. As a result,
we no longer need the weird MustGenerate node.

* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGArgumentsEliminationPhase.cpp:
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDCEPhase.cpp:
(JSC::DFG::DCEPhase::run):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::tryToRelaxRepresentation):
* dfg/DFGIntegerCheckCombiningPhase.cpp:
(JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
(JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd): Deleted.
* dfg/DFGMayExit.cpp:
(JSC::DFG::mayExit):
* dfg/DFGNode.h:
(JSC::DFG::Node::willHaveCodeGenOrOSR):
* dfg/DFGNodeType.h:
* dfg/DFGObjectAllocationSinkingPhase.cpp:
(JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
* dfg/DFGPhantomCanonicalizationPhase.cpp:
(JSC::DFG::PhantomCanonicalizationPhase::run):
* dfg/DFGPhantomRemovalPhase.cpp:
(JSC::DFG::PhantomRemovalPhase::run):
* dfg/DFGPlan.cpp:
(JSC::DFG::Plan::compileInThreadImpl):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGTypeCheckHoistingPhase.cpp:
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
* dfg/DFGVarargsForwardingPhase.cpp:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
* tests/stress/fold-based-on-int32-proof-mul-branch.js: Added.
(foo):
* tests/stress/fold-based-on-int32-proof-mul.js: Added.
(foo):
* tests/stress/fold-based-on-int32-proof-or-zero.js: Added.
(foo):
* tests/stress/fold-based-on-int32-proof.js: Added.
(foo):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDCEPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGIntegerCheckCombiningPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGMayExitcpp">trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeh">trunk/Source/JavaScriptCore/dfg/DFGNode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhantomCanonicalizationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPlancpp">trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGVarargsForwardingPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoretestsstressfoldbasedonint32proofmulbranchjs">trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-mul-branch.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfoldbasedonint32proofmuljs">trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-mul.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfoldbasedonint32prooforzerojs">trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-or-zero.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressfoldbasedonint32proofjs">trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -1,3 +1,84 @@
</span><ins>+2015-04-24  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Rationalize DFG DCE handling of nodes that perform checks that propagate through AI
+        https://bugs.webkit.org/show_bug.cgi?id=144186
+
+        Reviewed by Geoffrey Garen.
+        
+        If I do ArithAdd(Int32Use, Int32Use, CheckOverflow) then AI will prove that this returns
+        Int32. We may later perform code simplifications based on the proof that this is Int32, and
+        we may kill all DFG users of this ArithAdd. Then we may prove that there is no exit site at
+        which the ArithAdd is live. This seems like it is sufficient to then kill the ArithAdd,
+        except that we still need the overflow check!
+
+        Previously we mishandled this:
+
+        - In places where we want the overflow check we need to use MustGenerate(@ArithAdd) as a hack
+          to keep it alive. That's dirty and it's just indicative of a deeper issue.
+
+        - Our MovHint removal doesn't do Phantom canonicalization which essentially makes it
+          powerless. This was sort of hiding the bug.
+
+        - Nodes that have checks that AI leverages should always be NodeMustGenerate. You can't kill
+          something that you are relying on for subsequent simplifications.
+        
+        This fixes MovHint removal to also canonicalize Phantoms. This also adds ModeMustGenerate to
+        nodes that may perform checks that are used by AI to guarantee the result type. As a result,
+        we no longer need the weird MustGenerate node.
+
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGArgumentsEliminationPhase.cpp:
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDCEPhase.cpp:
+        (JSC::DFG::DCEPhase::run):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::tryToRelaxRepresentation):
+        * dfg/DFGIntegerCheckCombiningPhase.cpp:
+        (JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
+        (JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd): Deleted.
+        * dfg/DFGMayExit.cpp:
+        (JSC::DFG::mayExit):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::willHaveCodeGenOrOSR):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGObjectAllocationSinkingPhase.cpp:
+        (JSC::DFG::ObjectAllocationSinkingPhase::handleNode):
+        * dfg/DFGPhantomCanonicalizationPhase.cpp:
+        (JSC::DFG::PhantomCanonicalizationPhase::run):
+        * dfg/DFGPhantomRemovalPhase.cpp:
+        (JSC::DFG::PhantomRemovalPhase::run):
+        * dfg/DFGPlan.cpp:
+        (JSC::DFG::Plan::compileInThreadImpl):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGTypeCheckHoistingPhase.cpp:
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
+        (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
+        * dfg/DFGVarargsForwardingPhase.cpp:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        * tests/stress/fold-based-on-int32-proof-mul-branch.js: Added.
+        (foo):
+        * tests/stress/fold-based-on-int32-proof-mul.js: Added.
+        (foo):
+        * tests/stress/fold-based-on-int32-proof-or-zero.js: Added.
+        (foo):
+        * tests/stress/fold-based-on-int32-proof.js: Added.
+        (foo):
+
</ins><span class="cx"> 2015-04-26  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Class body ending with a semicolon throws a SyntaxError
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -2080,7 +2080,6 @@
</span><span class="cx">     case ProfileType:
</span><span class="cx">     case ProfileControlFlow:
</span><span class="cx">     case Phantom:
</span><del>-    case MustGenerate:
</del><span class="cx">     case CountExecution:
</span><span class="cx">     case CheckTierUpInLoop:
</span><span class="cx">     case CheckTierUpAtReturn:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArgumentsEliminationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGArgumentsEliminationPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -161,7 +161,6 @@
</span><span class="cx"> 
</span><span class="cx">                 case Phantom:
</span><span class="cx">                 case Check:
</span><del>-                case MustGenerate:
</del><span class="cx">                 case MovHint:
</span><span class="cx">                 case PutHint:
</span><span class="cx">                     break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -115,7 +115,6 @@
</span><span class="cx">         
</span><span class="cx">     case Identity:
</span><span class="cx">     case Phantom:
</span><del>-    case MustGenerate:
</del><span class="cx">     case Check:
</span><span class="cx">     case ExtractOSREntryLocal:
</span><span class="cx">     case CheckStructureImmediate:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDCEPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGDCEPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -71,7 +71,7 @@
</span><span class="cx">             cleanVariables(m_graph.m_arguments);
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        // Just do a basic MustGenerate/Phantom/Check clean-up.
</del><ins>+        // Just do a basic Phantom/Check clean-up.
</ins><span class="cx">         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
</span><span class="cx">             BasicBlock* block = m_graph.block(blockIndex);
</span><span class="cx">             if (!block)
</span><span class="lines">@@ -82,7 +82,6 @@
</span><span class="cx">                 Node* node = block-&gt;at(sourceIndex++);
</span><span class="cx">                 switch (node-&gt;op()) {
</span><span class="cx">                 case Check:
</span><del>-                case MustGenerate:
</del><span class="cx">                 case Phantom:
</span><span class="cx">                     if (node-&gt;children.isEmpty())
</span><span class="cx">                         continue;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -55,7 +55,6 @@
</span><span class="cx">     case MovHint:
</span><span class="cx">     case ZombieHint:
</span><span class="cx">     case Phantom:
</span><del>-    case MustGenerate:
</del><span class="cx">     case Upsilon:
</span><span class="cx">     case Phi:
</span><span class="cx">     case Flush:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -1033,7 +1033,6 @@
</span><span class="cx">         case ConstantStoragePointer:
</span><span class="cx">         case DoubleAsInt32:
</span><span class="cx">         case ValueToInt32:
</span><del>-        case MustGenerate: // MustGenerate would be trivial to handle but anyway we assert that we won't see it here yet.
</del><span class="cx">         case DoubleRep:
</span><span class="cx">         case ValueRep:
</span><span class="cx">         case Int52Rep:
</span><span class="lines">@@ -2018,7 +2017,6 @@
</span><span class="cx">         case MovHint:
</span><span class="cx">         case Phantom:
</span><span class="cx">         case Check:
</span><del>-        case MustGenerate:
</del><span class="cx">             DFG_NODE_DO_TO_CHILDREN(m_graph, m_currentNode, fixEdgeRepresentation);
</span><span class="cx">             break;
</span><span class="cx">             
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGIntegerCheckCombiningPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGIntegerCheckCombiningPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -236,12 +236,12 @@
</span><span class="cx">                 switch (data.m_key.m_kind) {
</span><span class="cx">                 case Addition: {
</span><span class="cx">                     if (range.m_minBound &lt; 0) {
</span><del>-                        insertMustAdd(
</del><ins>+                        insertAdd(
</ins><span class="cx">                             nodeIndex, NodeOrigin(range.m_minOrigin, node-&gt;origin.forExit),
</span><span class="cx">                             data.m_key.m_source, range.m_minBound);
</span><span class="cx">                     }
</span><span class="cx">                     if (range.m_maxBound &gt; 0) {
</span><del>-                        insertMustAdd(
</del><ins>+                        insertAdd(
</ins><span class="cx">                             nodeIndex, NodeOrigin(range.m_maxOrigin, node-&gt;origin.forExit),
</span><span class="cx">                             data.m_key.m_source, range.m_maxBound);
</span><span class="cx">                     }
</span><span class="lines">@@ -385,15 +385,6 @@
</span><span class="cx">                 nodeIndex, origin, jsNumber(addend), source.useKind()));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    Node* insertMustAdd(
-        unsigned nodeIndex, NodeOrigin origin, Edge source, int32_t addend)
-    {
-        Node* result = insertAdd(nodeIndex, origin, source, addend);
-        m_insertionSet.insertNode(
-            nodeIndex, SpecNone, MustGenerate, origin, result-&gt;defaultEdge());
-        return result;
-    }
-    
</del><span class="cx">     typedef std::unordered_map&lt;RangeKey, Range, HashMethod&lt;RangeKey&gt;&gt; RangeMap;
</span><span class="cx">     RangeMap m_map;
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGMayExitcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -85,7 +85,6 @@
</span><span class="cx">     case Flush:
</span><span class="cx">     case Phantom:
</span><span class="cx">     case Check:
</span><del>-    case MustGenerate:
</del><span class="cx">     case GetLocal:
</span><span class="cx">     case LoopHint:
</span><span class="cx">     case Phi:
</span><span class="lines">@@ -105,6 +104,9 @@
</span><span class="cx">     case Jump:
</span><span class="cx">     case Branch:
</span><span class="cx">     case Unreachable:
</span><ins>+    case DoubleRep:
+    case Int52Rep:
+    case ValueRep:
</ins><span class="cx">         break;
</span><span class="cx">         
</span><span class="cx">     default:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNode.h (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGNode.h        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -1554,7 +1554,6 @@
</span><span class="cx">         case ZombieHint:
</span><span class="cx">             return true;
</span><span class="cx">         case Phantom:
</span><del>-        case MustGenerate:
</del><span class="cx">             return child1().useKindUnchecked() != UntypedUse || child2().useKindUnchecked() != UntypedUse || child3().useKindUnchecked() != UntypedUse;
</span><span class="cx">         default:
</span><span class="cx">             return shouldGenerate();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -71,7 +71,6 @@
</span><span class="cx">     macro(MovHint, NodeMustGenerate) \
</span><span class="cx">     macro(ZombieHint, NodeMustGenerate) \
</span><span class="cx">     macro(Phantom, NodeMustGenerate) \
</span><del>-    macro(MustGenerate, NodeMustGenerate) /* Utility node for making soem not-usually-NodeMustGenerate node become like NodeMustGenerate. */ \
</del><span class="cx">     macro(Check, NodeMustGenerate) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
</span><span class="cx">     macro(Upsilon, NodeRelevantToOSR) \
</span><span class="cx">     macro(Phi, NodeRelevantToOSR) \
</span><span class="lines">@@ -130,16 +129,22 @@
</span><span class="cx">     /* Bogus type asserting node. Useful for testing, disappears during Fixup. */\
</span><span class="cx">     macro(FiatInt52, NodeResultJS) \
</span><span class="cx">     \
</span><del>-    /* Nodes for arithmetic operations. */\
-    macro(ArithAdd, NodeResultNumber) \
</del><ins>+    /* Nodes for arithmetic operations. Note that if they do checks other than just type checks, */\
+    /* then they are MustGenerate. This is probably stricter than it needs to be - for example */\
+    /* they won't do checks if they are speculated double. Also, we could kill these if we do it */\
+    /* before AI starts eliminating downstream operations based on proofs, for example in the */\
+    /* case of &quot;var tmp = a + b; return (tmp | 0) == tmp;&quot;. If a, b are speculated integer then */\
+    /* this is only true if we do the overflow check - hence the need to keep it alive. More */\
+    /* generally, we need to keep alive any operation whose checks cause filtration in AI. */\
+    macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
</ins><span class="cx">     macro(ArithClz32, NodeResultInt32) \
</span><del>-    macro(ArithSub, NodeResultNumber) \
-    macro(ArithNegate, NodeResultNumber) \
-    macro(ArithMul, NodeResultNumber) \
</del><ins>+    macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
</ins><span class="cx">     macro(ArithIMul, NodeResultInt32) \
</span><del>-    macro(ArithDiv, NodeResultNumber) \
-    macro(ArithMod, NodeResultNumber) \
-    macro(ArithAbs, NodeResultNumber) \
</del><ins>+    macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
+    macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
</ins><span class="cx">     macro(ArithMin, NodeResultNumber) \
</span><span class="cx">     macro(ArithMax, NodeResultNumber) \
</span><span class="cx">     macro(ArithFRound, NodeResultNumber) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGObjectAllocationSinkingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -797,7 +797,6 @@
</span><span class="cx">         case MovHint:
</span><span class="cx">         case Phantom:
</span><span class="cx">         case Check:
</span><del>-        case MustGenerate:
</del><span class="cx">         case StoreBarrier:
</span><span class="cx">         case StoreBarrierWithNullCheck:
</span><span class="cx">         case PutHint:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhantomCanonicalizationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhantomCanonicalizationPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -38,7 +38,6 @@
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><span class="cx"> static const NodeFlags NodeNeedsPhantom = NodeMiscFlag1;
</span><del>-static const NodeFlags NodeNeedsMustGenerate = NodeMiscFlag2;
</del><span class="cx"> 
</span><span class="cx"> class PhantomCanonicalizationPhase : public Phase {
</span><span class="cx"> public:
</span><span class="lines">@@ -51,7 +50,7 @@
</span><span class="cx">     {
</span><span class="cx">         ASSERT(m_graph.m_form == SSA);
</span><span class="cx">         
</span><del>-        m_graph.clearFlagsOnAllNodes(NodeNeedsPhantom | NodeNeedsMustGenerate | NodeRelevantToOSR);
</del><ins>+        m_graph.clearFlagsOnAllNodes(NodeNeedsPhantom | NodeRelevantToOSR);
</ins><span class="cx">         m_graph.mergeRelevantToOSR();
</span><span class="cx">         
</span><span class="cx">         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
</span><span class="lines">@@ -63,13 +62,11 @@
</span><span class="cx">             unsigned targetIndex = 0;
</span><span class="cx">             while (sourceIndex &lt; block-&gt;size()) {
</span><span class="cx">                 Node* node = block-&gt;at(sourceIndex++);
</span><del>-                if (node-&gt;op() == MustGenerate || node-&gt;op() == Phantom || node-&gt;op() == Check) {
</del><ins>+                if (node-&gt;op() == Phantom || node-&gt;op() == Check) {
</ins><span class="cx">                     for (unsigned i = 0; i &lt; AdjacencyList::Size; ++i) {
</span><span class="cx">                         Edge edge = node-&gt;children.child(i);
</span><span class="cx">                         if (!edge)
</span><span class="cx">                             break;
</span><del>-                        if (node-&gt;op() == MustGenerate)
-                            edge-&gt;mergeFlags(NodeNeedsMustGenerate);
</del><span class="cx">                         if ((edge-&gt;flags() &amp; NodeRelevantToOSR) &amp;&amp; node-&gt;op() == Phantom) {
</span><span class="cx">                             // A Phantom on a node that is RelevantToOSR means that we need to keep
</span><span class="cx">                             // a Phantom on this node instead of just having a Check.
</span><span class="lines">@@ -101,11 +98,8 @@
</span><span class="cx">             
</span><span class="cx">             for (unsigned nodeIndex = 0; nodeIndex &lt; block-&gt;size(); ++nodeIndex) {
</span><span class="cx">                 Node* node = block-&gt;at(nodeIndex);
</span><del>-                if (node-&gt;flags() &amp; NodeNeedsMustGenerate) {
</del><ins>+                if (node-&gt;flags() &amp; NodeNeedsPhantom) {
</ins><span class="cx">                     insertionSet.insertNode(
</span><del>-                        nodeIndex + 1, SpecNone, MustGenerate, node-&gt;origin, node-&gt;defaultEdge());
-                } else if (node-&gt;flags() &amp; NodeNeedsPhantom) {
-                    insertionSet.insertNode(
</del><span class="cx">                         nodeIndex + 1, SpecNone, Phantom, node-&gt;origin, node-&gt;defaultEdge());
</span><span class="cx">                 }
</span><span class="cx">             }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPhantomRemovalPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGPhantomRemovalPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -147,14 +147,6 @@
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><span class="cx">                     
</span><del>-                case MustGenerate: {
-                    if (node-&gt;children.isEmpty()) {
-                        m_graph.m_allocator.free(node);
-                        continue;
-                    }
-                    break;
-                }
-                    
</del><span class="cx">                 default:
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGPlan.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -395,8 +395,10 @@
</span><span class="cx">         performCFA(dfg);
</span><span class="cx">         if (Options::validateFTLOSRExitLiveness())
</span><span class="cx">             performResurrectionForValidation(dfg);
</span><del>-        if (Options::enableMovHintRemoval())
</del><ins>+        if (Options::enableMovHintRemoval()) {
</ins><span class="cx">             performMovHintRemoval(dfg);
</span><ins>+            performPhantomCanonicalization(dfg);
+        }
</ins><span class="cx">         performDCE(dfg); // We rely on this to kill dead code that won't be recognized as dead by LLVM.
</span><span class="cx">         performStackLayout(dfg);
</span><span class="cx">         performLivenessAnalysis(dfg);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -535,7 +535,6 @@
</span><span class="cx">         case InvalidationPoint:
</span><span class="cx">         case CheckInBounds:
</span><span class="cx">         case ValueToInt32:
</span><del>-        case MustGenerate:
</del><span class="cx">         case DoubleRep:
</span><span class="cx">         case ValueRep:
</span><span class="cx">         case Int52Rep:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -125,7 +125,6 @@
</span><span class="cx">     case MovHint:
</span><span class="cx">     case ZombieHint:
</span><span class="cx">     case Phantom:
</span><del>-    case MustGenerate:
</del><span class="cx">     case Upsilon:
</span><span class="cx">     case Phi:
</span><span class="cx">     case Flush:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -4621,7 +4621,6 @@
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case Phantom:
</span><del>-    case MustGenerate:
</del><span class="cx">     case Check:
</span><span class="cx">         DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
</span><span class="cx">         noResult(node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -4338,7 +4338,6 @@
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case Phantom:
</span><del>-    case MustGenerate:
</del><span class="cx">     case Check:
</span><span class="cx">         DFG_NODE_DO_TO_CHILDREN(m_jit.graph(), node, speculate);
</span><span class="cx">         noResult(node);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGTypeCheckHoistingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGTypeCheckHoistingPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -244,7 +244,6 @@
</span><span class="cx">                 case GetIndexedPropertyStorage:
</span><span class="cx">                 case GetTypedArrayByteOffset:
</span><span class="cx">                 case Phantom:
</span><del>-                case MustGenerate:
</del><span class="cx">                 case MovHint:
</span><span class="cx">                 case MultiGetByOffset:
</span><span class="cx">                 case MultiPutByOffset:
</span><span class="lines">@@ -337,7 +336,6 @@
</span><span class="cx">                 case GetArrayLength:
</span><span class="cx">                 case GetIndexedPropertyStorage:
</span><span class="cx">                 case Phantom:
</span><del>-                case MustGenerate:
</del><span class="cx">                 case MovHint:
</span><span class="cx">                 case MultiGetByOffset:
</span><span class="cx">                 case MultiPutByOffset:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGVarargsForwardingPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/dfg/DFGVarargsForwardingPhase.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -92,7 +92,6 @@
</span><span class="cx">             switch (node-&gt;op()) {
</span><span class="cx">             case Phantom:
</span><span class="cx">             case Check:
</span><del>-            case MustGenerate:
</del><span class="cx">             case MovHint:
</span><span class="cx">             case PutHint:
</span><span class="cx">             case LoadVarargs:
</span><span class="lines">@@ -214,7 +213,6 @@
</span><span class="cx">             switch (node-&gt;op()) {
</span><span class="cx">             case Phantom:
</span><span class="cx">             case Check:
</span><del>-            case MustGenerate:
</del><span class="cx">             case MovHint:
</span><span class="cx">             case PutHint:
</span><span class="cx">                 // We don't need to change anything with these.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -52,7 +52,6 @@
</span><span class="cx">     case MovHint:
</span><span class="cx">     case ZombieHint:
</span><span class="cx">     case Phantom:
</span><del>-    case MustGenerate:
</del><span class="cx">     case Flush:
</span><span class="cx">     case PhantomLocal:
</span><span class="cx">     case SetArgument:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (183400 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-04-27 18:19:37 UTC (rev 183400)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -464,7 +464,6 @@
</span><span class="cx">             compilePutStack();
</span><span class="cx">             break;
</span><span class="cx">         case Phantom:
</span><del>-        case MustGenerate:
</del><span class="cx">         case Check:
</span><span class="cx">             compilePhantom();
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfoldbasedonint32proofmulbranchjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-mul-branch.js (0 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-mul-branch.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-mul-branch.js        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+function foo(a, b) {
+    var value = DFGTrue() ? -0 : &quot;foo&quot;;
+    if (a * b == value)
+        return [DFGTrue(), true];
+    return [DFGTrue(), false];
+}
+noInline(foo);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var result = foo(1, 1);
+    if (result[1] !== false)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo(-1, 0);
+if (result[1] !== true &amp;&amp; result[0])
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfoldbasedonint32proofmuljs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-mul.js (0 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-mul.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-mul.js        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+function foo(a, b) {
+    return a * b === -0;
+}
+noInline(foo);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var result = foo(1, 1);
+    if (result !== false)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo(-1, 0);
+if (result !== true)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfoldbasedonint32prooforzerojs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-or-zero.js (0 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-or-zero.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof-or-zero.js        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function foo(a, b) {
+    var c = a + b;
+    return (c | 0) == c;
+}
+noInline(foo);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var result = foo(1, 1);
+    if (result !== true)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo(1073741824, 1073741824);
+if (result !== false)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressfoldbasedonint32proofjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof.js (0 => 183401)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/fold-based-on-int32-proof.js        2015-04-27 18:31:26 UTC (rev 183401)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+function foo(a, b) {
+    return a + b === 2147483648;
+}
+noInline(foo);
+
+for (var i = 0; i &lt; 10000; ++i) {
+    var result = foo(1, 1);
+    if (result !== false)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo(1073741824, 1073741824);
+if (result !== true)
+    throw &quot;Error: bad result at end: &quot; + result;
</ins></span></pre>
</div>
</div>

</body>
</html>