2  * Copyright (C) 2011-2015 Apple Inc. All rights reserved. 
   4  * Redistribution and use in source and binary forms, with or without 
   5  * modification, are permitted provided that the following conditions 
   7  * 1. Redistributions of source code must retain the above copyright 
   8  *    notice, this list of conditions and the following disclaimer. 
   9  * 2. Redistributions in binary form must reproduce the above copyright 
  10  *    notice, this list of conditions and the following disclaimer in the 
  11  *    documentation and/or other materials provided with the distribution. 
  13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 
  14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR 
  17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
  20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
  21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  27 #include "DFGPredictionPropagationPhase.h" 
  33 #include "JSCInlines.h" 
  35 namespace JSC 
{ namespace DFG 
{ 
  37 SpeculatedType 
resultOfToPrimitive(SpeculatedType type
) 
  39     if (type 
& SpecObject
) { 
  40         // Objects get turned into strings. So if the input has hints of objectness, 
  41         // the output will have hinsts of stringiness. 
  42         return mergeSpeculations(type 
& ~SpecObject
, SpecString
); 
  48 class PredictionPropagationPhase 
: public Phase 
{ 
  50     PredictionPropagationPhase(Graph
& graph
) 
  51         : Phase(graph
, "prediction propagation") 
  57         ASSERT(m_graph
.m_form 
== ThreadedCPS
); 
  58         ASSERT(m_graph
.m_unificationState 
== GloballyUnified
); 
  60         propagateThroughArgumentPositions(); 
  63         propagateToFixpoint(); 
  65         m_pass 
= RareCasePass
; 
  66         propagateToFixpoint(); 
  68         m_pass 
= DoubleVotingPass
; 
  71             doRoundOfDoubleVoting(); 
  82     void propagateToFixpoint() 
  87             // Forward propagation is near-optimal for both topologically-sorted and 
  93             // Backward propagation reduces the likelihood that pathological code will 
  94             // cause slowness. Loops (especially nested ones) resemble backward flow. 
  95             // This pass captures two cases: (1) it detects if the forward fixpoint 
  96             // found a sound solution and (2) short-circuits backward flow. 
 102     bool setPrediction(SpeculatedType prediction
) 
 104         ASSERT(m_currentNode
->hasResult()); 
 106         // setPrediction() is used when we know that there is no way that we can change 
 107         // our minds about what the prediction is going to be. There is no semantic 
 108         // difference between setPrediction() and mergeSpeculation() other than the 
 109         // increased checking to validate this property. 
 110         ASSERT(m_currentNode
->prediction() == SpecNone 
|| m_currentNode
->prediction() == prediction
); 
 112         return m_currentNode
->predict(prediction
); 
 115     bool mergePrediction(SpeculatedType prediction
) 
 117         ASSERT(m_currentNode
->hasResult()); 
 119         return m_currentNode
->predict(prediction
); 
 122     SpeculatedType 
speculatedDoubleTypeForPrediction(SpeculatedType value
) 
 124         SpeculatedType result 
= SpecDoubleReal
; 
 125         if (value 
& SpecDoubleImpureNaN
) 
 126             result 
|= SpecDoubleImpureNaN
; 
 127         if (value 
& SpecDoublePureNaN
) 
 128             result 
|= SpecDoublePureNaN
; 
 129         if (!isFullNumberOrBooleanSpeculation(value
)) 
 130             result 
|= SpecDoublePureNaN
; 
 134     SpeculatedType 
speculatedDoubleTypeForPredictions(SpeculatedType left
, SpeculatedType right
) 
 136         return speculatedDoubleTypeForPrediction(mergeSpeculations(left
, right
)); 
 139     void propagate(Node
* node
) 
 141         NodeType op 
= node
->op(); 
 143         bool changed 
= false; 
 147             SpeculatedType type 
= speculationFromValue(node
->asJSValue()); 
 148             if (type 
== SpecInt52AsDouble 
&& enableInt52()) 
 150             changed 
|= setPrediction(type
); 
 153         case DoubleConstant
: { 
 154             SpeculatedType type 
= speculationFromValue(node
->asJSValue()); 
 155             changed 
|= setPrediction(type
); 
 160             VariableAccessData
* variable 
= node
->variableAccessData(); 
 161             SpeculatedType prediction 
= variable
->prediction(); 
 162             if (!variable
->couldRepresentInt52() && (prediction 
& SpecInt52
)) 
 163                 prediction 
= (prediction 
| SpecInt52AsDouble
) & ~SpecInt52
; 
 165                 changed 
|= mergePrediction(prediction
); 
 170             VariableAccessData
* variableAccessData 
= node
->variableAccessData(); 
 171             changed 
|= variableAccessData
->predict(node
->child1()->prediction()); 
 183             changed 
|= setPrediction(SpecInt32
); 
 194         case MultiGetByOffset
: 
 199         case ConstructVarargs
: 
 200         case CallForwardVarargs
: 
 201         case ConstructForwardVarargs
: 
 203         case NativeConstruct
: 
 206         case GetFromArguments
: { 
 207             changed 
|= setPrediction(node
->getHeapPrediction()); 
 211         case GetGetterSetterByOffset
: 
 212         case GetExecutable
: { 
 213             changed 
|= setPrediction(SpecCellOther
); 
 221             changed 
|= setPrediction(SpecFunction
); 
 225         case GetArgumentCount
: { 
 226             changed 
|= setPrediction(SpecInt32
); 
 230         case StringCharCodeAt
: { 
 231             changed 
|= setPrediction(SpecInt32
); 
 235         case UInt32ToNumber
: { 
 236             // FIXME: Support Int52. 
 237             // https://bugs.webkit.org/show_bug.cgi?id=125704 
 238             if (node
->canSpeculateInt32(m_pass
)) 
 239                 changed 
|= mergePrediction(SpecInt32
); 
 241                 changed 
|= mergePrediction(SpecBytecodeNumber
); 
 246             SpeculatedType left 
= node
->child1()->prediction(); 
 247             SpeculatedType right 
= node
->child2()->prediction(); 
 250                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left
) 
 251                     && isFullNumberOrBooleanSpeculationExpectingDefined(right
)) { 
 252                     if (m_graph
.addSpeculationMode(node
, m_pass
) != DontSpeculateInt32
) 
 253                         changed 
|= mergePrediction(SpecInt32
); 
 254                     else if (m_graph
.addShouldSpeculateMachineInt(node
)) 
 255                         changed 
|= mergePrediction(SpecInt52
); 
 257                         changed 
|= mergePrediction(speculatedDoubleTypeForPredictions(left
, right
)); 
 259                     !(left 
& (SpecFullNumber 
| SpecBoolean
)) 
 260                     || !(right 
& (SpecFullNumber 
| SpecBoolean
))) { 
 261                     // left or right is definitely something other than a number. 
 262                     changed 
|= mergePrediction(SpecString
); 
 264                     changed 
|= mergePrediction(SpecString 
| SpecInt32 
| SpecBytecodeDouble
); 
 271             SpeculatedType left 
= node
->child1()->prediction(); 
 272             SpeculatedType right 
= node
->child2()->prediction(); 
 275                 if (m_graph
.addSpeculationMode(node
, m_pass
) != DontSpeculateInt32
) 
 276                     changed 
|= mergePrediction(SpecInt32
); 
 277                 else if (m_graph
.addShouldSpeculateMachineInt(node
)) 
 278                     changed 
|= mergePrediction(SpecInt52
); 
 280                     changed 
|= mergePrediction(speculatedDoubleTypeForPredictions(left
, right
)); 
 286             if (node
->child1()->prediction()) { 
 287                 if (m_graph
.negateShouldSpeculateInt32(node
, m_pass
)) 
 288                     changed 
|= mergePrediction(SpecInt32
); 
 289                 else if (m_graph
.negateShouldSpeculateMachineInt(node
, m_pass
)) 
 290                     changed 
|= mergePrediction(SpecInt52
); 
 292                     changed 
|= mergePrediction(speculatedDoubleTypeForPrediction(node
->child1()->prediction())); 
 298             SpeculatedType left 
= node
->child1()->prediction(); 
 299             SpeculatedType right 
= node
->child2()->prediction(); 
 302                 if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node
->child1().node(), node
->child2().node()) 
 303                     && node
->canSpeculateInt32(m_pass
)) 
 304                     changed 
|= mergePrediction(SpecInt32
); 
 306                     changed 
|= mergePrediction(speculatedDoubleTypeForPredictions(left
, right
)); 
 312             SpeculatedType left 
= node
->child1()->prediction(); 
 313             SpeculatedType right 
= node
->child2()->prediction(); 
 316                 if (m_graph
.mulShouldSpeculateInt32(node
, m_pass
)) 
 317                     changed 
|= mergePrediction(SpecInt32
); 
 318                 else if (m_graph
.mulShouldSpeculateMachineInt(node
, m_pass
)) 
 319                     changed 
|= mergePrediction(SpecInt52
); 
 321                     changed 
|= mergePrediction(speculatedDoubleTypeForPredictions(left
, right
)); 
 328             SpeculatedType left 
= node
->child1()->prediction(); 
 329             SpeculatedType right 
= node
->child2()->prediction(); 
 332                 if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node
->child1().node(), node
->child2().node()) 
 333                     && node
->canSpeculateInt32(m_pass
)) 
 334                     changed 
|= mergePrediction(SpecInt32
); 
 336                     changed 
|= mergePrediction(SpecBytecodeDouble
); 
 347             changed 
|= setPrediction(SpecBytecodeDouble
); 
 352             if (isInt32OrBooleanSpeculation(node
->getHeapPrediction()) && m_graph
.roundShouldSpeculateInt32(node
, m_pass
)) 
 353                 changed 
|= setPrediction(SpecInt32
); 
 355                 changed 
|= setPrediction(SpecBytecodeDouble
); 
 360             SpeculatedType child 
= node
->child1()->prediction(); 
 361             if (isInt32OrBooleanSpeculationForArithmetic(child
) 
 362                 && node
->canSpeculateInt32(m_pass
)) 
 363                 changed 
|= mergePrediction(SpecInt32
); 
 365                 changed 
|= mergePrediction(speculatedDoubleTypeForPrediction(child
)); 
 373         case CompareGreaterEq
: 
 375         case CompareEqConstant
: 
 376         case CompareStrictEq
: 
 385             changed 
|= setPrediction(SpecBoolean
); 
 390             changed 
|= setPrediction(SpecStringIdent
); 
 395             if (!node
->child1()->prediction()) 
 398             ArrayMode arrayMode 
= node
->arrayMode().refine( 
 400                 node
->child1()->prediction(), 
 401                 node
->child2()->prediction(), 
 404             switch (arrayMode
.type()) { 
 406                 if (arrayMode
.isOutOfBounds()) 
 407                     changed 
|= mergePrediction(node
->getHeapPrediction() | SpecInt32
); 
 409                     changed 
|= mergePrediction(SpecInt32
); 
 412                 if (arrayMode
.isOutOfBounds()) 
 413                     changed 
|= mergePrediction(node
->getHeapPrediction() | SpecDoubleReal
); 
 415                     changed 
|= mergePrediction(SpecDoubleReal
); 
 417             case Array::Float32Array
: 
 418             case Array::Float64Array
: 
 419                 changed 
|= mergePrediction(SpecFullDouble
); 
 421             case Array::Uint32Array
: 
 422                 if (isInt32SpeculationForArithmetic(node
->getHeapPrediction())) 
 423                     changed 
|= mergePrediction(SpecInt32
); 
 424                 else if (enableInt52()) 
 425                     changed 
|= mergePrediction(SpecMachineInt
); 
 427                     changed 
|= mergePrediction(SpecInt32 
| SpecInt52AsDouble
); 
 429             case Array::Int8Array
: 
 430             case Array::Uint8Array
: 
 431             case Array::Int16Array
: 
 432             case Array::Uint16Array
: 
 433             case Array::Int32Array
: 
 434                 changed 
|= mergePrediction(SpecInt32
); 
 437                 changed 
|= mergePrediction(node
->getHeapPrediction()); 
 444         case GetIndexedPropertyStorage
: 
 445         case AllocatePropertyStorage
: 
 446         case ReallocatePropertyStorage
: { 
 447             changed 
|= setPrediction(SpecOther
); 
 452             SpeculatedType prediction 
= node
->child1()->prediction(); 
 454                 if (prediction 
& ~SpecObject
) { 
 455                     prediction 
&= SpecObject
; 
 456                     prediction 
= mergeSpeculations(prediction
, SpecObjectOther
); 
 458                 changed 
|= mergePrediction(prediction
); 
 464             changed 
|= setPrediction(SpecObjectOther
); 
 470             changed 
|= setPrediction(SpecFinalObject
); 
 475         case NewArrayWithSize
: 
 476         case NewArrayBuffer
: { 
 477             changed 
|= setPrediction(SpecArray
); 
 481         case NewTypedArray
: { 
 482             changed 
|= setPrediction(speculationFromTypedArrayType(node
->typedArrayType())); 
 487         case CreateActivation
: { 
 488             changed 
|= setPrediction(SpecObjectOther
); 
 492         case StringFromCharCode
: { 
 493             changed 
|= setPrediction(SpecString
); 
 494             changed 
|= node
->child1()->mergeFlags(NodeBytecodeUsesAsNumber 
| NodeBytecodeUsesAsInt
);             
 498         case CallStringConstructor
: 
 501             changed 
|= setPrediction(SpecString
); 
 506             SpeculatedType child 
= node
->child1()->prediction(); 
 508                 changed 
|= mergePrediction(resultOfToPrimitive(child
)); 
 512         case NewStringObject
: { 
 513             changed 
|= setPrediction(SpecStringObject
); 
 517         case CreateDirectArguments
: { 
 518             changed 
|= setPrediction(SpecDirectArguments
); 
 522         case CreateScopedArguments
: { 
 523             changed 
|= setPrediction(SpecScopedArguments
); 
 527         case CreateClonedArguments
: { 
 528             changed 
|= setPrediction(SpecObjectOther
); 
 533             RELEASE_ASSERT(enableInt52()); 
 534             changed 
|= setPrediction(SpecMachineInt
); 
 540         case GetTypedArrayByteOffset
: 
 542         case GetLocalUnlinked
: 
 545         case ArrayifyToStructure
: 
 546         case CheckTierUpInLoop
: 
 547         case CheckTierUpAtReturn
: 
 548         case CheckTierUpAndOSREnter
: 
 549         case CheckTierUpWithNestedTriggerAndOSREnter
: 
 550         case InvalidationPoint
: 
 558         case BooleanToNumber
: 
 559         case PhantomNewObject
: 
 560         case PhantomNewFunction
: 
 561         case PhantomCreateActivation
: 
 562         case PhantomDirectArguments
: 
 563         case PhantomClonedArguments
: 
 564         case GetMyArgumentByVal
: 
 567         case CheckStructureImmediate
: 
 568         case MaterializeNewObject
: 
 569         case MaterializeCreateActivation
: 
 574             // This node should never be visible at this stage of compilation. It is 
 575             // inserted by fixup(), which follows this phase. 
 576             DFG_CRASH(m_graph
, node
, "Unexpected node during prediction propagation"); 
 581             // Phis should not be visible here since we're iterating the all-but-Phi's 
 582             // part of basic blocks. 
 583             RELEASE_ASSERT_NOT_REACHED(); 
 587             // These don't get inserted until we go into SSA. 
 588             RELEASE_ASSERT_NOT_REACHED(); 
 592             changed 
|= setPrediction(SpecObjectOther
); 
 596             changed 
|= setPrediction(SpecBoolean
); 
 599         case GetEnumerableLength
: { 
 600             changed 
|= setPrediction(SpecInt32
); 
 603         case HasGenericProperty
: 
 604         case HasStructureProperty
: 
 605         case HasIndexedProperty
: { 
 606             changed 
|= setPrediction(SpecBoolean
); 
 609         case GetPropertyEnumerator
: { 
 610             changed 
|= setPrediction(SpecCell
); 
 613         case GetEnumeratorStructurePname
: { 
 614             changed 
|= setPrediction(SpecCell 
| SpecOther
); 
 617         case GetEnumeratorGenericPname
: { 
 618             changed 
|= setPrediction(SpecCell 
| SpecOther
); 
 621         case ToIndexString
: { 
 622             changed 
|= setPrediction(SpecString
); 
 627         // These get ignored because they don't return anything. 
 638         case MultiPutByOffset
: 
 643         case ProfileWillCall
: 
 646         case ProfileControlFlow
: 
 647         case CheckHasInstance
: 
 648         case ThrowReferenceError
: 
 656         case VarInjectionWatchpoint
: 
 660         case CheckWatchdogTimer
: 
 664         case ConstantStoragePointer
: 
 670         // This gets ignored because it only pretends to produce a value. 
 674         // This gets ignored because it already has a prediction. 
 675         case ExtractOSREntryLocal
: 
 678         // These gets ignored because it doesn't do anything. 
 685             RELEASE_ASSERT_NOT_REACHED(); 
 693         m_changed 
|= changed
; 
 696     void propagateForward() 
 698         for (BlockIndex blockIndex 
= 0; blockIndex 
< m_graph
.numBlocks(); ++blockIndex
) { 
 699             BasicBlock
* block 
= m_graph
.block(blockIndex
); 
 702             ASSERT(block
->isReachable
); 
 703             for (unsigned i 
= 0; i 
< block
->size(); ++i
) { 
 704                 m_currentNode 
= block
->at(i
); 
 705                 propagate(m_currentNode
); 
 710     void propagateBackward() 
 712         for (BlockIndex blockIndex 
= m_graph
.numBlocks(); blockIndex
--;) { 
 713             BasicBlock
* block 
= m_graph
.block(blockIndex
); 
 716             ASSERT(block
->isReachable
); 
 717             for (unsigned i 
= block
->size(); i
--;) { 
 718                 m_currentNode 
= block
->at(i
); 
 719                 propagate(m_currentNode
); 
 724     void doDoubleVoting(Node
* node
, float weight
) 
 726         // Loop pre-headers created by OSR entrypoint creation may have NaN weight to indicate 
 727         // that we actually don't know they weight. Assume that they execute once. This turns 
 728         // out to be an OK assumption since the pre-header doesn't have any meaningful code. 
 729         if (weight 
!= weight
) 
 732         switch (node
->op()) { 
 736             SpeculatedType left 
= node
->child1()->prediction(); 
 737             SpeculatedType right 
= node
->child2()->prediction(); 
 741             if (isFullNumberSpeculation(left
) 
 742                 && isFullNumberSpeculation(right
) 
 743                 && !m_graph
.addShouldSpeculateInt32(node
, m_pass
) 
 744                 && !m_graph
.addShouldSpeculateMachineInt(node
)) 
 749             m_graph
.voteNode(node
->child1(), ballot
, weight
); 
 750             m_graph
.voteNode(node
->child2(), ballot
, weight
); 
 755             SpeculatedType left 
= node
->child1()->prediction(); 
 756             SpeculatedType right 
= node
->child2()->prediction(); 
 760             if (isFullNumberSpeculation(left
) 
 761                 && isFullNumberSpeculation(right
) 
 762                 && !m_graph
.mulShouldSpeculateInt32(node
, m_pass
) 
 763                 && !m_graph
.mulShouldSpeculateMachineInt(node
, m_pass
)) 
 768             m_graph
.voteNode(node
->child1(), ballot
, weight
); 
 769             m_graph
.voteNode(node
->child2(), ballot
, weight
); 
 777             SpeculatedType left 
= node
->child1()->prediction(); 
 778             SpeculatedType right 
= node
->child2()->prediction(); 
 782             if (isFullNumberSpeculation(left
) 
 783                 && isFullNumberSpeculation(right
) 
 784                 && !(Node::shouldSpeculateInt32OrBooleanForArithmetic(node
->child1().node(), node
->child2().node()) && node
->canSpeculateInt32(m_pass
))) 
 789             m_graph
.voteNode(node
->child1(), ballot
, weight
); 
 790             m_graph
.voteNode(node
->child2(), ballot
, weight
); 
 796             if (node
->child1()->shouldSpeculateNumber() 
 797                 && !(node
->child1()->shouldSpeculateInt32OrBooleanForArithmetic() && node
->canSpeculateInt32(m_pass
))) 
 802             m_graph
.voteNode(node
->child1(), ballot
, weight
); 
 809             if (node
->child1()->shouldSpeculateNumber()) 
 810                 m_graph
.voteNode(node
->child1(), VoteDouble
, weight
); 
 812                 m_graph
.voteNode(node
->child1(), VoteValue
, weight
); 
 816             SpeculatedType prediction 
= node
->child1()->prediction(); 
 817             if (isDoubleSpeculation(prediction
)) 
 818                 node
->variableAccessData()->vote(VoteDouble
, weight
); 
 820                 !isFullNumberSpeculation(prediction
) 
 821                 || isInt32Speculation(prediction
) || isMachineIntSpeculation(prediction
)) 
 822                 node
->variableAccessData()->vote(VoteValue
, weight
); 
 828         case PutByValAlias
: { 
 829             Edge child1 
= m_graph
.varArgChild(node
, 0); 
 830             Edge child2 
= m_graph
.varArgChild(node
, 1); 
 831             Edge child3 
= m_graph
.varArgChild(node
, 2); 
 832             m_graph
.voteNode(child1
, VoteValue
, weight
); 
 833             m_graph
.voteNode(child2
, VoteValue
, weight
); 
 834             switch (node
->arrayMode().type()) { 
 836                 m_graph
.voteNode(child3
, VoteDouble
, weight
); 
 839                 m_graph
.voteNode(child3
, VoteValue
, weight
); 
 846             // Ignore these since they have no effect on in-DFG execution. 
 850             m_graph
.voteChildren(node
, VoteValue
, weight
); 
 855     void doRoundOfDoubleVoting() 
 857         for (unsigned i 
= 0; i 
< m_graph
.m_variableAccessData
.size(); ++i
) 
 858             m_graph
.m_variableAccessData
[i
].find()->clearVotes(); 
 859         for (BlockIndex blockIndex 
= 0; blockIndex 
< m_graph
.numBlocks(); ++blockIndex
) { 
 860             BasicBlock
* block 
= m_graph
.block(blockIndex
); 
 863             ASSERT(block
->isReachable
); 
 864             for (unsigned i 
= 0; i 
< block
->size(); ++i
) { 
 865                 m_currentNode 
= block
->at(i
); 
 866                 doDoubleVoting(m_currentNode
, block
->executionCount
); 
 869         for (unsigned i 
= 0; i 
< m_graph
.m_variableAccessData
.size(); ++i
) { 
 870             VariableAccessData
* variableAccessData 
= &m_graph
.m_variableAccessData
[i
]; 
 871             if (!variableAccessData
->isRoot()) 
 873             m_changed 
|= variableAccessData
->tallyVotesForShouldUseDoubleFormat(); 
 875         propagateThroughArgumentPositions(); 
 876         for (unsigned i 
= 0; i 
< m_graph
.m_variableAccessData
.size(); ++i
) { 
 877             VariableAccessData
* variableAccessData 
= &m_graph
.m_variableAccessData
[i
]; 
 878             if (!variableAccessData
->isRoot()) 
 880             m_changed 
|= variableAccessData
->makePredictionForDoubleFormat(); 
 884     void propagateThroughArgumentPositions() 
 886         for (unsigned i 
= 0; i 
< m_graph
.m_argumentPositions
.size(); ++i
) 
 887             m_changed 
|= m_graph
.m_argumentPositions
[i
].mergeArgumentPredictionAwareness(); 
 892     PredictionPass m_pass
; // We use different logic for considering predictions depending on how far along we are in propagation. 
 895 bool performPredictionPropagation(Graph
& graph
) 
 897     SamplingRegion 
samplingRegion("DFG Prediction Propagation Phase"); 
 898     return runPhase
<PredictionPropagationPhase
>(graph
); 
 901 } } // namespace JSC::DFG 
 903 #endif // ENABLE(DFG_JIT)