f09dc541ef006134554d91fe442f2df859074973
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGPredictionPropagationPhase.cpp
1 /*
2  * Copyright (C) 2011-2016 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 & SpecInt52))
159                 prediction = (prediction | SpecInt52AsDouble) & ~SpecInt52;
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(SpecInt32);
174             else if (enableInt52())
175                 changed |= mergePrediction(SpecMachineInt);
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(SpecInt32);
190                     else if (m_graph.addShouldSpeculateMachineInt(node))
191                         changed |= mergePrediction(SpecInt52);
192                     else
193                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
194                 } else if (
195                     !(left & (SpecFullNumber | SpecBoolean))
196                     || !(right & (SpecFullNumber | SpecBoolean))) {
197                     // left or right is definitely something other than a number.
198                     changed |= mergePrediction(SpecString);
199                 } else
200                     changed |= mergePrediction(SpecString | SpecInt32 | SpecBytecodeDouble);
201             }
202             break;
203         }
204
205         case ArithAdd: {
206             SpeculatedType left = node->child1()->prediction();
207             SpeculatedType right = node->child2()->prediction();
208             
209             if (left && right) {
210                 if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
211                     changed |= mergePrediction(SpecInt32);
212                 else if (m_graph.addShouldSpeculateMachineInt(node))
213                     changed |= mergePrediction(SpecInt52);
214                 else
215                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
216             }
217             break;
218         }
219             
220         case ArithSub: {
221             SpeculatedType left = node->child1()->prediction();
222             SpeculatedType right = node->child2()->prediction();
223
224             if (left && right) {
225                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
226                     && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
227                     if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32)
228                         changed |= mergePrediction(SpecInt32);
229                     else if (m_graph.addShouldSpeculateMachineInt(node))
230                         changed |= mergePrediction(SpecInt52);
231                     else
232                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
233                 } else
234                     changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble);
235             }
236             break;
237         }
238
239         case ArithNegate:
240             if (node->child1()->prediction()) {
241                 if (m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
242                     changed |= mergePrediction(SpecInt32);
243                 else if (m_graph.unaryArithShouldSpeculateMachineInt(node, m_pass))
244                     changed |= mergePrediction(SpecInt52);
245                 else
246                     changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
247             }
248             break;
249             
250         case ArithMin:
251         case ArithMax: {
252             SpeculatedType left = node->child1()->prediction();
253             SpeculatedType right = node->child2()->prediction();
254             
255             if (left && right) {
256                 if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
257                     && node->canSpeculateInt32(m_pass))
258                     changed |= mergePrediction(SpecInt32);
259                 else
260                     changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
261             }
262             break;
263         }
264
265         case ArithMul: {
266             SpeculatedType left = node->child1()->prediction();
267             SpeculatedType right = node->child2()->prediction();
268             
269             if (left && right) {
270                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
271                     && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
272                     if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
273                         changed |= mergePrediction(SpecInt32);
274                     else if (m_graph.binaryArithShouldSpeculateMachineInt(node, m_pass))
275                         changed |= mergePrediction(SpecInt52);
276                     else
277                         changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
278                 } else {
279                     if (node->mayHaveNonIntResult())
280                         changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble);
281                     else
282                         changed |= mergePrediction(SpecInt32);
283                 }
284             }
285             break;
286         }
287
288         case ArithDiv:
289         case ArithMod: {
290             SpeculatedType left = node->child1()->prediction();
291             SpeculatedType right = node->child2()->prediction();
292             
293             if (left && right) {
294                 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
295                     && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
296                     if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
297                         changed |= mergePrediction(SpecInt32);
298                     else
299                         changed |= mergePrediction(SpecBytecodeDouble);
300                 } else
301                     changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble);
302             }
303             break;
304         }
305
306         case ArithRound:
307         case ArithFloor:
308         case ArithCeil:
309         case ArithTrunc: {
310             if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, m_pass))
311                 changed |= setPrediction(SpecInt32);
312             else
313                 changed |= setPrediction(SpecBytecodeDouble);
314             break;
315         }
316
317         case ArithAbs: {
318             SpeculatedType child = node->child1()->prediction();
319             if (isInt32OrBooleanSpeculationForArithmetic(child)
320                 && node->canSpeculateInt32(m_pass))
321                 changed |= mergePrediction(SpecInt32);
322             else
323                 changed |= mergePrediction(speculatedDoubleTypeForPrediction(child));
324             break;
325         }
326
327         case GetByVal: {
328             if (!node->child1()->prediction())
329                 break;
330             
331             ArrayMode arrayMode = node->arrayMode().refine(
332                 m_graph, node,
333                 node->child1()->prediction(),
334                 node->child2()->prediction(),
335                 SpecNone);
336             
337             switch (arrayMode.type()) {
338             case Array::Int32:
339                 if (arrayMode.isOutOfBounds())
340                     changed |= mergePrediction(node->getHeapPrediction() | SpecInt32);
341                 else
342                     changed |= mergePrediction(SpecInt32);
343                 break;
344             case Array::Double:
345                 if (arrayMode.isOutOfBounds())
346                     changed |= mergePrediction(node->getHeapPrediction() | SpecDoubleReal);
347                 else
348                     changed |= mergePrediction(SpecDoubleReal);
349                 break;
350             case Array::Float32Array:
351             case Array::Float64Array:
352                 changed |= mergePrediction(SpecFullDouble);
353                 break;
354             case Array::Uint32Array:
355                 if (isInt32SpeculationForArithmetic(node->getHeapPrediction()))
356                     changed |= mergePrediction(SpecInt32);
357                 else if (enableInt52())
358                     changed |= mergePrediction(SpecMachineInt);
359                 else
360                     changed |= mergePrediction(SpecInt32 | SpecInt52AsDouble);
361                 break;
362             case Array::Int8Array:
363             case Array::Uint8Array:
364             case Array::Int16Array:
365             case Array::Uint16Array:
366             case Array::Int32Array:
367                 changed |= mergePrediction(SpecInt32);
368                 break;
369             default:
370                 changed |= mergePrediction(node->getHeapPrediction());
371                 break;
372             }
373             break;
374         }
375
376         case ToThis: {
377             // ToThis in methods for primitive types should speculate primitive types in strict mode.
378             ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
379             if (ecmaMode == StrictMode) {
380                 if (node->child1()->shouldSpeculateBoolean()) {
381                     changed |= mergePrediction(SpecBoolean);
382                     break;
383                 }
384
385                 if (node->child1()->shouldSpeculateInt32()) {
386                     changed |= mergePrediction(SpecInt32);
387                     break;
388                 }
389
390                 if (enableInt52() && node->child1()->shouldSpeculateMachineInt()) {
391                     changed |= mergePrediction(SpecMachineInt);
392                     break;
393                 }
394
395                 if (node->child1()->shouldSpeculateNumber()) {
396                     changed |= mergePrediction(SpecMachineInt);
397                     break;
398                 }
399
400                 if (node->child1()->shouldSpeculateSymbol()) {
401                     changed |= mergePrediction(SpecSymbol);
402                     break;
403                 }
404
405                 if (node->child1()->shouldSpeculateStringIdent()) {
406                     changed |= mergePrediction(SpecStringIdent);
407                     break;
408                 }
409
410                 if (node->child1()->shouldSpeculateString()) {
411                     changed |= mergePrediction(SpecString);
412                     break;
413                 }
414             } else {
415                 if (node->child1()->shouldSpeculateString()) {
416                     changed |= mergePrediction(SpecStringObject);
417                     break;
418                 }
419             }
420
421             SpeculatedType prediction = node->child1()->prediction();
422             if (prediction) {
423                 if (prediction & ~SpecObject) {
424                     // Wrapper objects are created only in sloppy mode.
425                     if (ecmaMode != StrictMode) {
426                         prediction &= SpecObject;
427                         prediction = mergeSpeculations(prediction, SpecObjectOther);
428                     }
429                 }
430                 changed |= mergePrediction(prediction);
431             }
432             break;
433         }
434             
435         case ToPrimitive: {
436             SpeculatedType child = node->child1()->prediction();
437             if (child)
438                 changed |= mergePrediction(resultOfToPrimitive(child));
439             break;
440         }
441
442         default:
443             break;
444         }
445
446         m_changed |= changed;
447     }
448         
449     void propagateForward()
450     {
451         for (Node* node : m_dependentNodes) {
452             m_currentNode = node;
453             propagate(m_currentNode);
454         }
455     }
456
457     void propagateBackward()
458     {
459         for (unsigned i = m_dependentNodes.size(); i--;) {
460             m_currentNode = m_dependentNodes[i];
461             propagate(m_currentNode);
462         }
463     }
464     
465     void doDoubleVoting(Node* node, float weight)
466     {
467         // Loop pre-headers created by OSR entrypoint creation may have NaN weight to indicate
468         // that we actually don't know they weight. Assume that they execute once. This turns
469         // out to be an OK assumption since the pre-header doesn't have any meaningful code.
470         if (weight != weight)
471             weight = 1;
472         
473         switch (node->op()) {
474         case ValueAdd:
475         case ArithAdd:
476         case ArithSub: {
477             SpeculatedType left = node->child1()->prediction();
478             SpeculatedType right = node->child2()->prediction();
479                 
480             DoubleBallot ballot;
481                 
482             if (isFullNumberSpeculation(left)
483                 && isFullNumberSpeculation(right)
484                 && !m_graph.addShouldSpeculateInt32(node, m_pass)
485                 && !m_graph.addShouldSpeculateMachineInt(node))
486                 ballot = VoteDouble;
487             else
488                 ballot = VoteValue;
489                 
490             m_graph.voteNode(node->child1(), ballot, weight);
491             m_graph.voteNode(node->child2(), ballot, weight);
492             break;
493         }
494
495         case ArithMul: {
496             SpeculatedType left = node->child1()->prediction();
497             SpeculatedType right = node->child2()->prediction();
498                 
499             DoubleBallot ballot;
500                 
501             if (isFullNumberSpeculation(left)
502                 && isFullNumberSpeculation(right)
503                 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass)
504                 && !m_graph.binaryArithShouldSpeculateMachineInt(node, m_pass))
505                 ballot = VoteDouble;
506             else
507                 ballot = VoteValue;
508                 
509             m_graph.voteNode(node->child1(), ballot, weight);
510             m_graph.voteNode(node->child2(), ballot, weight);
511             break;
512         }
513
514         case ArithMin:
515         case ArithMax:
516         case ArithMod:
517         case ArithDiv: {
518             SpeculatedType left = node->child1()->prediction();
519             SpeculatedType right = node->child2()->prediction();
520                 
521             DoubleBallot ballot;
522                 
523             if (isFullNumberSpeculation(left)
524                 && isFullNumberSpeculation(right)
525                 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
526                 ballot = VoteDouble;
527             else
528                 ballot = VoteValue;
529                 
530             m_graph.voteNode(node->child1(), ballot, weight);
531             m_graph.voteNode(node->child2(), ballot, weight);
532             break;
533         }
534
535         case ArithAbs:
536             DoubleBallot ballot;
537             if (node->child1()->shouldSpeculateNumber()
538                 && !m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
539                 ballot = VoteDouble;
540             else
541                 ballot = VoteValue;
542                 
543             m_graph.voteNode(node->child1(), ballot, weight);
544             break;
545                 
546         case ArithSqrt:
547         case ArithCos:
548         case ArithSin:
549         case ArithLog:
550             if (node->child1()->shouldSpeculateNumber())
551                 m_graph.voteNode(node->child1(), VoteDouble, weight);
552             else
553                 m_graph.voteNode(node->child1(), VoteValue, weight);
554             break;
555                 
556         case SetLocal: {
557             SpeculatedType prediction = node->child1()->prediction();
558             if (isDoubleSpeculation(prediction))
559                 node->variableAccessData()->vote(VoteDouble, weight);
560             else if (!isFullNumberSpeculation(prediction)
561                 || isInt32Speculation(prediction) || isMachineIntSpeculation(prediction))
562                 node->variableAccessData()->vote(VoteValue, weight);
563             break;
564         }
565
566         case PutByValDirect:
567         case PutByVal:
568         case PutByValAlias: {
569             Edge child1 = m_graph.varArgChild(node, 0);
570             Edge child2 = m_graph.varArgChild(node, 1);
571             Edge child3 = m_graph.varArgChild(node, 2);
572             m_graph.voteNode(child1, VoteValue, weight);
573             m_graph.voteNode(child2, VoteValue, weight);
574             switch (node->arrayMode().type()) {
575             case Array::Double:
576                 m_graph.voteNode(child3, VoteDouble, weight);
577                 break;
578             default:
579                 m_graph.voteNode(child3, VoteValue, weight);
580                 break;
581             }
582             break;
583         }
584             
585         case MovHint:
586             // Ignore these since they have no effect on in-DFG execution.
587             break;
588             
589         default:
590             m_graph.voteChildren(node, VoteValue, weight);
591             break;
592         }
593     }
594     
595     void doRoundOfDoubleVoting()
596     {
597         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
598             m_graph.m_variableAccessData[i].find()->clearVotes();
599         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
600             BasicBlock* block = m_graph.block(blockIndex);
601             if (!block)
602                 continue;
603             ASSERT(block->isReachable);
604             for (unsigned i = 0; i < block->size(); ++i) {
605                 m_currentNode = block->at(i);
606                 doDoubleVoting(m_currentNode, block->executionCount);
607             }
608         }
609         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
610             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
611             if (!variableAccessData->isRoot())
612                 continue;
613             m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
614         }
615         propagateThroughArgumentPositions();
616         for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
617             VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
618             if (!variableAccessData->isRoot())
619                 continue;
620             m_changed |= variableAccessData->makePredictionForDoubleFormat();
621         }
622     }
623     
624     void propagateThroughArgumentPositions()
625     {
626         for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
627             m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
628     }
629
630     // Sets any predictions that do not depends on other nodes.
631     void processInvariants()
632     {
633         for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
634             for (Node* node : *block) {
635                 m_currentNode = node;
636                 processInvariantsForNode();
637             }
638         }
639     }
640
641     void processInvariantsForNode()
642     {
643         switch (m_currentNode->op()) {
644         case JSConstant: {
645             SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
646             if (type == SpecInt52AsDouble && enableInt52())
647                 type = SpecInt52;
648             setPrediction(type);
649             break;
650         }
651         case DoubleConstant: {
652             SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
653             setPrediction(type);
654             break;
655         }
656         case BitAnd:
657         case BitOr:
658         case BitXor:
659         case BitRShift:
660         case BitLShift:
661         case BitURShift:
662         case ArithIMul:
663         case ArithClz32: {
664             setPrediction(SpecInt32);
665             break;
666         }
667
668         case TryGetById: {
669             setPrediction(SpecBytecodeTop);
670             break;
671         }
672         case ArrayPop:
673         case ArrayPush:
674         case RegExpExec:
675         case RegExpTest:
676         case StringReplace:
677         case GetById:
678         case GetByIdFlush:
679         case GetByOffset:
680         case MultiGetByOffset:
681         case GetDirectPname:
682         case Call:
683         case TailCallInlinedCaller:
684         case Construct:
685         case CallVarargs:
686         case TailCallVarargsInlinedCaller:
687         case ConstructVarargs:
688         case CallForwardVarargs:
689         case ConstructForwardVarargs:
690         case TailCallForwardVarargsInlinedCaller:
691         case GetGlobalVar:
692         case GetGlobalLexicalVariable:
693         case GetClosureVar:
694         case GetFromArguments: {
695             setPrediction(m_currentNode->getHeapPrediction());
696             break;
697         }
698
699         case GetDynamicVar: {
700             setPrediction(SpecBytecodeTop);
701             break;
702         }
703             
704         case GetGetterSetterByOffset:
705         case GetExecutable: {
706             setPrediction(SpecCellOther);
707             break;
708         }
709
710         case GetGetter:
711         case GetSetter:
712         case GetCallee:
713         case NewFunction:
714         case NewGeneratorFunction: {
715             setPrediction(SpecFunction);
716             break;
717         }
718             
719         case GetArgumentCount: {
720             setPrediction(SpecInt32);
721             break;
722         }
723
724         case GetRestLength: {
725             setPrediction(SpecInt32);
726             break;
727         }
728
729         case GetTypedArrayByteOffset:
730         case GetArrayLength: {
731             setPrediction(SpecInt32);
732             break;
733         }
734
735         case StringCharCodeAt: {
736             setPrediction(SpecInt32);
737             break;
738         }
739         case ArithPow:
740         case ArithSqrt:
741         case ArithFRound:
742         case ArithSin:
743         case ArithCos:
744         case ArithLog: {
745             setPrediction(SpecBytecodeDouble);
746             break;
747         }
748
749         case ArithRandom: {
750             setPrediction(SpecDoubleReal);
751             break;
752         }
753         case DeleteById:
754         case LogicalNot:
755         case CompareLess:
756         case CompareLessEq:
757         case CompareGreater:
758         case CompareGreaterEq:
759         case CompareEq:
760         case CompareStrictEq:
761         case OverridesHasInstance:
762         case InstanceOf:
763         case InstanceOfCustom:
764         case IsArrayObject:
765         case IsJSArray:
766         case IsArrayConstructor:
767         case IsUndefined:
768         case IsBoolean:
769         case IsNumber:
770         case IsString:
771         case IsObject:
772         case IsObjectOrNull:
773         case IsFunction:
774         case IsRegExpObject: {
775             setPrediction(SpecBoolean);
776             break;
777         }
778
779         case TypeOf: {
780             setPrediction(SpecStringIdent);
781             break;
782         }
783         case GetButterfly:
784         case GetIndexedPropertyStorage:
785         case AllocatePropertyStorage:
786         case ReallocatePropertyStorage: {
787             setPrediction(SpecOther);
788             break;
789         }
790
791         case CallObjectConstructor: {
792             setPrediction(SpecObject);
793             break;
794         }
795         case SkipScope:
796         case GetGlobalObject: {
797             setPrediction(SpecObjectOther);
798             break;
799         }
800
801         case ResolveScope: {
802             setPrediction(SpecObjectOther);
803             break;
804         }
805             
806         case CreateThis:
807         case NewObject: {
808             setPrediction(SpecFinalObject);
809             break;
810         }
811             
812         case NewArray:
813         case NewArrayWithSize:
814         case NewArrayBuffer: {
815             setPrediction(SpecArray);
816             break;
817         }
818             
819         case NewTypedArray: {
820             setPrediction(speculationFromTypedArrayType(m_currentNode->typedArrayType()));
821             break;
822         }
823             
824         case NewRegexp: {
825             setPrediction(SpecRegExpObject);
826             break;
827         }
828             
829         case CreateActivation: {
830             setPrediction(SpecObjectOther);
831             break;
832         }
833         
834         case StringFromCharCode: {
835             setPrediction(SpecString);
836             m_currentNode->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsInt);
837             break;
838         }
839         case StringCharAt:
840         case CallStringConstructor:
841         case ToString:
842         case MakeRope:
843         case StrCat: {
844             setPrediction(SpecString);
845             break;
846         }
847         case NewStringObject: {
848             setPrediction(SpecStringObject);
849             break;
850         }
851             
852         case CreateDirectArguments: {
853             setPrediction(SpecDirectArguments);
854             break;
855         }
856             
857         case CreateScopedArguments: {
858             setPrediction(SpecScopedArguments);
859             break;
860         }
861             
862         case CreateClonedArguments: {
863             setPrediction(SpecObjectOther);
864             break;
865         }
866             
867         case FiatInt52: {
868             RELEASE_ASSERT(enableInt52());
869             setPrediction(SpecMachineInt);
870             break;
871         }
872
873         case GetScope:
874             setPrediction(SpecObjectOther);
875             break;
876
877         case In:
878             setPrediction(SpecBoolean);
879             break;
880
881         case GetEnumerableLength: {
882             setPrediction(SpecInt32);
883             break;
884         }
885         case HasGenericProperty:
886         case HasStructureProperty:
887         case HasIndexedProperty: {
888             setPrediction(SpecBoolean);
889             break;
890         }
891         case GetPropertyEnumerator: {
892             setPrediction(SpecCell);
893             break;
894         }
895         case GetEnumeratorStructurePname: {
896             setPrediction(SpecCell | SpecOther);
897             break;
898         }
899         case GetEnumeratorGenericPname: {
900             setPrediction(SpecCell | SpecOther);
901             break;
902         }
903         case ToIndexString: {
904             setPrediction(SpecString);
905             break;
906         }
907
908         case GetLocal:
909         case SetLocal:
910         case UInt32ToNumber:
911         case ValueAdd:
912         case ArithAdd:
913         case ArithSub:
914         case ArithNegate:
915         case ArithMin:
916         case ArithMax:
917         case ArithMul:
918         case ArithDiv:
919         case ArithMod:
920         case ArithRound:
921         case ArithFloor:
922         case ArithCeil:
923         case ArithTrunc:
924         case ArithAbs:
925         case GetByVal:
926         case ToThis:
927         case ToPrimitive: {
928             m_dependentNodes.append(m_currentNode);
929             break;
930         }
931
932         case PutByValAlias:
933         case DoubleAsInt32:
934         case GetLocalUnlinked:
935         case CheckArray:
936         case CheckTypeInfoFlags:
937         case Arrayify:
938         case ArrayifyToStructure:
939         case CheckTierUpInLoop:
940         case CheckTierUpAtReturn:
941         case CheckTierUpAndOSREnter:
942         case InvalidationPoint:
943         case CheckInBounds:
944         case ValueToInt32:
945         case DoubleRep:
946         case ValueRep:
947         case Int52Rep:
948         case Int52Constant:
949         case Identity:
950         case BooleanToNumber:
951         case PhantomNewObject:
952         case PhantomNewFunction:
953         case PhantomNewGeneratorFunction:
954         case PhantomCreateActivation:
955         case PhantomDirectArguments:
956         case PhantomClonedArguments:
957         case GetMyArgumentByVal:
958         case GetMyArgumentByValOutOfBounds:
959         case ForwardVarargs:
960         case PutHint:
961         case CheckStructureImmediate:
962         case MaterializeNewObject:
963         case MaterializeCreateActivation:
964         case PutStack:
965         case KillStack:
966         case StoreBarrier:
967         case GetStack:
968         case GetRegExpObjectLastIndex:
969         case SetRegExpObjectLastIndex:
970         case RecordRegExpCachedResult:
971         case LazyJSConstant: {
972             // This node should never be visible at this stage of compilation. It is
973             // inserted by fixup(), which follows this phase.
974             DFG_CRASH(m_graph, m_currentNode, "Unexpected node during prediction propagation");
975             break;
976         }
977         
978         case Phi:
979             // Phis should not be visible here since we're iterating the all-but-Phi's
980             // part of basic blocks.
981             RELEASE_ASSERT_NOT_REACHED();
982             break;
983             
984         case Upsilon:
985             // These don't get inserted until we go into SSA.
986             RELEASE_ASSERT_NOT_REACHED();
987             break;
988
989 #ifndef NDEBUG
990         // These get ignored because they don't return anything.
991         case PutByValDirect:
992         case PutByVal:
993         case PutClosureVar:
994         case PutToArguments:
995         case Return:
996         case TailCall:
997         case TailCallVarargs:
998         case TailCallForwardVarargs:
999         case Throw:
1000         case PutById:
1001         case PutByIdFlush:
1002         case PutByIdDirect:
1003         case PutByOffset:
1004         case MultiPutByOffset:
1005         case PutGetterById:
1006         case PutSetterById:
1007         case PutGetterSetterById:
1008         case PutGetterByVal:
1009         case PutSetterByVal:
1010         case DFG::Jump:
1011         case Branch:
1012         case Switch:
1013         case ProfileWillCall:
1014         case ProfileDidCall:
1015         case ProfileType:
1016         case ProfileControlFlow:
1017         case ThrowReferenceError:
1018         case ForceOSRExit:
1019         case SetArgument:
1020         case SetFunctionName:
1021         case CheckStructure:
1022         case CheckCell:
1023         case CheckNotEmpty:
1024         case CheckIdent:
1025         case CheckBadCell:
1026         case PutStructure:
1027         case VarInjectionWatchpoint:
1028         case Phantom:
1029         case Check:
1030         case PutGlobalVariable:
1031         case CheckWatchdogTimer:
1032         case LogShadowChickenPrologue:
1033         case LogShadowChickenTail:
1034         case Unreachable:
1035         case LoopHint:
1036         case NotifyWrite:
1037         case ConstantStoragePointer:
1038         case MovHint:
1039         case ZombieHint:
1040         case ExitOK:
1041         case LoadVarargs:
1042         case CopyRest:
1043         case PutDynamicVar:
1044             break;
1045             
1046         // This gets ignored because it only pretends to produce a value.
1047         case BottomValue:
1048             break;
1049             
1050         // This gets ignored because it already has a prediction.
1051         case ExtractOSREntryLocal:
1052             break;
1053             
1054         // These gets ignored because it doesn't do anything.
1055         case CountExecution:
1056         case PhantomLocal:
1057         case Flush:
1058             break;
1059             
1060         case LastNodeType:
1061             RELEASE_ASSERT_NOT_REACHED();
1062             break;
1063 #else
1064         default:
1065             break;
1066 #endif
1067         }
1068     }
1069
1070     SpeculatedType resultOfToPrimitive(SpeculatedType type)
1071     {
1072         if (type & SpecObject) {
1073             // We try to be optimistic here about StringObjects since it's unlikely that
1074             // someone overrides the valueOf or toString methods.
1075             if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic))
1076                 return mergeSpeculations(type & ~SpecObject, SpecString);
1077
1078             return mergeSpeculations(type & ~SpecObject, SpecPrimitive);
1079         }
1080
1081         return type;
1082     }
1083
1084     Vector<Node*> m_dependentNodes;
1085     Node* m_currentNode;
1086     bool m_changed;
1087     PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation.
1088 };
1089
1090 } // Anonymous namespace.
1091     
1092 bool performPredictionPropagation(Graph& graph)
1093 {
1094     return runPhase<PredictionPropagationPhase>(graph);
1095 }
1096
1097 } } // namespace JSC::DFG
1098
1099 #endif // ENABLE(DFG_JIT)
1100