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