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