cad4c7a7f8cb44de02bfbcd1f2ce393a3482fe19
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGPredictionPropagationPhase.cpp
1 /*
2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #include "config.h"
27 #include "DFGPredictionPropagationPhase.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGGraph.h"
32 #include "DFGPhase.h"
33 #include "Operations.h"
34
35 namespace JSC { namespace DFG {
36
37 SpeculatedType resultOfToPrimitive(SpeculatedType type)
38 {
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);
43     }
44     
45     return type;
46 }
47
48 class PredictionPropagationPhase : public Phase {
49 public:
50     PredictionPropagationPhase(Graph& graph)
51         : Phase(graph, "prediction propagation")
52     {
53     }
54     
55     bool run()
56     {
57         ASSERT(m_graph.m_form == ThreadedCPS);
58         ASSERT(m_graph.m_unificationState == GloballyUnified);
59         
60 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
61         m_count = 0;
62 #endif
63         // 1) propagate predictions
64
65         do {
66             m_changed = false;
67             
68             // Forward propagation is near-optimal for both topologically-sorted and
69             // DFS-sorted code.
70             propagateForward();
71             if (!m_changed)
72                 break;
73             
74             // Backward propagation reduces the likelihood that pathological code will
75             // cause slowness. Loops (especially nested ones) resemble backward flow.
76             // This pass captures two cases: (1) it detects if the forward fixpoint
77             // found a sound solution and (2) short-circuits backward flow.
78             m_changed = false;
79             propagateBackward();
80         } while (m_changed);
81         
82         // 2) repropagate predictions while doing double voting.
83
84         do {
85             m_changed = false;
86             doRoundOfDoubleVoting();
87             if (!m_changed)
88                 break;
89             m_changed = false;
90             propagateForward();
91         } while (m_changed);
92         
93         return true;
94     }
95     
96 private:
97     bool setPrediction(SpeculatedType prediction)
98     {
99         ASSERT(m_currentNode->hasResult());
100         
101         // setPrediction() is used when we know that there is no way that we can change
102         // our minds about what the prediction is going to be. There is no semantic
103         // difference between setPrediction() and mergeSpeculation() other than the
104         // increased checking to validate this property.
105         ASSERT(m_currentNode->prediction() == SpecNone || m_currentNode->prediction() == prediction);
106         
107         return m_currentNode->predict(prediction);
108     }
109     
110     bool mergePrediction(SpeculatedType prediction)
111     {
112         ASSERT(m_currentNode->hasResult());
113         
114         return m_currentNode->predict(prediction);
115     }
116     
117     SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
118     {
119         if (!isNumberSpeculation(value))
120             return SpecDouble;
121         if (value & SpecDoubleNaN)
122             return SpecDouble;
123         return SpecDoubleReal;
124     }
125
126     SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right)
127     {
128         return speculatedDoubleTypeForPrediction(mergeSpeculations(left, right));
129     }
130
131     void propagate(Node* node)
132     {
133         NodeType op = node->op();
134
135 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
136         dataLog("   ", Graph::opName(op), " ", m_currentNode, ": ", NodeFlagsDump(node->flags()), " ");
137 #endif
138         
139         bool changed = false;
140         
141         switch (op) {
142         case JSConstant:
143         case WeakJSConstant: {
144             changed |= setPrediction(speculationFromValue(m_graph.valueOfJSConstant(node)));
145             break;
146         }
147             
148         case GetLocal: {
149             VariableAccessData* variableAccessData = node->variableAccessData();
150             SpeculatedType prediction = variableAccessData->prediction();
151             if (prediction)
152                 changed |= mergePrediction(prediction);
153             break;
154         }
155             
156         case SetLocal: {
157             VariableAccessData* variableAccessData = node->variableAccessData();
158             changed |= variableAccessData->predict(node->child1()->prediction());
159             break;
160         }
161             
162         case BitAnd:
163         case BitOr:
164         case BitXor:
165         case BitRShift:
166         case BitLShift:
167         case BitURShift:
168         case ArithIMul: {
169             changed |= setPrediction(SpecInt32);
170             break;
171         }
172             
173         case ValueToInt32: {
174             changed |= setPrediction(SpecInt32);
175             break;
176         }
177             
178         case ArrayPop:
179         case ArrayPush:
180         case RegExpExec:
181         case RegExpTest:
182         case GetById:
183         case GetByIdFlush:
184         case GetMyArgumentByValSafe:
185         case GetByOffset:
186         case Call:
187         case Construct:
188         case GetGlobalVar:
189         case GetClosureVar: {
190             changed |= setPrediction(node->getHeapPrediction());
191             break;
192         }
193
194         case StringCharCodeAt: {
195             changed |= setPrediction(SpecInt32);
196             break;
197         }
198
199         case UInt32ToNumber: {
200             if (nodeCanSpeculateInteger(node->arithNodeFlags()))
201                 changed |= mergePrediction(SpecInt32);
202             else
203                 changed |= mergePrediction(SpecNumber);
204             break;
205         }
206
207         case ValueAdd: {
208             SpeculatedType left = node->child1()->prediction();
209             SpeculatedType right = node->child2()->prediction();
210             
211             if (left && right) {
212                 if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) {
213                     if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
214                         changed |= mergePrediction(SpecInt32);
215                     else
216                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
217                 } else if (!(left & SpecNumber) || !(right & SpecNumber)) {
218                     // left or right is definitely something other than a number.
219                     changed |= mergePrediction(SpecString);
220                 } else
221                     changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble);
222             }
223             break;
224         }
225             
226         case ArithAdd: {
227             SpeculatedType left = node->child1()->prediction();
228             SpeculatedType right = node->child2()->prediction();
229             
230             if (left && right) {
231                 if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
232                     changed |= mergePrediction(SpecInt32);
233                 else
234                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
235             }
236             break;
237         }
238             
239         case ArithSub: {
240             SpeculatedType left = node->child1()->prediction();
241             SpeculatedType right = node->child2()->prediction();
242             
243             if (left && right) {
244                 if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
245                     changed |= mergePrediction(SpecInt32);
246                 else
247                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
248             }
249             break;
250         }
251             
252         case ArithNegate:
253             if (node->child1()->prediction()) {
254                 if (m_graph.negateShouldSpeculateInteger(node))
255                     changed |= mergePrediction(SpecInt32);
256                 else
257                     changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
258             }
259             break;
260             
261         case ArithMin:
262         case ArithMax: {
263             SpeculatedType left = node->child1()->prediction();
264             SpeculatedType right = node->child2()->prediction();
265             
266             if (left && right) {
267                 if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
268                     && nodeCanSpeculateInteger(node->arithNodeFlags()))
269                     changed |= mergePrediction(SpecInt32);
270                 else
271                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
272             }
273             break;
274         }
275
276         case ArithMul: {
277             SpeculatedType left = node->child1()->prediction();
278             SpeculatedType right = node->child2()->prediction();
279             
280             if (left && right) {
281                 if (m_graph.mulShouldSpeculateInteger(node))
282                     changed |= mergePrediction(SpecInt32);
283                 else
284                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
285             }
286             break;
287         }
288             
289         case ArithDiv: {
290             SpeculatedType left = node->child1()->prediction();
291             SpeculatedType right = node->child2()->prediction();
292             
293             if (left && right) {
294                 if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
295                     && nodeCanSpeculateInteger(node->arithNodeFlags()))
296                     changed |= mergePrediction(SpecInt32);
297                 else
298                     changed |= mergePrediction(SpecDouble);
299             }
300             break;
301         }
302             
303         case ArithMod: {
304             SpeculatedType left = node->child1()->prediction();
305             SpeculatedType right = node->child2()->prediction();
306             
307             if (left && right) {
308                 if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
309                     && nodeCanSpeculateInteger(node->arithNodeFlags()))
310                     changed |= mergePrediction(SpecInt32);
311                 else
312                     changed |= mergePrediction(SpecDouble);
313             }
314             break;
315         }
316             
317         case ArithSqrt: {
318             changed |= setPrediction(SpecDouble);
319             break;
320         }
321             
322         case ArithAbs: {
323             SpeculatedType child = node->child1()->prediction();
324             if (isInt32SpeculationForArithmetic(child)
325                 && nodeCanSpeculateInteger(node->arithNodeFlags()))
326                 changed |= mergePrediction(SpecInt32);
327             else
328                 changed |= mergePrediction(speculatedDoubleTypeForPrediction(child));
329             break;
330         }
331             
332         case LogicalNot:
333         case CompareLess:
334         case CompareLessEq:
335         case CompareGreater:
336         case CompareGreaterEq:
337         case CompareEq:
338         case CompareEqConstant:
339         case CompareStrictEq:
340         case CompareStrictEqConstant:
341         case InstanceOf:
342         case IsUndefined:
343         case IsBoolean:
344         case IsNumber:
345         case IsString:
346         case IsObject:
347         case IsFunction: {
348             changed |= setPrediction(SpecBoolean);
349             break;
350         }
351
352         case TypeOf: {
353             changed |= setPrediction(SpecString);
354             break;
355         }
356
357         case GetByVal: {
358             if (node->child1()->shouldSpeculateFloat32Array()
359                 || node->child1()->shouldSpeculateFloat64Array())
360                 changed |= mergePrediction(SpecDouble);
361             else
362                 changed |= mergePrediction(node->getHeapPrediction());
363             break;
364         }
365             
366         case GetMyArgumentsLengthSafe: {
367             changed |= setPrediction(SpecInt32);
368             break;
369         }
370
371         case GetClosureRegisters:            
372         case GetButterfly: 
373         case GetIndexedPropertyStorage:
374         case AllocatePropertyStorage:
375         case ReallocatePropertyStorage: {
376             changed |= setPrediction(SpecOther);
377             break;
378         }
379
380         case ToThis: {
381             SpeculatedType prediction = node->child1()->prediction();
382             if (prediction) {
383                 if (prediction & ~SpecObject) {
384                     prediction &= SpecObject;
385                     prediction = mergeSpeculations(prediction, SpecObjectOther);
386                 }
387                 changed |= mergePrediction(prediction);
388             }
389             break;
390         }
391             
392         case GetMyScope:
393         case SkipTopScope:
394         case SkipScope: {
395             changed |= setPrediction(SpecObjectOther);
396             break;
397         }
398             
399         case GetCallee: {
400             changed |= setPrediction(SpecFunction);
401             break;
402         }
403             
404         case CreateThis:
405         case NewObject: {
406             changed |= setPrediction(SpecFinalObject);
407             break;
408         }
409             
410         case NewArray:
411         case NewArrayWithSize:
412         case NewArrayBuffer: {
413             changed |= setPrediction(SpecArray);
414             break;
415         }
416             
417         case NewTypedArray: {
418             changed |= setPrediction(speculationFromTypedArrayType(node->typedArrayType()));
419             break;
420         }
421             
422         case NewRegexp:
423         case CreateActivation: {
424             changed |= setPrediction(SpecObjectOther);
425             break;
426         }
427         
428         case StringFromCharCode: {
429             changed |= setPrediction(SpecString);
430             changed |= node->child1()->mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);            
431             break;
432         }
433         case StringCharAt:
434         case ToString:
435         case MakeRope: {
436             changed |= setPrediction(SpecString);
437             break;
438         }
439             
440         case ToPrimitive: {
441             SpeculatedType child = node->child1()->prediction();
442             if (child)
443                 changed |= mergePrediction(resultOfToPrimitive(child));
444             break;
445         }
446             
447         case NewStringObject: {
448             changed |= setPrediction(SpecStringObject);
449             break;
450         }
451             
452         case CreateArguments: {
453             changed |= setPrediction(SpecArguments);
454             break;
455         }
456             
457         case NewFunction: {
458             SpeculatedType child = node->child1()->prediction();
459             if (child & SpecEmpty)
460                 changed |= mergePrediction((child & ~SpecEmpty) | SpecFunction);
461             else
462                 changed |= mergePrediction(child);
463             break;
464         }
465             
466         case NewFunctionNoCheck:
467         case NewFunctionExpression: {
468             changed |= setPrediction(SpecFunction);
469             break;
470         }
471             
472         case PutByValAlias:
473         case GetArrayLength:
474         case GetTypedArrayByteOffset:
475         case Int32ToDouble:
476         case DoubleAsInt32:
477         case GetLocalUnlinked:
478         case GetMyArgumentsLength:
479         case GetMyArgumentByVal:
480         case PhantomPutStructure:
481         case PhantomArguments:
482         case CheckArray:
483         case Arrayify:
484         case ArrayifyToStructure:
485         case MovHint:
486         case MovHintAndCheck:
487         case ZombieHint: {
488             // This node should never be visible at this stage of compilation. It is
489             // inserted by fixup(), which follows this phase.
490             RELEASE_ASSERT_NOT_REACHED();
491             break;
492         }
493         
494         case Phi:
495             // Phis should not be visible here since we're iterating the all-but-Phi's
496             // part of basic blocks.
497             RELEASE_ASSERT_NOT_REACHED();
498             break;
499             
500         case Upsilon:
501         case GetArgument:
502             // These don't get inserted until we go into SSA.
503             RELEASE_ASSERT_NOT_REACHED();
504             break;
505
506         case GetScope:
507             changed |= setPrediction(SpecObjectOther);
508             break;
509             
510         case In:
511             changed |= setPrediction(SpecBoolean);
512             break;
513
514         case Identity:
515             changed |= mergePrediction(node->child1()->prediction());
516             break;
517
518 #ifndef NDEBUG
519         // These get ignored because they don't return anything.
520         case PutByVal:
521         case PutClosureVar:
522         case Return:
523         case Throw:
524         case PutById:
525         case PutByIdDirect:
526         case PutByOffset:
527         case SetCallee:
528         case SetMyScope:
529         case DFG::Jump:
530         case Branch:
531         case Switch:
532         case Breakpoint:
533         case CheckHasInstance:
534         case ThrowReferenceError:
535         case ForceOSRExit:
536         case SetArgument:
537         case CheckStructure:
538         case CheckExecutable:
539         case StructureTransitionWatchpoint:
540         case CheckFunction:
541         case PutStructure:
542         case TearOffActivation:
543         case TearOffArguments:
544         case CheckArgumentsNotCreated:
545         case GlobalVarWatchpoint:
546         case VarInjectionWatchpoint:
547         case AllocationProfileWatchpoint:
548         case Phantom:
549         case PutGlobalVar:
550         case CheckWatchdogTimer:
551         case Unreachable:
552             break;
553             
554         // These gets ignored because it doesn't do anything.
555         case InlineStart:
556         case CountExecution:
557         case PhantomLocal:
558         case Flush:
559             break;
560             
561         case LastNodeType:
562             RELEASE_ASSERT_NOT_REACHED();
563             break;
564 #else
565         default:
566             break;
567 #endif
568         }
569
570 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
571         dataLog(SpeculationDump(node->prediction()), "\n");
572 #endif
573         
574         m_changed |= changed;
575     }
576         
577     void propagateForward()
578     {
579 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
580         dataLogF("Propagating predictions forward [%u]\n", ++m_count);
581 #endif
582         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
583             BasicBlock* block = m_graph.block(blockIndex);
584             if (!block)
585                 continue;
586             ASSERT(block->isReachable);
587             for (unsigned i = 0; i < block->size(); ++i) {
588                 m_currentNode = block->at(i);
589                 propagate(m_currentNode);
590             }
591         }
592     }
593     
594     void propagateBackward()
595     {
596 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
597         dataLogF("Propagating predictions backward [%u]\n", ++m_count);
598 #endif
599         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
600             BasicBlock* block = m_graph.block(blockIndex);
601             if (!block)
602                 continue;
603             ASSERT(block->isReachable);
604             for (unsigned i = block->size(); i--;) {
605                 m_currentNode = block->at(i);
606                 propagate(m_currentNode);
607             }
608         }
609     }
610     
611     void doDoubleVoting(Node* node)
612     {
613         switch (node->op()) {
614         case ValueAdd:
615         case ArithAdd:
616         case ArithSub: {
617             SpeculatedType left = node->child1()->prediction();
618             SpeculatedType right = node->child2()->prediction();
619                 
620             DoubleBallot ballot;
621                 
622             if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)
623                 && !m_graph.addShouldSpeculateInteger(node))
624                 ballot = VoteDouble;
625             else
626                 ballot = VoteValue;
627                 
628             m_graph.voteNode(node->child1(), ballot);
629             m_graph.voteNode(node->child2(), ballot);
630             break;
631         }
632                 
633         case ArithMul: {
634             SpeculatedType left = node->child1()->prediction();
635             SpeculatedType right = node->child2()->prediction();
636                 
637             DoubleBallot ballot;
638                 
639             if (isNumberSpeculation(left) && isNumberSpeculation(right)
640                 && !m_graph.mulShouldSpeculateInteger(node))
641                 ballot = VoteDouble;
642             else
643                 ballot = VoteValue;
644                 
645             m_graph.voteNode(node->child1(), ballot);
646             m_graph.voteNode(node->child2(), ballot);
647             break;
648         }
649
650         case ArithMin:
651         case ArithMax:
652         case ArithMod:
653         case ArithDiv: {
654             SpeculatedType left = node->child1()->prediction();
655             SpeculatedType right = node->child2()->prediction();
656                 
657             DoubleBallot ballot;
658                 
659             if (isNumberSpeculation(left) && isNumberSpeculation(right)
660                 && !(Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInteger()))
661                 ballot = VoteDouble;
662             else
663                 ballot = VoteValue;
664                 
665             m_graph.voteNode(node->child1(), ballot);
666             m_graph.voteNode(node->child2(), ballot);
667             break;
668         }
669                 
670         case ArithAbs:
671             DoubleBallot ballot;
672             if (!(node->child1()->shouldSpeculateIntegerForArithmetic() && node->canSpeculateInteger()))
673                 ballot = VoteDouble;
674             else
675                 ballot = VoteValue;
676                 
677             m_graph.voteNode(node->child1(), ballot);
678             break;
679                 
680         case ArithSqrt:
681             m_graph.voteNode(node->child1(), VoteDouble);
682             break;
683                 
684         case SetLocal: {
685             SpeculatedType prediction = node->child1()->prediction();
686             if (isDoubleSpeculation(prediction))
687                 node->variableAccessData()->vote(VoteDouble);
688             else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction))
689                 node->variableAccessData()->vote(VoteValue);
690             break;
691         }
692                 
693         case PutByVal:
694         case PutByValAlias: {
695             Edge child1 = m_graph.varArgChild(node, 0);
696             Edge child2 = m_graph.varArgChild(node, 1);
697             Edge child3 = m_graph.varArgChild(node, 2);
698             m_graph.voteNode(child1, VoteValue);
699             m_graph.voteNode(child2, VoteValue);
700             switch (node->arrayMode().type()) {
701             case Array::Double:
702                 m_graph.voteNode(child3, VoteDouble);
703                 break;
704             default:
705                 m_graph.voteNode(child3, VoteValue);
706                 break;
707             }
708             break;
709         }
710             
711         default:
712             m_graph.voteChildren(node, VoteValue);
713             break;
714         }
715     }
716     
717     void doRoundOfDoubleVoting()
718     {
719 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
720         dataLogF("Voting on double uses of locals [%u]\n", m_count);
721 #endif
722         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
723             m_graph.m_variableAccessData[i].find()->clearVotes();
724         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
725             BasicBlock* block = m_graph.block(blockIndex);
726             if (!block)
727                 continue;
728             ASSERT(block->isReachable);
729             for (unsigned i = 0; i < block->size(); ++i) {
730                 m_currentNode = block->at(i);
731                 doDoubleVoting(m_currentNode);
732             }
733         }
734         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
735             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
736             if (!variableAccessData->isRoot())
737                 continue;
738             m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
739         }
740         for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
741             m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
742         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
743             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
744             if (!variableAccessData->isRoot())
745                 continue;
746             m_changed |= variableAccessData->makePredictionForDoubleFormat();
747         }
748     }
749     
750     Node* m_currentNode;
751     bool m_changed;
752
753 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
754     unsigned m_count;
755 #endif
756 };
757     
758 bool performPredictionPropagation(Graph& graph)
759 {
760     SamplingRegion samplingRegion("DFG Prediction Propagation Phase");
761     return runPhase<PredictionPropagationPhase>(graph);
762 }
763
764 } } // namespace JSC::DFG
765
766 #endif // ENABLE(DFG_JIT)
767