Rollout r200426 since it causes PLT regressions.
[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             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             setPrediction(SpecFunction);
737             break;
738         }
739             
740         case GetArgumentCount: {
741             setPrediction(SpecInt32Only);
742             break;
743         }
744
745         case GetRestLength: {
746             setPrediction(SpecInt32Only);
747             break;
748         }
749
750         case GetTypedArrayByteOffset:
751         case GetArrayLength: {
752             setPrediction(SpecInt32Only);
753             break;
754         }
755
756         case StringCharCodeAt: {
757             setPrediction(SpecInt32Only);
758             break;
759         }
760         case ArithPow:
761         case ArithSqrt:
762         case ArithFRound:
763         case ArithSin:
764         case ArithCos:
765         case ArithLog: {
766             setPrediction(SpecBytecodeDouble);
767             break;
768         }
769
770         case ArithRandom: {
771             setPrediction(SpecDoubleReal);
772             break;
773         }
774         case DeleteByVal:
775         case DeleteById:
776         case LogicalNot:
777         case CompareLess:
778         case CompareLessEq:
779         case CompareGreater:
780         case CompareGreaterEq:
781         case CompareEq:
782         case CompareStrictEq:
783         case OverridesHasInstance:
784         case InstanceOf:
785         case InstanceOfCustom:
786         case IsEmpty:
787         case IsUndefined:
788         case IsBoolean:
789         case IsNumber:
790         case IsString:
791         case IsObject:
792         case IsObjectOrNull:
793         case IsFunction:
794         case IsRegExpObject: {
795             setPrediction(SpecBoolean);
796             break;
797         }
798
799         case TypeOf: {
800             setPrediction(SpecStringIdent);
801             break;
802         }
803         case GetButterfly:
804         case GetIndexedPropertyStorage:
805         case AllocatePropertyStorage:
806         case ReallocatePropertyStorage: {
807             setPrediction(SpecOther);
808             break;
809         }
810
811         case SkipScope:
812         case GetGlobalObject: {
813             setPrediction(SpecObjectOther);
814             break;
815         }
816
817         case ResolveScope: {
818             setPrediction(SpecObjectOther);
819             break;
820         }
821             
822         case CreateThis:
823         case NewObject: {
824             setPrediction(SpecFinalObject);
825             break;
826         }
827             
828         case NewArray:
829         case NewArrayWithSize:
830         case NewArrayBuffer: {
831             setPrediction(SpecArray);
832             break;
833         }
834             
835         case NewTypedArray: {
836             setPrediction(speculationFromTypedArrayType(m_currentNode->typedArrayType()));
837             break;
838         }
839             
840         case NewRegexp: {
841             setPrediction(SpecRegExpObject);
842             break;
843         }
844             
845         case CreateActivation: {
846             setPrediction(SpecObjectOther);
847             break;
848         }
849         
850         case StringFromCharCode: {
851             setPrediction(SpecString);
852             m_currentNode->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsInt);
853             break;
854         }
855         case StringCharAt:
856         case CallStringConstructor:
857         case ToString:
858         case MakeRope:
859         case StrCat: {
860             setPrediction(SpecString);
861             break;
862         }
863         case NewStringObject: {
864             setPrediction(SpecStringObject);
865             break;
866         }
867             
868         case CreateDirectArguments: {
869             setPrediction(SpecDirectArguments);
870             break;
871         }
872             
873         case CreateScopedArguments: {
874             setPrediction(SpecScopedArguments);
875             break;
876         }
877             
878         case CreateClonedArguments: {
879             setPrediction(SpecObjectOther);
880             break;
881         }
882             
883         case FiatInt52: {
884             RELEASE_ASSERT(enableInt52());
885             setPrediction(SpecAnyInt);
886             break;
887         }
888
889         case GetScope:
890             setPrediction(SpecObjectOther);
891             break;
892
893         case In:
894             setPrediction(SpecBoolean);
895             break;
896
897         case GetEnumerableLength: {
898             setPrediction(SpecInt32Only);
899             break;
900         }
901         case HasGenericProperty:
902         case HasStructureProperty:
903         case HasIndexedProperty: {
904             setPrediction(SpecBoolean);
905             break;
906         }
907         case GetPropertyEnumerator: {
908             setPrediction(SpecCell);
909             break;
910         }
911         case GetEnumeratorStructurePname: {
912             setPrediction(SpecCell | SpecOther);
913             break;
914         }
915         case GetEnumeratorGenericPname: {
916             setPrediction(SpecCell | SpecOther);
917             break;
918         }
919         case ToIndexString: {
920             setPrediction(SpecString);
921             break;
922         }
923
924         case GetLocal:
925         case SetLocal:
926         case UInt32ToNumber:
927         case ValueAdd:
928         case ArithAdd:
929         case ArithSub:
930         case ArithNegate:
931         case ArithMin:
932         case ArithMax:
933         case ArithMul:
934         case ArithDiv:
935         case ArithMod:
936         case ArithRound:
937         case ArithFloor:
938         case ArithCeil:
939         case ArithTrunc:
940         case ArithAbs:
941         case GetByVal:
942         case ToThis:
943         case ToPrimitive: {
944             m_dependentNodes.append(m_currentNode);
945             break;
946         }
947
948         case PutByValAlias:
949         case DoubleAsInt32:
950         case GetLocalUnlinked:
951         case CheckArray:
952         case CheckTypeInfoFlags:
953         case Arrayify:
954         case ArrayifyToStructure:
955         case CheckTierUpInLoop:
956         case CheckTierUpAtReturn:
957         case CheckTierUpAndOSREnter:
958         case InvalidationPoint:
959         case CheckInBounds:
960         case ValueToInt32:
961         case DoubleRep:
962         case ValueRep:
963         case Int52Rep:
964         case Int52Constant:
965         case Identity:
966         case BooleanToNumber:
967         case PhantomNewObject:
968         case PhantomNewFunction:
969         case PhantomNewGeneratorFunction:
970         case PhantomCreateActivation:
971         case PhantomDirectArguments:
972         case PhantomClonedArguments:
973         case GetMyArgumentByVal:
974         case GetMyArgumentByValOutOfBounds:
975         case ForwardVarargs:
976         case PutHint:
977         case CheckStructureImmediate:
978         case MaterializeNewObject:
979         case MaterializeCreateActivation:
980         case PutStack:
981         case KillStack:
982         case StoreBarrier:
983         case GetStack:
984         case GetRegExpObjectLastIndex:
985         case SetRegExpObjectLastIndex:
986         case RecordRegExpCachedResult:
987         case LazyJSConstant: {
988             // This node should never be visible at this stage of compilation. It is
989             // inserted by fixup(), which follows this phase.
990             DFG_CRASH(m_graph, m_currentNode, "Unexpected node during prediction propagation");
991             break;
992         }
993         
994         case Phi:
995             // Phis should not be visible here since we're iterating the all-but-Phi's
996             // part of basic blocks.
997             RELEASE_ASSERT_NOT_REACHED();
998             break;
999             
1000         case Upsilon:
1001             // These don't get inserted until we go into SSA.
1002             RELEASE_ASSERT_NOT_REACHED();
1003             break;
1004
1005 #ifndef NDEBUG
1006         // These get ignored because they don't return anything.
1007         case PutByValDirect:
1008         case PutByValWithThis:
1009         case PutByIdWithThis:
1010         case PutByVal:
1011         case PutClosureVar:
1012         case PutToArguments:
1013         case Return:
1014         case TailCall:
1015         case TailCallVarargs:
1016         case TailCallForwardVarargs:
1017         case Throw:
1018         case PutById:
1019         case PutByIdFlush:
1020         case PutByIdDirect:
1021         case PutByOffset:
1022         case MultiPutByOffset:
1023         case PutGetterById:
1024         case PutSetterById:
1025         case PutGetterSetterById:
1026         case PutGetterByVal:
1027         case PutSetterByVal:
1028         case DFG::Jump:
1029         case Branch:
1030         case Switch:
1031         case ProfileWillCall:
1032         case ProfileDidCall:
1033         case ProfileType:
1034         case ProfileControlFlow:
1035         case ThrowReferenceError:
1036         case ForceOSRExit:
1037         case SetArgument:
1038         case SetFunctionName:
1039         case CheckStructure:
1040         case CheckCell:
1041         case CheckNotEmpty:
1042         case CheckIdent:
1043         case CheckBadCell:
1044         case PutStructure:
1045         case VarInjectionWatchpoint:
1046         case Phantom:
1047         case Check:
1048         case PutGlobalVariable:
1049         case CheckWatchdogTimer:
1050         case LogShadowChickenPrologue:
1051         case LogShadowChickenTail:
1052         case Unreachable:
1053         case LoopHint:
1054         case NotifyWrite:
1055         case ConstantStoragePointer:
1056         case MovHint:
1057         case ZombieHint:
1058         case ExitOK:
1059         case LoadVarargs:
1060         case CopyRest:
1061         case PutDynamicVar:
1062             break;
1063             
1064         // This gets ignored because it only pretends to produce a value.
1065         case BottomValue:
1066             break;
1067             
1068         // This gets ignored because it already has a prediction.
1069         case ExtractOSREntryLocal:
1070             break;
1071             
1072         // These gets ignored because it doesn't do anything.
1073         case CountExecution:
1074         case PhantomLocal:
1075         case Flush:
1076             break;
1077             
1078         case LastNodeType:
1079             RELEASE_ASSERT_NOT_REACHED();
1080             break;
1081 #else
1082         default:
1083             break;
1084 #endif
1085         }
1086     }
1087
1088     SpeculatedType resultOfToPrimitive(SpeculatedType type)
1089     {
1090         if (type & SpecObject) {
1091             // We try to be optimistic here about StringObjects since it's unlikely that
1092             // someone overrides the valueOf or toString methods.
1093             if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic))
1094                 return mergeSpeculations(type & ~SpecObject, SpecString);
1095
1096             return mergeSpeculations(type & ~SpecObject, SpecPrimitive);
1097         }
1098
1099         return type;
1100     }
1101
1102     Vector<Node*> m_dependentNodes;
1103     Node* m_currentNode;
1104     bool m_changed;
1105     PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation.
1106 };
1107
1108 } // Anonymous namespace.
1109     
1110 bool performPredictionPropagation(Graph& graph)
1111 {
1112     return runPhase<PredictionPropagationPhase>(graph);
1113 }
1114
1115 } } // namespace JSC::DFG
1116
1117 #endif // ENABLE(DFG_JIT)
1118