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