Unreviewed, rolling out r145299.
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGPredictionPropagationPhase.cpp
1 /*
2  * Copyright (C) 2011, 2012, 2013 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 "Operations.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 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
50         m_count = 0;
51 #endif
52         // 1) propagate predictions
53
54         do {
55             m_changed = false;
56             
57             // Forward propagation is near-optimal for both topologically-sorted and
58             // DFS-sorted code.
59             propagateForward();
60             if (!m_changed)
61                 break;
62             
63             // Backward propagation reduces the likelihood that pathological code will
64             // cause slowness. Loops (especially nested ones) resemble backward flow.
65             // This pass captures two cases: (1) it detects if the forward fixpoint
66             // found a sound solution and (2) short-circuits backward flow.
67             m_changed = false;
68             propagateBackward();
69         } while (m_changed);
70         
71         // 2) repropagate predictions while doing double voting.
72
73         do {
74             m_changed = false;
75             doRoundOfDoubleVoting();
76             propagateForward();
77             if (!m_changed)
78                 break;
79             
80             m_changed = false;
81             doRoundOfDoubleVoting();
82             propagateBackward();
83         } while (m_changed);
84         
85         return true;
86     }
87     
88 private:
89     bool setPrediction(SpeculatedType prediction)
90     {
91         ASSERT(m_currentNode->hasResult());
92         
93         // setPrediction() is used when we know that there is no way that we can change
94         // our minds about what the prediction is going to be. There is no semantic
95         // difference between setPrediction() and mergeSpeculation() other than the
96         // increased checking to validate this property.
97         ASSERT(m_currentNode->prediction() == SpecNone || m_currentNode->prediction() == prediction);
98         
99         return m_currentNode->predict(prediction);
100     }
101     
102     bool mergePrediction(SpeculatedType prediction)
103     {
104         ASSERT(m_currentNode->hasResult());
105         
106         return m_currentNode->predict(prediction);
107     }
108     
109     bool isNotNegZero(Node* node)
110     {
111         if (!m_graph.isNumberConstant(node))
112             return false;
113         double value = m_graph.valueOfNumberConstant(node);
114         return !value && 1.0 / value < 0.0;
115     }
116     
117     bool isNotZero(Node* node)
118     {
119         if (!m_graph.isNumberConstant(node))
120             return false;
121         return !!m_graph.valueOfNumberConstant(node);
122     }
123     
124     bool isWithinPowerOfTwoForConstant(Node* node, int power)
125     {
126         JSValue immediateValue = node->valueOfJSConstant(codeBlock());
127         if (!immediateValue.isInt32())
128             return false;
129         int32_t intImmediate = immediateValue.asInt32();
130         return intImmediate > -(1 << power) && intImmediate < (1 << power);
131     }
132     
133     bool isWithinPowerOfTwoNonRecursive(Node* node, int power)
134     {
135         if (node->op() != JSConstant)
136             return false;
137         return isWithinPowerOfTwoForConstant(node, power);
138     }
139     
140     bool isWithinPowerOfTwo(Node* node, int power)
141     {
142         switch (node->op()) {
143         case JSConstant: {
144             return isWithinPowerOfTwoForConstant(node, power);
145         }
146             
147         case BitAnd: {
148             return isWithinPowerOfTwoNonRecursive(node->child1().node(), power)
149                 || isWithinPowerOfTwoNonRecursive(node->child2().node(), power);
150         }
151             
152         case BitRShift:
153         case BitURShift: {
154             Node* shiftAmount = node->child2().node();
155             if (shiftAmount->op() != JSConstant)
156                 return false;
157             JSValue immediateValue = shiftAmount->valueOfJSConstant(codeBlock());
158             if (!immediateValue.isInt32())
159                 return false;
160             return immediateValue > 32 - power;
161         }
162             
163         default:
164             return false;
165         }
166     }
167
168     SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
169     {
170         if (!isNumberSpeculation(value))
171             return SpecDouble;
172         if (value & SpecDoubleNaN)
173             return SpecDouble;
174         return SpecDoubleReal;
175     }
176
177     SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right)
178     {
179         return speculatedDoubleTypeForPrediction(mergeSpeculations(left, right));
180     }
181
182     void propagate(Node* node)
183     {
184         NodeType op = node->op();
185         NodeFlags flags = node->flags() & NodeBackPropMask;
186
187 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
188         dataLog("   ", Graph::opName(op), " ", m_currentNode, ": ", nodeFlagsAsString(flags), " ");
189 #endif
190         
191         bool changed = false;
192         
193         switch (op) {
194         case JSConstant:
195         case WeakJSConstant: {
196             changed |= setPrediction(speculationFromValue(m_graph.valueOfJSConstant(node)));
197             break;
198         }
199             
200         case GetLocal: {
201             VariableAccessData* variableAccessData = node->variableAccessData();
202             SpeculatedType prediction = variableAccessData->prediction();
203             if (prediction)
204                 changed |= mergePrediction(prediction);
205             
206             // Assume conservatively that a SetLocal implies that the value may flow through a loop,
207             // and so we would have overflow leading to the program "observing" numbers even if all
208             // users of the value are doing toInt32. It might be worthwhile to revisit this at some
209             // point and actually check if the data flow involves loops, but right now I don't think
210             // we have evidence that this would be beneficial for benchmarks.
211             
212             changed |= variableAccessData->mergeFlags((flags & ~NodeUsedAsIntLocally) | NodeUsedAsNumber);
213             break;
214         }
215             
216         case SetLocal: {
217             VariableAccessData* variableAccessData = node->variableAccessData();
218             changed |= variableAccessData->predict(node->child1()->prediction());
219
220             changed |= node->child1()->mergeFlags(variableAccessData->flags());
221             break;
222         }
223             
224         case Flush: {
225             // Make sure that the analysis knows that flushed locals escape.
226             VariableAccessData* variableAccessData = node->variableAccessData();
227             changed |= variableAccessData->mergeFlags(NodeUsedAsValue);
228             break;
229         }
230             
231         case BitAnd:
232         case BitOr:
233         case BitXor:
234         case BitRShift:
235         case BitLShift:
236         case BitURShift: {
237             changed |= setPrediction(SpecInt32);
238             flags |= NodeUsedAsInt | NodeUsedAsIntLocally;
239             flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
240             changed |= node->child1()->mergeFlags(flags);
241             changed |= node->child2()->mergeFlags(flags);
242             break;
243         }
244             
245         case ValueToInt32: {
246             changed |= setPrediction(SpecInt32);
247             flags |= NodeUsedAsInt | NodeUsedAsIntLocally;
248             flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
249             changed |= node->child1()->mergeFlags(flags);
250             break;
251         }
252             
253         case ArrayPop: {
254             changed |= mergePrediction(node->getHeapPrediction());
255             changed |= mergeDefaultFlags(node);
256             break;
257         }
258
259         case ArrayPush: {
260             changed |= mergePrediction(node->getHeapPrediction());
261             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
262             changed |= node->child2()->mergeFlags(NodeUsedAsValue);
263             break;
264         }
265
266         case RegExpExec:
267         case RegExpTest: {
268             changed |= mergePrediction(node->getHeapPrediction());
269             changed |= mergeDefaultFlags(node);
270             break;
271         }
272
273         case StringCharCodeAt: {
274             changed |= mergePrediction(SpecInt32);
275             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
276             changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
277             break;
278         }
279
280         case UInt32ToNumber: {
281             if (nodeCanSpeculateInteger(node->arithNodeFlags()))
282                 changed |= mergePrediction(SpecInt32);
283             else
284                 changed |= mergePrediction(SpecNumber);
285             
286             changed |= node->child1()->mergeFlags(flags);
287             break;
288         }
289
290         case ValueAdd: {
291             SpeculatedType left = node->child1()->prediction();
292             SpeculatedType right = node->child2()->prediction();
293             
294             AddSpeculationMode mode = DontSpeculateInteger;
295             
296             if (left && right) {
297                 if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) {
298                     if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
299                         changed |= mergePrediction(SpecInt32);
300                     else
301                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
302                 } else if (!(left & SpecNumber) || !(right & SpecNumber)) {
303                     // left or right is definitely something other than a number.
304                     changed |= mergePrediction(SpecString);
305                 } else
306                     changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble);
307             }
308             
309             if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
310                 flags &= ~NodeNeedsNegZero;
311             if (node->child1()->hasNumberResult() || node->child2()->hasNumberResult())
312                 flags &= ~NodeUsedAsOther;
313             
314             if (mode != SpeculateInteger)
315                 flags |= NodeUsedAsNumber;
316             
317             changed |= node->child1()->mergeFlags(flags);
318             changed |= node->child2()->mergeFlags(flags);
319             break;
320         }
321             
322         case ArithAdd: {
323             SpeculatedType left = node->child1()->prediction();
324             SpeculatedType right = node->child2()->prediction();
325             
326             AddSpeculationMode mode = DontSpeculateInteger;
327             
328             if (left && right) {
329                 if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
330                     changed |= mergePrediction(SpecInt32);
331                 else
332                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
333             }
334             
335             if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
336                 flags &= ~NodeNeedsNegZero;
337             flags &= ~NodeUsedAsOther;
338             
339             if (mode != SpeculateInteger)
340                 flags |= NodeUsedAsNumber;
341             
342             changed |= node->child1()->mergeFlags(flags);
343             changed |= node->child2()->mergeFlags(flags);
344             break;
345         }
346             
347         case ArithSub: {
348             SpeculatedType left = node->child1()->prediction();
349             SpeculatedType right = node->child2()->prediction();
350             
351             AddSpeculationMode mode = DontSpeculateInteger;
352             
353             if (left && right) {
354                 if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
355                     changed |= mergePrediction(SpecInt32);
356                 else
357                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
358             }
359
360             if (isNotZero(node->child1().node()) || isNotZero(node->child2().node()))
361                 flags &= ~NodeNeedsNegZero;
362             flags &= ~NodeUsedAsOther;
363             
364             if (mode != SpeculateInteger)
365                 flags |= NodeUsedAsNumber;
366             
367             changed |= node->child1()->mergeFlags(flags);
368             changed |= node->child2()->mergeFlags(flags);
369             break;
370         }
371             
372         case ArithNegate:
373             if (node->child1()->prediction()) {
374                 if (m_graph.negateShouldSpeculateInteger(node))
375                     changed |= mergePrediction(SpecInt32);
376                 else
377                     changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
378             }
379
380             flags &= ~NodeUsedAsOther;
381
382             changed |= node->child1()->mergeFlags(flags);
383             break;
384             
385         case ArithMin:
386         case ArithMax: {
387             SpeculatedType left = node->child1()->prediction();
388             SpeculatedType right = node->child2()->prediction();
389             
390             if (left && right) {
391                 if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
392                     && nodeCanSpeculateInteger(node->arithNodeFlags()))
393                     changed |= mergePrediction(SpecInt32);
394                 else
395                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
396             }
397
398             flags |= NodeUsedAsNumber;
399             flags &= ~NodeUsedAsOther;
400
401             changed |= node->child1()->mergeFlags(flags);
402             changed |= node->child2()->mergeFlags(flags);
403             break;
404         }
405
406         case ArithMul: {
407             SpeculatedType left = node->child1()->prediction();
408             SpeculatedType right = node->child2()->prediction();
409             
410             if (left && right) {
411                 if (m_graph.mulShouldSpeculateInteger(node))
412                     changed |= mergePrediction(SpecInt32);
413                 else
414                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
415             }
416
417             // As soon as a multiply happens, we can easily end up in the part
418             // of the double domain where the point at which you do truncation
419             // can change the outcome. So, ArithMul always forces its inputs to
420             // check for overflow. Additionally, it will have to check for overflow
421             // itself unless we can prove that there is no way for the values
422             // produced to cause double rounding.
423             
424             if (!isWithinPowerOfTwo(node->child1().node(), 22)
425                 && !isWithinPowerOfTwo(node->child2().node(), 22))
426                 flags |= NodeUsedAsNumber;
427             
428             changed |= node->mergeFlags(flags);
429             
430             flags |= NodeUsedAsNumber | NodeNeedsNegZero;
431             flags &= ~NodeUsedAsOther;
432
433             changed |= node->child1()->mergeFlags(flags);
434             changed |= node->child2()->mergeFlags(flags);
435             break;
436         }
437             
438         case ArithDiv: {
439             SpeculatedType left = node->child1()->prediction();
440             SpeculatedType right = node->child2()->prediction();
441             
442             if (left && right) {
443                 if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
444                     && nodeCanSpeculateInteger(node->arithNodeFlags()))
445                     changed |= mergePrediction(SpecInt32);
446                 else
447                     changed |= mergePrediction(SpecDouble);
448             }
449
450             // As soon as a multiply happens, we can easily end up in the part
451             // of the double domain where the point at which you do truncation
452             // can change the outcome. So, ArithDiv always checks for overflow
453             // no matter what, and always forces its inputs to check as well.
454             
455             flags |= NodeUsedAsNumber | NodeNeedsNegZero;
456             flags &= ~NodeUsedAsOther;
457
458             changed |= node->child1()->mergeFlags(flags);
459             changed |= node->child2()->mergeFlags(flags);
460             break;
461         }
462             
463         case ArithMod: {
464             SpeculatedType left = node->child1()->prediction();
465             SpeculatedType right = node->child2()->prediction();
466             
467             if (left && right) {
468                 if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
469                     && nodeCanSpeculateInteger(node->arithNodeFlags()))
470                     changed |= mergePrediction(SpecInt32);
471                 else
472                     changed |= mergePrediction(SpecDouble);
473             }
474             
475             flags |= NodeUsedAsNumber | NodeNeedsNegZero;
476             flags &= ~NodeUsedAsOther;
477
478             changed |= node->child1()->mergeFlags(flags);
479             changed |= node->child2()->mergeFlags(flags);
480             break;
481         }
482             
483         case ArithSqrt: {
484             changed |= setPrediction(SpecDouble);
485             flags |= NodeUsedAsNumber | NodeNeedsNegZero;
486             flags &= ~NodeUsedAsOther;
487             changed |= node->child1()->mergeFlags(flags);
488             break;
489         }
490             
491         case ArithAbs: {
492             SpeculatedType child = node->child1()->prediction();
493             if (isInt32SpeculationForArithmetic(child)
494                 && nodeCanSpeculateInteger(node->arithNodeFlags()))
495                 changed |= mergePrediction(SpecInt32);
496             else
497                 changed |= mergePrediction(speculatedDoubleTypeForPrediction(child));
498
499             changed |= node->child1()->mergeFlags(flags);
500             break;
501         }
502             
503         case LogicalNot:
504         case CompareLess:
505         case CompareLessEq:
506         case CompareGreater:
507         case CompareGreaterEq:
508         case CompareEq:
509         case CompareEqConstant:
510         case CompareStrictEq:
511         case CompareStrictEqConstant:
512         case InstanceOf:
513         case IsUndefined:
514         case IsBoolean:
515         case IsNumber:
516         case IsString:
517         case IsObject:
518         case IsFunction: {
519             changed |= setPrediction(SpecBoolean);
520             changed |= mergeDefaultFlags(node);
521             break;
522         }
523
524         case TypeOf: {
525             changed |= setPrediction(SpecString);
526             changed |= mergeDefaultFlags(node);
527             break;
528         }
529
530         case GetById: {
531             changed |= mergePrediction(node->getHeapPrediction());
532             changed |= mergeDefaultFlags(node);
533             break;
534         }
535             
536         case GetByIdFlush:
537             changed |= mergePrediction(node->getHeapPrediction());
538             changed |= mergeDefaultFlags(node);
539             break;
540             
541         case GetByVal: {
542             if (node->child1()->shouldSpeculateFloat32Array()
543                 || node->child1()->shouldSpeculateFloat64Array())
544                 changed |= mergePrediction(SpecDouble);
545             else
546                 changed |= mergePrediction(node->getHeapPrediction());
547
548             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
549             changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
550             break;
551         }
552             
553         case GetMyArgumentByValSafe: {
554             changed |= mergePrediction(node->getHeapPrediction());
555             changed |= node->child1()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
556             break;
557         }
558             
559         case GetMyArgumentsLengthSafe: {
560             changed |= setPrediction(SpecInt32);
561             break;
562         }
563
564         case GetScopeRegisters:            
565         case GetButterfly: 
566         case GetIndexedPropertyStorage:
567         case AllocatePropertyStorage:
568         case ReallocatePropertyStorage: {
569             changed |= setPrediction(SpecOther);
570             changed |= mergeDefaultFlags(node);
571             break;
572         }
573
574         case GetByOffset: {
575             changed |= mergePrediction(node->getHeapPrediction());
576             changed |= mergeDefaultFlags(node);
577             break;
578         }
579             
580         case Call:
581         case Construct: {
582             changed |= mergePrediction(node->getHeapPrediction());
583             for (unsigned childIdx = node->firstChild();
584                 childIdx < node->firstChild() + node->numChildren();
585                 ++childIdx)
586                 changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue);
587             break;
588         }
589             
590         case ConvertThis: {
591             SpeculatedType prediction = node->child1()->prediction();
592             if (prediction) {
593                 if (prediction & ~SpecObject) {
594                     prediction &= SpecObject;
595                     prediction = mergeSpeculations(prediction, SpecObjectOther);
596                 }
597                 changed |= mergePrediction(prediction);
598             }
599             changed |= mergeDefaultFlags(node);
600             break;
601         }
602             
603         case GetGlobalVar: {
604             changed |= mergePrediction(node->getHeapPrediction());
605             break;
606         }
607             
608         case PutGlobalVar:
609         case PutGlobalVarCheck: {
610             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
611             break;
612         }
613             
614         case GetScopedVar:
615         case Resolve:
616         case ResolveBase:
617         case ResolveBaseStrictPut:
618         case ResolveGlobal: {
619             SpeculatedType prediction = node->getHeapPrediction();
620             changed |= mergePrediction(prediction);
621             break;
622         }
623             
624         case GetMyScope:
625         case SkipTopScope:
626         case SkipScope: {
627             changed |= setPrediction(SpecCellOther);
628             break;
629         }
630             
631         case GetCallee: {
632             changed |= setPrediction(SpecFunction);
633             break;
634         }
635             
636         case CreateThis:
637         case NewObject: {
638             changed |= setPrediction(SpecFinalObject);
639             changed |= mergeDefaultFlags(node);
640             break;
641         }
642             
643         case NewArray: {
644             changed |= setPrediction(SpecArray);
645             for (unsigned childIdx = node->firstChild();
646                 childIdx < node->firstChild() + node->numChildren();
647                 ++childIdx)
648                 changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue);
649             break;
650         }
651             
652         case NewArrayWithSize: {
653             changed |= setPrediction(SpecArray);
654             changed |= node->child1()->mergeFlags(NodeUsedAsValue | NodeUsedAsInt | NodeUsedAsIntLocally);
655             break;
656         }
657             
658         case NewArrayBuffer: {
659             changed |= setPrediction(SpecArray);
660             break;
661         }
662             
663         case NewRegexp: {
664             changed |= setPrediction(SpecObjectOther);
665             break;
666         }
667         
668         case StringCharAt: {
669             changed |= setPrediction(SpecString);
670             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
671             changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
672             break;
673         }
674             
675         case StrCat: {
676             changed |= setPrediction(SpecString);
677             for (unsigned childIdx = node->firstChild();
678                 childIdx < node->firstChild() + node->numChildren();
679                 ++childIdx)
680                 changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther);
681             break;
682         }
683             
684         case ToPrimitive: {
685             SpeculatedType child = node->child1()->prediction();
686             if (child) {
687                 if (isObjectSpeculation(child)) {
688                     // I'd love to fold this case into the case below, but I can't, because
689                     // removing SpecObject from something that only has an object
690                     // prediction and nothing else means we have an ill-formed SpeculatedType
691                     // (strong predict-none). This should be killed once we remove all traces
692                     // of static (aka weak) predictions.
693                     changed |= mergePrediction(SpecString);
694                 } else if (child & SpecObject) {
695                     // Objects get turned into strings. So if the input has hints of objectness,
696                     // the output will have hinsts of stringiness.
697                     changed |= mergePrediction(
698                         mergeSpeculations(child & ~SpecObject, SpecString));
699                 } else
700                     changed |= mergePrediction(child);
701             }
702             changed |= node->child1()->mergeFlags(flags);
703             break;
704         }
705             
706         case CreateActivation: {
707             changed |= setPrediction(SpecObjectOther);
708             break;
709         }
710             
711         case CreateArguments: {
712             changed |= setPrediction(SpecArguments);
713             break;
714         }
715             
716         case NewFunction:
717         case NewFunctionNoCheck:
718         case NewFunctionExpression: {
719             changed |= setPrediction(SpecFunction);
720             break;
721         }
722             
723         case PutByValAlias:
724         case GetArrayLength:
725         case Int32ToDouble:
726         case ForwardInt32ToDouble:
727         case DoubleAsInt32:
728         case GetLocalUnlinked:
729         case GetMyArgumentsLength:
730         case GetMyArgumentByVal:
731         case PhantomPutStructure:
732         case PhantomArguments:
733         case CheckArray:
734         case Arrayify:
735         case ArrayifyToStructure:
736         case Identity:
737         case MovHint:
738         case MovHintAndCheck:
739         case ZombieHint: {
740             // This node should never be visible at this stage of compilation. It is
741             // inserted by fixup(), which follows this phase.
742             CRASH();
743             break;
744         }
745         
746         case PutByVal:
747             changed |= m_graph.varArgChild(node, 0)->mergeFlags(NodeUsedAsValue);
748             changed |= m_graph.varArgChild(node, 1)->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
749             changed |= m_graph.varArgChild(node, 2)->mergeFlags(NodeUsedAsValue);
750             break;
751
752         case PutScopedVar:
753             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
754             changed |= node->child3()->mergeFlags(NodeUsedAsValue);
755             break;
756             
757         case Return:
758         case Throw:
759             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
760             break;
761
762         case PutById:
763         case PutByIdDirect:
764             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
765             changed |= node->child2()->mergeFlags(NodeUsedAsValue);
766             break;
767
768         case PutByOffset:
769             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
770             changed |= node->child3()->mergeFlags(NodeUsedAsValue);
771             break;
772             
773         case Phi:
774             // Phis should not be visible here since we're iterating the all-but-Phi's
775             // part of basic blocks.
776             CRASH();
777             break;
778
779         case SetCallee:
780         case SetMyScope:
781             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
782             break;
783             
784         case GetScope:
785             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
786             changed |= setPrediction(SpecCellOther);
787             break;
788
789 #ifndef NDEBUG
790         // These get ignored because they don't return anything.
791         case DFG::Jump:
792         case Branch:
793         case Breakpoint:
794         case CheckHasInstance:
795         case ThrowReferenceError:
796         case ForceOSRExit:
797         case SetArgument:
798         case CheckStructure:
799         case CheckExecutable:
800         case ForwardCheckStructure:
801         case StructureTransitionWatchpoint:
802         case ForwardStructureTransitionWatchpoint:
803         case CheckFunction:
804         case PutStructure:
805         case TearOffActivation:
806         case TearOffArguments:
807         case CheckArgumentsNotCreated:
808         case GlobalVarWatchpoint:
809         case GarbageValue:
810         case AllocationProfileWatchpoint:
811         case Phantom:
812             changed |= mergeDefaultFlags(node);
813             break;
814             
815         // These gets ignored because it doesn't do anything.
816         case InlineStart:
817         case Nop:
818         case CountExecution:
819         case PhantomLocal:
820             break;
821             
822         case LastNodeType:
823             CRASH();
824             break;
825 #else
826         default:
827             changed |= mergeDefaultFlags(node);
828             break;
829 #endif
830         }
831
832 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
833         dataLog(SpeculationDump(node->prediction()), "\n");
834 #endif
835         
836         m_changed |= changed;
837     }
838         
839     bool mergeDefaultFlags(Node* node)
840     {
841         bool changed = false;
842         if (node->flags() & NodeHasVarArgs) {
843             for (unsigned childIdx = node->firstChild();
844                 childIdx < node->firstChild() + node->numChildren();
845                 childIdx++) {
846                 if (!!m_graph.m_varArgChildren[childIdx])
847                     changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue);
848             }
849         } else {
850             if (!node->child1())
851                 return changed;
852             changed |= node->child1()->mergeFlags(NodeUsedAsValue);
853             if (!node->child2())
854                 return changed;
855             changed |= node->child2()->mergeFlags(NodeUsedAsValue);
856             if (!node->child3())
857                 return changed;
858             changed |= node->child3()->mergeFlags(NodeUsedAsValue);
859         }
860         return changed;
861     }
862     
863     void propagateForward()
864     {
865 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
866         dataLogF("Propagating predictions forward [%u]\n", ++m_count);
867 #endif
868         for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
869             BasicBlock* block = m_graph.m_blocks[blockIndex].get();
870             if (!block)
871                 continue;
872             ASSERT(block->isReachable);
873             for (unsigned i = 0; i < block->size(); ++i) {
874                 m_currentNode = block->at(i);
875                 propagate(m_currentNode);
876             }
877         }
878     }
879     
880     void propagateBackward()
881     {
882 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
883         dataLogF("Propagating predictions backward [%u]\n", ++m_count);
884 #endif
885         for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
886             BasicBlock* block = m_graph.m_blocks[blockIndex].get();
887             if (!block)
888                 continue;
889             ASSERT(block->isReachable);
890             for (unsigned i = block->size(); i--;) {
891                 m_currentNode = block->at(i);
892                 propagate(m_currentNode);
893             }
894         }
895     }
896     
897     void doDoubleVoting(Node* node)
898     {
899         switch (node->op()) {
900         case ValueAdd:
901         case ArithAdd:
902         case ArithSub: {
903             SpeculatedType left = node->child1()->prediction();
904             SpeculatedType right = node->child2()->prediction();
905                 
906             DoubleBallot ballot;
907                 
908             if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)
909                 && !m_graph.addShouldSpeculateInteger(node))
910                 ballot = VoteDouble;
911             else
912                 ballot = VoteValue;
913                 
914             m_graph.voteNode(node->child1(), ballot);
915             m_graph.voteNode(node->child2(), ballot);
916             break;
917         }
918                 
919         case ArithMul: {
920             SpeculatedType left = node->child1()->prediction();
921             SpeculatedType right = node->child2()->prediction();
922                 
923             DoubleBallot ballot;
924                 
925             if (isNumberSpeculation(left) && isNumberSpeculation(right)
926                 && !m_graph.mulShouldSpeculateInteger(node))
927                 ballot = VoteDouble;
928             else
929                 ballot = VoteValue;
930                 
931             m_graph.voteNode(node->child1(), ballot);
932             m_graph.voteNode(node->child2(), ballot);
933             break;
934         }
935
936         case ArithMin:
937         case ArithMax:
938         case ArithMod:
939         case ArithDiv: {
940             SpeculatedType left = node->child1()->prediction();
941             SpeculatedType right = node->child2()->prediction();
942                 
943             DoubleBallot ballot;
944                 
945             if (isNumberSpeculation(left) && isNumberSpeculation(right)
946                 && !(Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInteger()))
947                 ballot = VoteDouble;
948             else
949                 ballot = VoteValue;
950                 
951             m_graph.voteNode(node->child1(), ballot);
952             m_graph.voteNode(node->child2(), ballot);
953             break;
954         }
955                 
956         case ArithAbs:
957             DoubleBallot ballot;
958             if (!(node->child1()->shouldSpeculateIntegerForArithmetic() && node->canSpeculateInteger()))
959                 ballot = VoteDouble;
960             else
961                 ballot = VoteValue;
962                 
963             m_graph.voteNode(node->child1(), ballot);
964             break;
965                 
966         case ArithSqrt:
967             m_graph.voteNode(node->child1(), VoteDouble);
968             break;
969                 
970         case SetLocal: {
971             SpeculatedType prediction = node->child1()->prediction();
972             if (isDoubleSpeculation(prediction))
973                 node->variableAccessData()->vote(VoteDouble);
974             else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction))
975                 node->variableAccessData()->vote(VoteValue);
976             break;
977         }
978                 
979         case PutByVal:
980         case PutByValAlias: {
981             Edge child1 = m_graph.varArgChild(node, 0);
982             Edge child2 = m_graph.varArgChild(node, 1);
983             Edge child3 = m_graph.varArgChild(node, 2);
984             m_graph.voteNode(child1, VoteValue);
985             m_graph.voteNode(child2, VoteValue);
986             switch (node->arrayMode().type()) {
987             case Array::Double:
988                 m_graph.voteNode(child3, VoteDouble);
989                 break;
990             default:
991                 m_graph.voteNode(child3, VoteValue);
992                 break;
993             }
994             break;
995         }
996             
997         default:
998             m_graph.voteChildren(node, VoteValue);
999             break;
1000         }
1001     }
1002     
1003     void doRoundOfDoubleVoting()
1004     {
1005 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1006         dataLogF("Voting on double uses of locals [%u]\n", m_count);
1007 #endif
1008         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
1009             m_graph.m_variableAccessData[i].find()->clearVotes();
1010         for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
1011             BasicBlock* block = m_graph.m_blocks[blockIndex].get();
1012             if (!block)
1013                 continue;
1014             ASSERT(block->isReachable);
1015             for (unsigned i = 0; i < block->size(); ++i) {
1016                 m_currentNode = block->at(i);
1017                 doDoubleVoting(m_currentNode);
1018             }
1019         }
1020         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
1021             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
1022             if (!variableAccessData->isRoot())
1023                 continue;
1024             m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
1025         }
1026         for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
1027             m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
1028         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
1029             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
1030             if (!variableAccessData->isRoot())
1031                 continue;
1032             m_changed |= variableAccessData->makePredictionForDoubleFormat();
1033         }
1034     }
1035     
1036     Node* m_currentNode;
1037     bool m_changed;
1038
1039 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1040     unsigned m_count;
1041 #endif
1042 };
1043     
1044 bool performPredictionPropagation(Graph& graph)
1045 {
1046     SamplingRegion samplingRegion("DFG Prediction Propagation Phase");
1047     return runPhase<PredictionPropagationPhase>(graph);
1048 }
1049
1050 } } // namespace JSC::DFG
1051
1052 #endif // ENABLE(DFG_JIT)
1053