[JSC] DFG should respect node's strict flag
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGPredictionPropagationPhase.cpp
1 /*
2  * Copyright (C) 2011-2017 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 namespace {
38
39 bool verboseFixPointLoops = false;
40
41 class PredictionPropagationPhase : public Phase {
42 public:
43     PredictionPropagationPhase(Graph& graph)
44         : Phase(graph, "prediction propagation")
45     {
46     }
47     
48     bool run()
49     {
50         ASSERT(m_graph.m_form == ThreadedCPS);
51         ASSERT(m_graph.m_unificationState == GloballyUnified);
52
53         m_pass = PrimaryPass;
54
55         propagateThroughArgumentPositions();
56
57         processInvariants();
58
59         propagateToFixpoint();
60         
61         m_pass = RareCasePass;
62         propagateToFixpoint();
63         
64         m_pass = DoubleVotingPass;
65         unsigned counter = 0;
66         do {
67             if (verboseFixPointLoops)
68                 ++counter;
69
70             m_changed = false;
71             doRoundOfDoubleVoting();
72             if (!m_changed)
73                 break;
74             m_changed = false;
75             propagateForward();
76         } while (m_changed);
77
78         if (verboseFixPointLoops)
79             dataLog("Iterated ", counter, " times in double voting fixpoint.\n");
80         
81         return true;
82     }
83     
84 private:
85     void propagateToFixpoint()
86     {
87         unsigned counter = 0;
88         do {
89             if (verboseFixPointLoops)
90                 ++counter;
91
92             m_changed = false;
93
94             // Forward propagation is near-optimal for both topologically-sorted and
95             // DFS-sorted code.
96             propagateForward();
97             if (!m_changed)
98                 break;
99             
100             // Backward propagation reduces the likelihood that pathological code will
101             // cause slowness. Loops (especially nested ones) resemble backward flow.
102             // This pass captures two cases: (1) it detects if the forward fixpoint
103             // found a sound solution and (2) short-circuits backward flow.
104             m_changed = false;
105             propagateBackward();
106         } while (m_changed);
107
108         if (verboseFixPointLoops)
109             dataLog("Iterated ", counter, " times in propagateToFixpoint.\n");
110     }
111     
112     bool setPrediction(SpeculatedType prediction)
113     {
114         ASSERT(m_currentNode->hasResult());
115         
116         // setPrediction() is used when we know that there is no way that we can change
117         // our minds about what the prediction is going to be. There is no semantic
118         // difference between setPrediction() and mergeSpeculation() other than the
119         // increased checking to validate this property.
120         ASSERT(m_currentNode->prediction() == SpecNone || m_currentNode->prediction() == prediction);
121         
122         return m_currentNode->predict(prediction);
123     }
124     
125     bool mergePrediction(SpeculatedType prediction)
126     {
127         ASSERT(m_currentNode->hasResult());
128         
129         return m_currentNode->predict(prediction);
130     }
131     
132     SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
133     {
134         SpeculatedType result = SpecDoubleReal;
135         if (value & SpecDoubleImpureNaN)
136             result |= SpecDoubleImpureNaN;
137         if (value & SpecDoublePureNaN)
138             result |= SpecDoublePureNaN;
139         if (!isFullNumberOrBooleanSpeculation(value))
140             result |= SpecDoublePureNaN;
141         return result;
142     }
143
144     SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right)
145     {
146         return speculatedDoubleTypeForPrediction(mergeSpeculations(left, right));
147     }
148
149     void propagate(Node* node)
150     {
151         NodeType op = node->op();
152
153         bool changed = false;
154         
155         switch (op) {
156         case GetLocal: {
157             VariableAccessData* variable = node->variableAccessData();
158             SpeculatedType prediction = variable->prediction();
159             if (!variable->couldRepresentInt52() && (prediction & SpecInt52Only))
160                 prediction = (prediction | SpecAnyIntAsDouble) & ~SpecInt52Only;
161             if (prediction)
162                 changed |= mergePrediction(prediction);
163             break;
164         }
165             
166         case SetLocal: {
167             VariableAccessData* variableAccessData = node->variableAccessData();
168             changed |= variableAccessData->predict(node->child1()->prediction());
169             break;
170         }
171
172         case UInt32ToNumber: {
173             if (node->canSpeculateInt32(m_pass))
174                 changed |= mergePrediction(SpecInt32Only);
175             else if (enableInt52())
176                 changed |= mergePrediction(SpecAnyInt);
177             else
178                 changed |= mergePrediction(SpecBytecodeNumber);
179             break;
180         }
181
182         case ValueAdd: {
183             SpeculatedType left = node->child1()->prediction();
184             SpeculatedType right = node->child2()->prediction();
185             
186             if (left && right) {
187                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
188                     && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
189                     if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
190                         changed |= mergePrediction(SpecInt32Only);
191                     else if (m_graph.addShouldSpeculateAnyInt(node))
192                         changed |= mergePrediction(SpecInt52Only);
193                     else
194                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
195                 } else if (isStringOrStringObjectSpeculation(left) || isStringOrStringObjectSpeculation(right)) {
196                     // left or right is definitely something other than a number.
197                     changed |= mergePrediction(SpecString);
198                 } else if (isBigIntSpeculation(left) && isBigIntSpeculation(right))
199                     changed |= mergePrediction(SpecBigInt);
200                 else {
201                     changed |= mergePrediction(SpecInt32Only);
202                     if (node->mayHaveDoubleResult())
203                         changed |= mergePrediction(SpecBytecodeDouble);
204                     if (node->mayHaveBigIntResult())
205                         changed |= mergePrediction(SpecBigInt);
206                     if (node->mayHaveNonNumericResult())
207                         changed |= mergePrediction(SpecString);
208                 }
209             }
210             break;
211         }
212
213         case ArithAdd: {
214             SpeculatedType left = node->child1()->prediction();
215             SpeculatedType right = node->child2()->prediction();
216             
217             if (left && right) {
218                 if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
219                     changed |= mergePrediction(SpecInt32Only);
220                 else if (m_graph.addShouldSpeculateAnyInt(node))
221                     changed |= mergePrediction(SpecInt52Only);
222                 else if (isFullNumberOrBooleanSpeculation(left) && isFullNumberOrBooleanSpeculation(right))
223                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
224                 else if (node->mayHaveNonIntResult() || (left & SpecBytecodeDouble) || (right & SpecBytecodeDouble))
225                     changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
226                 else
227                     changed |= mergePrediction(SpecInt32Only);
228             }
229             break;
230         }
231             
232         case ArithSub: {
233             SpeculatedType left = node->child1()->prediction();
234             SpeculatedType right = node->child2()->prediction();
235
236             if (left && right) {
237                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
238                     && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
239                     if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
240                         changed |= mergePrediction(SpecInt32Only);
241                     else if (m_graph.addShouldSpeculateAnyInt(node))
242                         changed |= mergePrediction(SpecInt52Only);
243                     else
244                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
245                 } else if (node->mayHaveNonIntResult() || (left & SpecBytecodeDouble) || (right & SpecBytecodeDouble))
246                     changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
247                 else
248                     changed |= mergePrediction(SpecInt32Only);
249             }
250             break;
251         }
252
253         case ValueSub: {
254             SpeculatedType left = node->child1()->prediction();
255             SpeculatedType right = node->child2()->prediction();
256
257             if (left && right) {
258                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
259                     && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
260                     if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
261                         changed |= mergePrediction(SpecInt32Only);
262                     else if (m_graph.addShouldSpeculateAnyInt(node))
263                         changed |= mergePrediction(SpecInt52Only);
264                     else
265                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
266                 } else if (isBigIntSpeculation(left) && isBigIntSpeculation(right))
267                     changed |= mergePrediction(SpecBigInt);
268                 else {
269                     changed |= mergePrediction(SpecInt32Only);
270                     if (node->mayHaveDoubleResult())
271                         changed |= mergePrediction(SpecBytecodeDouble);
272                     if (node->mayHaveBigIntResult())
273                         changed |= mergePrediction(SpecBigInt);
274                 }
275             }
276
277             break;
278         }
279
280         case ValueNegate:
281         case ArithNegate: {
282             SpeculatedType prediction = node->child1()->prediction();
283             if (prediction) {
284                 if (isInt32OrBooleanSpeculation(prediction) && node->canSpeculateInt32(m_pass))
285                     changed |= mergePrediction(SpecInt32Only);
286                 else if (m_graph.unaryArithShouldSpeculateAnyInt(node, m_pass))
287                     changed |= mergePrediction(SpecInt52Only);
288                 else if (isBytecodeNumberSpeculation(prediction))
289                     changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
290                 else {
291                     changed |= mergePrediction(SpecInt32Only);
292                     if (node->op() == ValueNegate && node->mayHaveBigIntResult())
293                         changed |= mergePrediction(SpecBigInt);
294                     if (node->mayHaveDoubleResult())
295                         changed |= mergePrediction(SpecBytecodeDouble);
296                 }
297             }
298             break;
299         }
300         case ArithMin:
301         case ArithMax: {
302             SpeculatedType left = node->child1()->prediction();
303             SpeculatedType right = node->child2()->prediction();
304             
305             if (left && right) {
306                 if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
307                     && node->canSpeculateInt32(m_pass))
308                     changed |= mergePrediction(SpecInt32Only);
309                 else
310                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
311             }
312             break;
313         }
314
315         case ValueMul:
316         case ArithMul: {
317             SpeculatedType left = node->child1()->prediction();
318             SpeculatedType right = node->child2()->prediction();
319             
320             if (left && right) {
321                 // FIXME: We're currently relying on prediction propagation and backwards propagation
322                 // whenever we can, and only falling back on result flags if that fails. And the result
323                 // flags logic doesn't know how to use backwards propagation. We should get rid of the
324                 // prediction propagation logic and rely solely on the result type.
325                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
326                     && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
327                     if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
328                         changed |= mergePrediction(SpecInt32Only);
329                     else if (m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
330                         changed |= mergePrediction(SpecInt52Only);
331                     else
332                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
333                 } else if (op == ValueMul && isBigIntSpeculation(left) && isBigIntSpeculation(right))
334                     changed |= mergePrediction(SpecBigInt);
335                 else {
336                     changed |= mergePrediction(SpecInt32Only);
337                     if (node->mayHaveDoubleResult()
338                         || (left & SpecBytecodeDouble)
339                         || (right & SpecBytecodeDouble))
340                         changed |= mergePrediction(SpecBytecodeDouble);
341                     if ((op == ValueMul && node->mayHaveBigIntResult())
342                         || (left & SpecBigInt)
343                         || (right & SpecBigInt))
344                         changed |= mergePrediction(SpecBigInt);
345                 }
346             }
347             break;
348         }
349
350         case ValueDiv:
351         case ArithDiv:
352         case ArithMod: {
353             SpeculatedType left = node->child1()->prediction();
354             SpeculatedType right = node->child2()->prediction();
355             
356             if (left && right) {
357                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
358                     && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
359                     if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
360                         changed |= mergePrediction(SpecInt32Only);
361                     else
362                         changed |= mergePrediction(SpecBytecodeDouble);
363                 } else if (op == ValueDiv && isBigIntSpeculation(left) && isBigIntSpeculation(right))
364                     changed |= mergePrediction(SpecBigInt);
365                 else {
366                     changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
367                     if (op == ValueDiv && (node->mayHaveBigIntResult()
368                         || (left & SpecBigInt)
369                         || (right & SpecBigInt)))
370                         changed |= mergePrediction(SpecBigInt);
371                 }
372             }
373             break;
374         }
375
376         case ArithAbs: {
377             SpeculatedType childPrediction = node->child1()->prediction();
378             if (isInt32OrBooleanSpeculation(childPrediction)
379                 && node->canSpeculateInt32(m_pass))
380                 changed |= mergePrediction(SpecInt32Only);
381             else
382                 changed |= mergePrediction(SpecBytecodeDouble);
383             break;
384         }
385
386         case GetByVal:
387         case AtomicsAdd:
388         case AtomicsAnd:
389         case AtomicsCompareExchange:
390         case AtomicsExchange:
391         case AtomicsLoad:
392         case AtomicsOr:
393         case AtomicsStore:
394         case AtomicsSub:
395         case AtomicsXor: {
396             Edge child1 = m_graph.child(node, 0);
397             if (!child1->prediction())
398                 break;
399             
400             Edge child2 = m_graph.child(node, 1);
401             ArrayMode arrayMode = node->arrayMode().refine(
402                 m_graph, node,
403                 child1->prediction(),
404                 child2->prediction(),
405                 SpecNone);
406             
407             switch (arrayMode.type()) {
408             case Array::Int32:
409                 if (arrayMode.isOutOfBounds())
410                     changed |= mergePrediction(node->getHeapPrediction() | SpecInt32Only);
411                 else
412                     changed |= mergePrediction(SpecInt32Only);
413                 break;
414             case Array::Double:
415                 if (arrayMode.isOutOfBounds())
416                     changed |= mergePrediction(node->getHeapPrediction() | SpecDoubleReal);
417                 else if (node->getHeapPrediction() & SpecNonIntAsDouble)
418                     changed |= mergePrediction(SpecDoubleReal);
419                 else
420                     changed |= mergePrediction(SpecAnyIntAsDouble);
421                 break;
422             case Array::Float32Array:
423             case Array::Float64Array:
424                 changed |= mergePrediction(SpecFullDouble);
425                 break;
426             case Array::Uint32Array:
427                 if (isInt32SpeculationForArithmetic(node->getHeapPrediction()) && node->op() == GetByVal)
428                     changed |= mergePrediction(SpecInt32Only);
429                 else if (enableInt52())
430                     changed |= mergePrediction(SpecAnyInt);
431                 else
432                     changed |= mergePrediction(SpecInt32Only | SpecAnyIntAsDouble);
433                 break;
434             case Array::Int8Array:
435             case Array::Uint8Array:
436             case Array::Int16Array:
437             case Array::Uint16Array:
438             case Array::Int32Array:
439                 changed |= mergePrediction(SpecInt32Only);
440                 break;
441             default:
442                 changed |= mergePrediction(node->getHeapPrediction());
443                 break;
444             }
445             break;
446         }
447             
448         case ToThis: {
449             // ToThis in methods for primitive types should speculate primitive types in strict mode.
450             bool isStrictMode = m_graph.isStrictModeFor(node->origin.semantic);
451             if (isStrictMode) {
452                 if (node->child1()->shouldSpeculateBoolean()) {
453                     changed |= mergePrediction(SpecBoolean);
454                     break;
455                 }
456
457                 if (node->child1()->shouldSpeculateInt32()) {
458                     changed |= mergePrediction(SpecInt32Only);
459                     break;
460                 }
461
462                 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
463                     changed |= mergePrediction(SpecAnyInt);
464                     break;
465                 }
466
467                 if (node->child1()->shouldSpeculateNumber()) {
468                     changed |= mergePrediction(SpecBytecodeNumber);
469                     break;
470                 }
471
472                 if (node->child1()->shouldSpeculateSymbol()) {
473                     changed |= mergePrediction(SpecSymbol);
474                     break;
475                 }
476                 
477                 if (node->child1()->shouldSpeculateBigInt()) {
478                     changed |= mergePrediction(SpecBigInt);
479                     break;
480                 }
481
482                 if (node->child1()->shouldSpeculateStringIdent()) {
483                     changed |= mergePrediction(SpecStringIdent);
484                     break;
485                 }
486
487                 if (node->child1()->shouldSpeculateString()) {
488                     changed |= mergePrediction(SpecString);
489                     break;
490                 }
491             } else {
492                 if (node->child1()->shouldSpeculateString()) {
493                     changed |= mergePrediction(SpecStringObject);
494                     break;
495                 }
496             }
497
498             SpeculatedType prediction = node->child1()->prediction();
499             if (isStrictMode)
500                 changed |= mergePrediction(node->getHeapPrediction());
501             else if (prediction) {
502                 if (prediction & ~SpecObject) {
503                     // Wrapper objects are created only in sloppy mode.
504                     prediction &= SpecObject;
505                     prediction = mergeSpeculations(prediction, SpecObjectOther);
506                 }
507                 changed |= mergePrediction(prediction);
508             }
509             break;
510         }
511             
512         case ToPrimitive: {
513             SpeculatedType child = node->child1()->prediction();
514             if (child)
515                 changed |= mergePrediction(resultOfToPrimitive(child));
516             break;
517         }
518
519         case NormalizeMapKey: {
520             SpeculatedType prediction = node->child1()->prediction();
521             if (prediction)
522                 changed |= mergePrediction(prediction);
523             break;
524         }
525
526         default:
527             break;
528         }
529
530         m_changed |= changed;
531     }
532         
533     void propagateForward()
534     {
535         for (Node* node : m_dependentNodes) {
536             m_currentNode = node;
537             propagate(m_currentNode);
538         }
539     }
540
541     void propagateBackward()
542     {
543         for (unsigned i = m_dependentNodes.size(); i--;) {
544             m_currentNode = m_dependentNodes[i];
545             propagate(m_currentNode);
546         }
547     }
548     
549     void doDoubleVoting(Node* node, float weight)
550     {
551         // Loop pre-headers created by OSR entrypoint creation may have NaN weight to indicate
552         // that we actually don't know they weight. Assume that they execute once. This turns
553         // out to be an OK assumption since the pre-header doesn't have any meaningful code.
554         if (weight != weight)
555             weight = 1;
556         
557         switch (node->op()) {
558         case ValueAdd:
559         case ValueSub:
560         case ArithAdd:
561         case ArithSub: {
562             SpeculatedType left = node->child1()->prediction();
563             SpeculatedType right = node->child2()->prediction();
564                 
565             DoubleBallot ballot;
566                 
567             if (isFullNumberSpeculation(left)
568                 && isFullNumberSpeculation(right)
569                 && !m_graph.addShouldSpeculateInt32(node, m_pass)
570                 && !m_graph.addShouldSpeculateAnyInt(node))
571                 ballot = VoteDouble;
572             else
573                 ballot = VoteValue;
574                 
575             m_graph.voteNode(node->child1(), ballot, weight);
576             m_graph.voteNode(node->child2(), ballot, weight);
577             break;
578         }
579
580         case ValueMul:
581         case ArithMul: {
582             SpeculatedType left = node->child1()->prediction();
583             SpeculatedType right = node->child2()->prediction();
584                 
585             DoubleBallot ballot;
586                 
587             if (isFullNumberSpeculation(left)
588                 && isFullNumberSpeculation(right)
589                 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass)
590                 && !m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
591                 ballot = VoteDouble;
592             else
593                 ballot = VoteValue;
594                 
595             m_graph.voteNode(node->child1(), ballot, weight);
596             m_graph.voteNode(node->child2(), ballot, weight);
597             break;
598         }
599
600         case ArithMin:
601         case ArithMax:
602         case ArithMod:
603         case ValueDiv:
604         case ArithDiv: {
605             SpeculatedType left = node->child1()->prediction();
606             SpeculatedType right = node->child2()->prediction();
607                 
608             DoubleBallot ballot;
609                 
610             if (isFullNumberSpeculation(left)
611                 && isFullNumberSpeculation(right)
612                 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
613                 ballot = VoteDouble;
614             else
615                 ballot = VoteValue;
616                 
617             m_graph.voteNode(node->child1(), ballot, weight);
618             m_graph.voteNode(node->child2(), ballot, weight);
619             break;
620         }
621
622         case ArithAbs:
623             DoubleBallot ballot;
624             if (node->child1()->shouldSpeculateNumber()
625                 && !m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
626                 ballot = VoteDouble;
627             else
628                 ballot = VoteValue;
629                 
630             m_graph.voteNode(node->child1(), ballot, weight);
631             break;
632                 
633         case ArithSqrt:
634         case ArithUnary:
635             if (node->child1()->shouldSpeculateNumber())
636                 m_graph.voteNode(node->child1(), VoteDouble, weight);
637             else
638                 m_graph.voteNode(node->child1(), VoteValue, weight);
639             break;
640                 
641         case SetLocal: {
642             SpeculatedType prediction = node->child1()->prediction();
643             if (isDoubleSpeculation(prediction))
644                 node->variableAccessData()->vote(VoteDouble, weight);
645             else if (!isFullNumberSpeculation(prediction)
646                 || isInt32Speculation(prediction) || isAnyIntSpeculation(prediction))
647                 node->variableAccessData()->vote(VoteValue, weight);
648             break;
649         }
650
651         case PutByValDirect:
652         case PutByVal:
653         case PutByValAlias: {
654             Edge child1 = m_graph.varArgChild(node, 0);
655             Edge child2 = m_graph.varArgChild(node, 1);
656             Edge child3 = m_graph.varArgChild(node, 2);
657             m_graph.voteNode(child1, VoteValue, weight);
658             m_graph.voteNode(child2, VoteValue, weight);
659             switch (node->arrayMode().type()) {
660             case Array::Double:
661                 m_graph.voteNode(child3, VoteDouble, weight);
662                 break;
663             default:
664                 m_graph.voteNode(child3, VoteValue, weight);
665                 break;
666             }
667             break;
668         }
669         
670         case DataViewSet: {
671             DataViewData data = node->dataViewData();
672             if (data.isFloatingPoint)
673                 m_graph.voteNode(m_graph.varArgChild(node, 2), VoteValue, weight);
674             break;
675         }
676
677         case MovHint:
678             // Ignore these since they have no effect on in-DFG execution.
679             break;
680             
681         default:
682             m_graph.voteChildren(node, VoteValue, weight);
683             break;
684         }
685     }
686     
687     void doRoundOfDoubleVoting()
688     {
689         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
690             m_graph.m_variableAccessData[i].find()->clearVotes();
691         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
692             BasicBlock* block = m_graph.block(blockIndex);
693             if (!block)
694                 continue;
695             ASSERT(block->isReachable);
696             for (unsigned i = 0; i < block->size(); ++i) {
697                 m_currentNode = block->at(i);
698                 doDoubleVoting(m_currentNode, block->executionCount);
699             }
700         }
701         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
702             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
703             if (!variableAccessData->isRoot())
704                 continue;
705             m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
706         }
707         propagateThroughArgumentPositions();
708         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
709             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
710             if (!variableAccessData->isRoot())
711                 continue;
712             m_changed |= variableAccessData->makePredictionForDoubleFormat();
713         }
714     }
715     
716     void propagateThroughArgumentPositions()
717     {
718         for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
719             m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
720     }
721
722     // Sets any predictions that do not depends on other nodes.
723     void processInvariants()
724     {
725         for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
726             for (Node* node : *block) {
727                 m_currentNode = node;
728                 processInvariantsForNode();
729             }
730         }
731     }
732
733     void processInvariantsForNode()
734     {
735         switch (m_currentNode->op()) {
736         case JSConstant: {
737             SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
738             if (type == SpecAnyIntAsDouble && enableInt52())
739                 type = SpecInt52Only;
740             setPrediction(type);
741             break;
742         }
743         case DoubleConstant: {
744             SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
745             setPrediction(type);
746             break;
747         }
748
749         case ArithBitNot:
750         case ArithBitAnd:
751         case ArithBitOr:
752         case ArithBitXor:
753         case BitRShift:
754         case BitLShift:
755         case BitURShift:
756         case ArithIMul:
757         case ArithClz32: {
758             setPrediction(SpecInt32Only);
759             break;
760         }
761
762         case ArrayPop:
763         case ArrayPush:
764         case RegExpExec:
765         case RegExpExecNonGlobalOrSticky:
766         case RegExpTest:
767         case RegExpMatchFast:
768         case RegExpMatchFastGlobal:
769         case StringReplace:
770         case StringReplaceRegExp:
771         case GetById:
772         case GetByIdFlush:
773         case GetByIdWithThis:
774         case GetByIdDirect:
775         case GetByIdDirectFlush:
776         case TryGetById:
777         case GetByValWithThis:
778         case GetByOffset:
779         case MultiGetByOffset:
780         case GetDirectPname:
781         case Call:
782         case DirectCall:
783         case TailCallInlinedCaller:
784         case DirectTailCallInlinedCaller:
785         case Construct:
786         case DirectConstruct:
787         case CallVarargs:
788         case CallEval:
789         case TailCallVarargsInlinedCaller:
790         case ConstructVarargs:
791         case CallForwardVarargs:
792         case ConstructForwardVarargs:
793         case TailCallForwardVarargsInlinedCaller:
794         case GetGlobalVar:
795         case GetGlobalLexicalVariable:
796         case GetClosureVar:
797         case GetFromArguments:
798         case LoadKeyFromMapBucket:
799         case LoadValueFromMapBucket:
800         case ToNumber:
801         case ToObject:
802         case ValueBitAnd:
803         case ValueBitXor:
804         case ValueBitOr:
805         case ValueBitNot:
806         case CallObjectConstructor:
807         case GetArgument:
808         case CallDOMGetter:
809         case GetDynamicVar:
810         case GetPrototypeOf:
811         case ExtractValueFromWeakMapGet: 
812         case DataViewGetInt:
813         case DataViewGetFloat: {
814             setPrediction(m_currentNode->getHeapPrediction());
815             break;
816         }
817
818         case WeakMapGet:
819         case ResolveScopeForHoistingFuncDeclInEval: {
820             setPrediction(SpecBytecodeTop);
821             break;
822         }
823             
824         case GetGetterSetterByOffset:
825         case GetExecutable: {
826             setPrediction(SpecCellOther);
827             break;
828         }
829
830         case GetGetter:
831         case GetSetter:
832         case GetCallee:
833         case NewFunction:
834         case NewGeneratorFunction:
835         case NewAsyncGeneratorFunction:
836         case NewAsyncFunction: {
837             setPrediction(SpecFunction);
838             break;
839         }
840             
841         case GetArgumentCountIncludingThis: {
842             setPrediction(SpecInt32Only);
843             break;
844         }
845
846         case SetCallee:
847         case SetArgumentCountIncludingThis:
848             break;
849
850         case MapHash:
851             setPrediction(SpecInt32Only);
852             break;
853
854         case GetMapBucket:
855         case GetMapBucketHead:
856         case GetMapBucketNext:
857         case SetAdd:
858         case MapSet:
859             setPrediction(SpecCellOther);
860             break;
861
862         case GetRestLength:
863         case ArrayIndexOf: {
864             setPrediction(SpecInt32Only);
865             break;
866         }
867
868         case GetTypedArrayByteOffset:
869         case GetArrayLength:
870         case GetVectorLength: {
871             setPrediction(SpecInt32Only);
872             break;
873         }
874
875         case StringCharCodeAt: {
876             setPrediction(SpecInt32Only);
877             break;
878         }
879
880         case StringValueOf:
881         case StringSlice:
882         case ToLowerCase:
883             setPrediction(SpecString);
884             break;
885
886         case ArithPow:
887         case ArithSqrt:
888         case ArithFRound:
889         case ArithUnary: {
890             setPrediction(SpecBytecodeDouble);
891             break;
892         }
893
894         case ArithRound:
895         case ArithFloor:
896         case ArithCeil:
897         case ArithTrunc: {
898             if (isInt32OrBooleanSpeculation(m_currentNode->getHeapPrediction())
899                 && m_graph.roundShouldSpeculateInt32(m_currentNode, m_pass))
900                 setPrediction(SpecInt32Only);
901             else
902                 setPrediction(SpecBytecodeDouble);
903             break;
904         }
905
906         case ArithRandom: {
907             setPrediction(SpecDoubleReal);
908             break;
909         }
910         case DeleteByVal:
911         case DeleteById:
912         case LogicalNot:
913         case CompareLess:
914         case CompareLessEq:
915         case CompareGreater:
916         case CompareGreaterEq:
917         case CompareBelow:
918         case CompareBelowEq:
919         case CompareEq:
920         case CompareStrictEq:
921         case CompareEqPtr:
922         case SameValue:
923         case OverridesHasInstance:
924         case InstanceOf:
925         case InstanceOfCustom:
926         case IsEmpty:
927         case IsUndefined:
928         case IsUndefinedOrNull:
929         case IsBoolean:
930         case IsNumber:
931         case NumberIsInteger:
932         case IsObject:
933         case IsObjectOrNull:
934         case IsFunction:
935         case IsCellWithType:
936         case IsTypedArrayView:
937         case MatchStructure: {
938             setPrediction(SpecBoolean);
939             break;
940         }
941
942         case TypeOf: {
943             setPrediction(SpecStringIdent);
944             break;
945         }
946         case GetButterfly:
947         case GetIndexedPropertyStorage:
948         case AllocatePropertyStorage:
949         case ReallocatePropertyStorage: {
950             setPrediction(SpecOther);
951             break;
952         }
953
954         case CheckSubClass:
955             break;
956
957         case SkipScope:
958         case GetGlobalObject: {
959             setPrediction(SpecObjectOther);
960             break;
961         }
962
963         case GetGlobalThis:
964             setPrediction(SpecObject);
965             break;
966
967         case ResolveScope: {
968             setPrediction(SpecObjectOther);
969             break;
970         }
971             
972         case ObjectCreate:
973         case CreateThis:
974         case NewObject: {
975             setPrediction(SpecFinalObject);
976             break;
977         }
978             
979         case ArraySlice:
980         case NewArrayWithSpread:
981         case NewArray:
982         case NewArrayWithSize:
983         case CreateRest:
984         case NewArrayBuffer:
985         case ObjectKeys: {
986             setPrediction(SpecArray);
987             break;
988         }
989
990         case Spread:
991             setPrediction(SpecCellOther);
992             break;
993             
994         case NewTypedArray: {
995             setPrediction(speculationFromTypedArrayType(m_currentNode->typedArrayType()));
996             break;
997         }
998             
999         case NewRegexp: {
1000             setPrediction(SpecRegExpObject);
1001             break;
1002         }
1003             
1004         case PushWithScope:
1005         case CreateActivation: {
1006             setPrediction(SpecObjectOther);
1007             break;
1008         }
1009         
1010         case StringFromCharCode: {
1011             setPrediction(SpecString);
1012             m_currentNode->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsInt);
1013             break;
1014         }
1015         case StringCharAt:
1016         case CallStringConstructor:
1017         case ToString:
1018         case NumberToStringWithRadix:
1019         case NumberToStringWithValidRadixConstant:
1020         case MakeRope:
1021         case StrCat: {
1022             setPrediction(SpecString);
1023             break;
1024         }
1025         case NewStringObject: {
1026             setPrediction(SpecStringObject);
1027             break;
1028         }
1029         case NewSymbol: {
1030             setPrediction(SpecSymbol);
1031             break;
1032         }
1033             
1034         case CreateDirectArguments: {
1035             setPrediction(SpecDirectArguments);
1036             break;
1037         }
1038             
1039         case CreateScopedArguments: {
1040             setPrediction(SpecScopedArguments);
1041             break;
1042         }
1043             
1044         case CreateClonedArguments: {
1045             setPrediction(SpecObjectOther);
1046             break;
1047         }
1048             
1049         case FiatInt52: {
1050             RELEASE_ASSERT(enableInt52());
1051             setPrediction(SpecAnyInt);
1052             break;
1053         }
1054
1055         case GetScope:
1056             setPrediction(SpecObjectOther);
1057             break;
1058
1059         case InByVal:
1060         case InById:
1061             setPrediction(SpecBoolean);
1062             break;
1063
1064         case HasOwnProperty:
1065             setPrediction(SpecBoolean);
1066             break;
1067
1068         case GetEnumerableLength: {
1069             setPrediction(SpecInt32Only);
1070             break;
1071         }
1072         case HasGenericProperty:
1073         case HasStructureProperty:
1074         case HasIndexedProperty: {
1075             setPrediction(SpecBoolean);
1076             break;
1077         }
1078         case GetPropertyEnumerator: {
1079             setPrediction(SpecCell);
1080             break;
1081         }
1082         case GetEnumeratorStructurePname: {
1083             setPrediction(SpecCell | SpecOther);
1084             break;
1085         }
1086         case GetEnumeratorGenericPname: {
1087             setPrediction(SpecCell | SpecOther);
1088             break;
1089         }
1090         case ToIndexString: {
1091             setPrediction(SpecString);
1092             break;
1093         }
1094         case ParseInt: {
1095             // We expect this node to almost always produce an int32. However,
1096             // it's possible it produces NaN or integers out of int32 range. We
1097             // rely on the heap prediction since the parseInt() call profiled
1098             // its result.
1099             setPrediction(m_currentNode->getHeapPrediction());
1100             break;
1101         }
1102
1103         case IdentityWithProfile: {
1104             setPrediction(m_currentNode->getForcedPrediction());
1105             break;
1106         }
1107
1108         case ExtractCatchLocal: {
1109             setPrediction(m_currentNode->catchLocalPrediction());
1110             break;
1111         }
1112
1113         case GetLocal:
1114         case SetLocal:
1115         case UInt32ToNumber:
1116         case ValueNegate:
1117         case ValueAdd:
1118         case ValueSub:
1119         case ValueMul:
1120         case ValueDiv:
1121         case ArithAdd:
1122         case ArithSub:
1123         case ArithNegate:
1124         case ArithMin:
1125         case ArithMax:
1126         case ArithMul:
1127         case ArithDiv:
1128         case ArithMod:
1129         case ArithAbs:
1130         case GetByVal:
1131         case ToThis:
1132         case ToPrimitive: 
1133         case NormalizeMapKey:
1134         case AtomicsAdd:
1135         case AtomicsAnd:
1136         case AtomicsCompareExchange:
1137         case AtomicsExchange:
1138         case AtomicsLoad:
1139         case AtomicsOr:
1140         case AtomicsStore:
1141         case AtomicsSub:
1142         case AtomicsXor: {
1143             m_dependentNodes.append(m_currentNode);
1144             break;
1145         }
1146             
1147         case AtomicsIsLockFree: {
1148             setPrediction(SpecBoolean);
1149             break;
1150         }
1151
1152         case CPUIntrinsic: {
1153             if (m_currentNode->intrinsic() == CPURdtscIntrinsic)
1154                 setPrediction(SpecInt32Only);
1155             else
1156                 setPrediction(SpecOther);
1157             break;
1158         }
1159
1160         case PutByValAlias:
1161         case DoubleAsInt32:
1162         case CheckArray:
1163         case CheckTypeInfoFlags:
1164         case Arrayify:
1165         case ArrayifyToStructure:
1166         case CheckTierUpInLoop:
1167         case CheckTierUpAtReturn:
1168         case CheckTierUpAndOSREnter:
1169         case CheckInBounds:
1170         case ValueToInt32:
1171         case DoubleRep:
1172         case ValueRep:
1173         case Int52Rep:
1174         case Int52Constant:
1175         case Identity:
1176         case BooleanToNumber:
1177         case PhantomNewObject:
1178         case PhantomNewFunction:
1179         case PhantomNewGeneratorFunction:
1180         case PhantomNewAsyncGeneratorFunction:
1181         case PhantomNewAsyncFunction:
1182         case PhantomCreateActivation:
1183         case PhantomDirectArguments:
1184         case PhantomCreateRest:
1185         case PhantomSpread:
1186         case PhantomNewArrayWithSpread:
1187         case PhantomNewArrayBuffer:
1188         case PhantomClonedArguments:
1189         case PhantomNewRegexp:
1190         case GetMyArgumentByVal:
1191         case GetMyArgumentByValOutOfBounds:
1192         case PutHint:
1193         case CheckStructureImmediate:
1194         case CheckStructureOrEmpty:
1195         case MaterializeNewObject:
1196         case MaterializeCreateActivation:
1197         case PutStack:
1198         case KillStack:
1199         case StoreBarrier:
1200         case FencedStoreBarrier:
1201         case GetStack:
1202         case GetRegExpObjectLastIndex:
1203         case SetRegExpObjectLastIndex:
1204         case RecordRegExpCachedResult:
1205         case LazyJSConstant:
1206         case CallDOM: {
1207             // This node should never be visible at this stage of compilation.
1208             DFG_CRASH(m_graph, m_currentNode, "Unexpected node during prediction propagation");
1209             break;
1210         }
1211         
1212         case Phi:
1213             // Phis should not be visible here since we're iterating the all-but-Phi's
1214             // part of basic blocks.
1215             RELEASE_ASSERT_NOT_REACHED();
1216             break;
1217             
1218         case EntrySwitch:
1219         case Upsilon:
1220             // These don't get inserted until we go into SSA.
1221             RELEASE_ASSERT_NOT_REACHED();
1222             break;
1223
1224 #ifndef NDEBUG
1225         // These get ignored because they don't return anything.
1226         case PutByValDirect:
1227         case PutByValWithThis:
1228         case PutByIdWithThis:
1229         case PutByVal:
1230         case PutClosureVar:
1231         case PutToArguments:
1232         case Return:
1233         case Throw:
1234         case ThrowStaticError:
1235         case TailCall:
1236         case DirectTailCall:
1237         case TailCallVarargs:
1238         case TailCallForwardVarargs:
1239         case PutById:
1240         case PutByIdFlush:
1241         case PutByIdDirect:
1242         case PutByOffset:
1243         case MultiPutByOffset:
1244         case PutGetterById:
1245         case PutSetterById:
1246         case PutGetterSetterById:
1247         case PutGetterByVal:
1248         case PutSetterByVal:
1249         case DefineDataProperty:
1250         case DefineAccessorProperty:
1251         case DFG::Jump:
1252         case Branch:
1253         case Switch:
1254         case ProfileType:
1255         case ProfileControlFlow:
1256         case ForceOSRExit:
1257         case SetArgument:
1258         case SetFunctionName:
1259         case CheckStructure:
1260         case CheckCell:
1261         case CheckNotEmpty:
1262         case AssertNotEmpty:
1263         case CheckStringIdent:
1264         case CheckBadCell:
1265         case PutStructure:
1266         case Phantom:
1267         case Check:
1268         case CheckVarargs:
1269         case PutGlobalVariable:
1270         case CheckTraps:
1271         case LogShadowChickenPrologue:
1272         case LogShadowChickenTail:
1273         case Unreachable:
1274         case LoopHint:
1275         case NotifyWrite:
1276         case ConstantStoragePointer:
1277         case MovHint:
1278         case ZombieHint:
1279         case ExitOK:
1280         case LoadVarargs:
1281         case ForwardVarargs:
1282         case PutDynamicVar:
1283         case NukeStructureAndSetButterfly:
1284         case InitializeEntrypointArguments:
1285         case WeakSetAdd:
1286         case WeakMapSet:
1287         case FilterCallLinkStatus:
1288         case FilterGetByIdStatus:
1289         case FilterPutByIdStatus:
1290         case FilterInByIdStatus:
1291         case ClearCatchLocals:
1292         case DataViewSet:
1293         case InvalidationPoint:
1294             break;
1295             
1296         // This gets ignored because it only pretends to produce a value.
1297         case BottomValue:
1298             break;
1299             
1300         // This gets ignored because it already has a prediction.
1301         case ExtractOSREntryLocal:
1302             break;
1303             
1304         // These gets ignored because it doesn't do anything.
1305         case CountExecution:
1306         case SuperSamplerBegin:
1307         case SuperSamplerEnd:
1308         case PhantomLocal:
1309         case Flush:
1310             break;
1311             
1312         case LastNodeType:
1313             RELEASE_ASSERT_NOT_REACHED();
1314             break;
1315 #else
1316         default:
1317             break;
1318 #endif
1319         }
1320     }
1321
1322     SpeculatedType resultOfToPrimitive(SpeculatedType type)
1323     {
1324         if (type & SpecObject) {
1325             // We try to be optimistic here about StringObjects since it's unlikely that
1326             // someone overrides the valueOf or toString methods.
1327             if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic))
1328                 return mergeSpeculations(type & ~SpecObject, SpecString);
1329
1330             return mergeSpeculations(type & ~SpecObject, SpecPrimitive);
1331         }
1332
1333         return type;
1334     }
1335
1336     Vector<Node*> m_dependentNodes;
1337     Node* m_currentNode;
1338     bool m_changed { false };
1339     PredictionPass m_pass { PrimaryPass }; // We use different logic for considering predictions depending on how far along we are in propagation.
1340 };
1341
1342 } // Anonymous namespace.
1343     
1344 bool performPredictionPropagation(Graph& graph)
1345 {
1346     return runPhase<PredictionPropagationPhase>(graph);
1347 }
1348
1349 } } // namespace JSC::DFG
1350
1351 #endif // ENABLE(DFG_JIT)
1352