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