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