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