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