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