2 * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "DFGPredictionPropagationPhase.h"
33 #include "JSCInlines.h"
35 namespace JSC { namespace DFG {
39 bool verboseFixPointLoops = false;
41 class PredictionPropagationPhase : public Phase {
43 PredictionPropagationPhase(Graph& graph)
44 : Phase(graph, "prediction propagation")
50 ASSERT(m_graph.m_form == ThreadedCPS);
51 ASSERT(m_graph.m_unificationState == GloballyUnified);
53 propagateThroughArgumentPositions();
58 propagateToFixpoint();
60 m_pass = RareCasePass;
61 propagateToFixpoint();
63 m_pass = DoubleVotingPass;
66 if (verboseFixPointLoops)
70 doRoundOfDoubleVoting();
77 if (verboseFixPointLoops)
78 dataLog("Iterated ", counter, " times in double voting fixpoint.\n");
84 void propagateToFixpoint()
88 if (verboseFixPointLoops)
93 // Forward propagation is near-optimal for both topologically-sorted and
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.
107 if (verboseFixPointLoops)
108 dataLog("Iterated ", counter, " times in propagateToFixpoint.\n");
111 bool setPrediction(SpeculatedType prediction)
113 ASSERT(m_currentNode->hasResult());
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);
121 return m_currentNode->predict(prediction);
124 bool mergePrediction(SpeculatedType prediction)
126 ASSERT(m_currentNode->hasResult());
128 return m_currentNode->predict(prediction);
131 SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
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;
143 SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right)
145 return speculatedDoubleTypeForPrediction(mergeSpeculations(left, right));
148 void propagate(Node* node)
150 NodeType op = node->op();
152 bool changed = false;
156 VariableAccessData* variable = node->variableAccessData();
157 SpeculatedType prediction = variable->prediction();
158 if (!variable->couldRepresentInt52() && (prediction & SpecInt52Only))
159 prediction = (prediction | SpecAnyIntAsDouble) & ~SpecInt52Only;
161 changed |= mergePrediction(prediction);
166 VariableAccessData* variableAccessData = node->variableAccessData();
167 changed |= variableAccessData->predict(node->child1()->prediction());
171 case UInt32ToNumber: {
172 if (node->canSpeculateInt32(m_pass))
173 changed |= mergePrediction(SpecInt32Only);
174 else if (enableInt52())
175 changed |= mergePrediction(SpecAnyInt);
177 changed |= mergePrediction(SpecBytecodeNumber);
182 SpeculatedType left = node->child1()->prediction();
183 SpeculatedType right = node->child2()->prediction();
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);
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);
198 changed |= mergePrediction(SpecInt32Only);
199 if (node->mayHaveDoubleResult())
200 changed |= mergePrediction(SpecBytecodeDouble);
201 if (node->mayHaveNonNumberResult())
202 changed |= mergePrediction(SpecString);
209 SpeculatedType left = node->child1()->prediction();
210 SpeculatedType right = node->child2()->prediction();
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);
222 changed |= mergePrediction(SpecInt32Only);
228 SpeculatedType left = node->child1()->prediction();
229 SpeculatedType right = node->child2()->prediction();
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);
239 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
240 } else if (node->mayHaveNonIntResult() || (left & SpecBytecodeDouble) || (right & SpecBytecodeDouble))
241 changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
243 changed |= mergePrediction(SpecInt32Only);
249 SpeculatedType prediction = node->child1()->prediction();
251 if (isInt32OrBooleanSpeculation(prediction) && node->canSpeculateInt32(m_pass))
252 changed |= mergePrediction(SpecInt32Only);
253 else if (m_graph.unaryArithShouldSpeculateAnyInt(node, m_pass))
254 changed |= mergePrediction(SpecInt52Only);
255 else if (isBytecodeNumberSpeculation(prediction))
256 changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
258 changed |= mergePrediction(SpecInt32Only);
259 if (node->mayHaveDoubleResult())
260 changed |= mergePrediction(SpecBytecodeDouble);
267 SpeculatedType left = node->child1()->prediction();
268 SpeculatedType right = node->child2()->prediction();
271 if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node())
272 && node->canSpeculateInt32(m_pass))
273 changed |= mergePrediction(SpecInt32Only);
275 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
281 SpeculatedType left = node->child1()->prediction();
282 SpeculatedType right = node->child2()->prediction();
285 // FIXME: We're currently relying on prediction propagation and backwards propagation
286 // whenever we can, and only falling back on result flags if that fails. And the result
287 // flags logic doesn't know how to use backwards propagation. We should get rid of the
288 // prediction propagation logic and rely solely on the result type.
289 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
290 && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
291 if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
292 changed |= mergePrediction(SpecInt32Only);
293 else if (m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
294 changed |= mergePrediction(SpecInt52Only);
296 changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
298 if (node->mayHaveNonIntResult()
299 || (left & SpecBytecodeDouble)
300 || (right & SpecBytecodeDouble))
301 changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
303 changed |= mergePrediction(SpecInt32Only);
311 SpeculatedType left = node->child1()->prediction();
312 SpeculatedType right = node->child2()->prediction();
315 if (isFullNumberOrBooleanSpeculationExpectingDefined(left)
316 && isFullNumberOrBooleanSpeculationExpectingDefined(right)) {
317 if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
318 changed |= mergePrediction(SpecInt32Only);
320 changed |= mergePrediction(SpecBytecodeDouble);
322 changed |= mergePrediction(SpecInt32Only | SpecBytecodeDouble);
328 SpeculatedType childPrediction = node->child1()->prediction();
329 if (isInt32OrBooleanSpeculation(childPrediction)
330 && node->canSpeculateInt32(m_pass))
331 changed |= mergePrediction(SpecInt32Only);
333 changed |= mergePrediction(SpecBytecodeDouble);
340 case AtomicsCompareExchange:
341 case AtomicsExchange:
347 Edge child1 = m_graph.child(node, 0);
348 if (!child1->prediction())
351 Edge child2 = m_graph.child(node, 1);
352 ArrayMode arrayMode = node->arrayMode().refine(
354 child1->prediction(),
355 child2->prediction(),
358 switch (arrayMode.type()) {
360 if (arrayMode.isOutOfBounds())
361 changed |= mergePrediction(node->getHeapPrediction() | SpecInt32Only);
363 changed |= mergePrediction(SpecInt32Only);
366 if (arrayMode.isOutOfBounds())
367 changed |= mergePrediction(node->getHeapPrediction() | SpecDoubleReal);
368 else if (node->getHeapPrediction() & SpecNonIntAsDouble)
369 changed |= mergePrediction(SpecDoubleReal);
371 changed |= mergePrediction(SpecAnyIntAsDouble);
373 case Array::Float32Array:
374 case Array::Float64Array:
375 changed |= mergePrediction(SpecFullDouble);
377 case Array::Uint32Array:
378 if (isInt32SpeculationForArithmetic(node->getHeapPrediction()) && node->op() == GetByVal)
379 changed |= mergePrediction(SpecInt32Only);
380 else if (enableInt52())
381 changed |= mergePrediction(SpecAnyInt);
383 changed |= mergePrediction(SpecInt32Only | SpecAnyIntAsDouble);
385 case Array::Int8Array:
386 case Array::Uint8Array:
387 case Array::Int16Array:
388 case Array::Uint16Array:
389 case Array::Int32Array:
390 changed |= mergePrediction(SpecInt32Only);
393 changed |= mergePrediction(node->getHeapPrediction());
400 // ToThis in methods for primitive types should speculate primitive types in strict mode.
401 ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode;
402 if (ecmaMode == StrictMode) {
403 if (node->child1()->shouldSpeculateBoolean()) {
404 changed |= mergePrediction(SpecBoolean);
408 if (node->child1()->shouldSpeculateInt32()) {
409 changed |= mergePrediction(SpecInt32Only);
413 if (enableInt52() && node->child1()->shouldSpeculateAnyInt()) {
414 changed |= mergePrediction(SpecAnyInt);
418 if (node->child1()->shouldSpeculateNumber()) {
419 changed |= mergePrediction(SpecBytecodeNumber);
423 if (node->child1()->shouldSpeculateSymbol()) {
424 changed |= mergePrediction(SpecSymbol);
428 if (node->child1()->shouldSpeculateStringIdent()) {
429 changed |= mergePrediction(SpecStringIdent);
433 if (node->child1()->shouldSpeculateString()) {
434 changed |= mergePrediction(SpecString);
438 if (node->child1()->shouldSpeculateString()) {
439 changed |= mergePrediction(SpecStringObject);
444 SpeculatedType prediction = node->child1()->prediction();
446 if (prediction & ~SpecObject) {
447 // Wrapper objects are created only in sloppy mode.
448 if (ecmaMode != StrictMode) {
449 prediction &= SpecObject;
450 prediction = mergeSpeculations(prediction, SpecObjectOther);
453 changed |= mergePrediction(prediction);
459 SpeculatedType child = node->child1()->prediction();
461 changed |= mergePrediction(resultOfToPrimitive(child));
469 m_changed |= changed;
472 void propagateForward()
474 for (Node* node : m_dependentNodes) {
475 m_currentNode = node;
476 propagate(m_currentNode);
480 void propagateBackward()
482 for (unsigned i = m_dependentNodes.size(); i--;) {
483 m_currentNode = m_dependentNodes[i];
484 propagate(m_currentNode);
488 void doDoubleVoting(Node* node, float weight)
490 // Loop pre-headers created by OSR entrypoint creation may have NaN weight to indicate
491 // that we actually don't know they weight. Assume that they execute once. This turns
492 // out to be an OK assumption since the pre-header doesn't have any meaningful code.
493 if (weight != weight)
496 switch (node->op()) {
500 SpeculatedType left = node->child1()->prediction();
501 SpeculatedType right = node->child2()->prediction();
505 if (isFullNumberSpeculation(left)
506 && isFullNumberSpeculation(right)
507 && !m_graph.addShouldSpeculateInt32(node, m_pass)
508 && !m_graph.addShouldSpeculateAnyInt(node))
513 m_graph.voteNode(node->child1(), ballot, weight);
514 m_graph.voteNode(node->child2(), ballot, weight);
519 SpeculatedType left = node->child1()->prediction();
520 SpeculatedType right = node->child2()->prediction();
524 if (isFullNumberSpeculation(left)
525 && isFullNumberSpeculation(right)
526 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass)
527 && !m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
532 m_graph.voteNode(node->child1(), ballot, weight);
533 m_graph.voteNode(node->child2(), ballot, weight);
541 SpeculatedType left = node->child1()->prediction();
542 SpeculatedType right = node->child2()->prediction();
546 if (isFullNumberSpeculation(left)
547 && isFullNumberSpeculation(right)
548 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
553 m_graph.voteNode(node->child1(), ballot, weight);
554 m_graph.voteNode(node->child2(), ballot, weight);
560 if (node->child1()->shouldSpeculateNumber()
561 && !m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
566 m_graph.voteNode(node->child1(), ballot, weight);
571 if (node->child1()->shouldSpeculateNumber())
572 m_graph.voteNode(node->child1(), VoteDouble, weight);
574 m_graph.voteNode(node->child1(), VoteValue, weight);
578 SpeculatedType prediction = node->child1()->prediction();
579 if (isDoubleSpeculation(prediction))
580 node->variableAccessData()->vote(VoteDouble, weight);
581 else if (!isFullNumberSpeculation(prediction)
582 || isInt32Speculation(prediction) || isAnyIntSpeculation(prediction))
583 node->variableAccessData()->vote(VoteValue, weight);
589 case PutByValAlias: {
590 Edge child1 = m_graph.varArgChild(node, 0);
591 Edge child2 = m_graph.varArgChild(node, 1);
592 Edge child3 = m_graph.varArgChild(node, 2);
593 m_graph.voteNode(child1, VoteValue, weight);
594 m_graph.voteNode(child2, VoteValue, weight);
595 switch (node->arrayMode().type()) {
597 m_graph.voteNode(child3, VoteDouble, weight);
600 m_graph.voteNode(child3, VoteValue, weight);
607 // Ignore these since they have no effect on in-DFG execution.
611 m_graph.voteChildren(node, VoteValue, weight);
616 void doRoundOfDoubleVoting()
618 for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
619 m_graph.m_variableAccessData[i].find()->clearVotes();
620 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
621 BasicBlock* block = m_graph.block(blockIndex);
624 ASSERT(block->isReachable);
625 for (unsigned i = 0; i < block->size(); ++i) {
626 m_currentNode = block->at(i);
627 doDoubleVoting(m_currentNode, block->executionCount);
630 for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
631 VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
632 if (!variableAccessData->isRoot())
634 m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
636 propagateThroughArgumentPositions();
637 for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
638 VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
639 if (!variableAccessData->isRoot())
641 m_changed |= variableAccessData->makePredictionForDoubleFormat();
645 void propagateThroughArgumentPositions()
647 for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
648 m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
651 // Sets any predictions that do not depends on other nodes.
652 void processInvariants()
654 for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
655 for (Node* node : *block) {
656 m_currentNode = node;
657 processInvariantsForNode();
662 void processInvariantsForNode()
664 switch (m_currentNode->op()) {
666 SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
667 if (type == SpecAnyIntAsDouble && enableInt52())
668 type = SpecInt52Only;
672 case DoubleConstant: {
673 SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
685 setPrediction(SpecInt32Only);
694 case StringReplaceRegExp:
697 case GetByIdWithThis:
699 case GetByValWithThis:
701 case MultiGetByOffset:
705 case TailCallInlinedCaller:
706 case DirectTailCallInlinedCaller:
708 case DirectConstruct:
711 case TailCallVarargsInlinedCaller:
712 case ConstructVarargs:
713 case CallForwardVarargs:
714 case ConstructForwardVarargs:
715 case TailCallForwardVarargsInlinedCaller:
717 case GetGlobalLexicalVariable:
719 case GetFromArguments:
720 case LoadKeyFromMapBucket:
721 case LoadValueFromMapBucket:
724 case CallObjectConstructor:
729 case GetPrototypeOf: {
730 setPrediction(m_currentNode->getHeapPrediction());
734 case ResolveScopeForHoistingFuncDeclInEval: {
735 setPrediction(SpecBytecodeTop);
739 case GetGetterSetterByOffset:
740 case GetExecutable: {
741 setPrediction(SpecCellOther);
749 case NewGeneratorFunction:
750 case NewAsyncGeneratorFunction:
751 case NewAsyncFunction: {
752 setPrediction(SpecFunction);
756 case GetArgumentCountIncludingThis: {
757 setPrediction(SpecInt32Only);
762 setPrediction(SpecInt32Only);
766 case GetMapBucketHead:
767 case GetMapBucketNext:
768 setPrediction(SpecCellOther);
773 setPrediction(SpecInt32Only);
777 case GetTypedArrayByteOffset:
779 case GetVectorLength: {
780 setPrediction(SpecInt32Only);
784 case StringCharCodeAt: {
785 setPrediction(SpecInt32Only);
791 setPrediction(SpecString);
798 setPrediction(SpecBytecodeDouble);
806 if (isInt32OrBooleanSpeculation(m_currentNode->getHeapPrediction())
807 && m_graph.roundShouldSpeculateInt32(m_currentNode, m_pass))
808 setPrediction(SpecInt32Only);
810 setPrediction(SpecBytecodeDouble);
815 setPrediction(SpecDoubleReal);
824 case CompareGreaterEq:
828 case CompareStrictEq:
830 case OverridesHasInstance:
832 case InstanceOfCustom:
841 case IsTypedArrayView: {
842 setPrediction(SpecBoolean);
847 setPrediction(SpecStringIdent);
851 case GetButterflyWithoutCaging:
852 case GetIndexedPropertyStorage:
853 case AllocatePropertyStorage:
854 case ReallocatePropertyStorage: {
855 setPrediction(SpecOther);
863 case GetGlobalObject: {
864 setPrediction(SpecObjectOther);
869 setPrediction(SpecObject);
873 setPrediction(SpecObjectOther);
879 setPrediction(SpecFinalObject);
884 case NewArrayWithSpread:
886 case NewArrayWithSize:
888 case NewArrayBuffer: {
889 setPrediction(SpecArray);
894 setPrediction(SpecCellOther);
897 case NewTypedArray: {
898 setPrediction(speculationFromTypedArrayType(m_currentNode->typedArrayType()));
903 setPrediction(SpecRegExpObject);
908 case CreateActivation: {
909 setPrediction(SpecObjectOther);
913 case StringFromCharCode: {
914 setPrediction(SpecString);
915 m_currentNode->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsInt);
919 case CallStringConstructor:
921 case NumberToStringWithRadix:
922 case NumberToStringWithValidRadixConstant:
925 setPrediction(SpecString);
928 case NewStringObject: {
929 setPrediction(SpecStringObject);
933 case CreateDirectArguments: {
934 setPrediction(SpecDirectArguments);
938 case CreateScopedArguments: {
939 setPrediction(SpecScopedArguments);
943 case CreateClonedArguments: {
944 setPrediction(SpecObjectOther);
949 RELEASE_ASSERT(enableInt52());
950 setPrediction(SpecAnyInt);
955 setPrediction(SpecObjectOther);
959 setPrediction(SpecBoolean);
963 setPrediction(SpecBoolean);
966 case GetEnumerableLength: {
967 setPrediction(SpecInt32Only);
970 case HasGenericProperty:
971 case HasStructureProperty:
972 case HasIndexedProperty: {
973 setPrediction(SpecBoolean);
976 case GetPropertyEnumerator: {
977 setPrediction(SpecCell);
980 case GetEnumeratorStructurePname: {
981 setPrediction(SpecCell | SpecOther);
984 case GetEnumeratorGenericPname: {
985 setPrediction(SpecCell | SpecOther);
988 case ToIndexString: {
989 setPrediction(SpecString);
993 // We expect this node to almost always produce an int32. However,
994 // it's possible it produces NaN or integers out of int32 range. We
995 // rely on the heap prediction since the parseInt() call profiled
997 setPrediction(m_currentNode->getHeapPrediction());
1001 case IdentityWithProfile: {
1002 setPrediction(m_currentNode->getForcedPrediction());
1006 case ExtractCatchLocal: {
1007 setPrediction(m_currentNode->catchLocalPrediction());
1013 case UInt32ToNumber:
1029 case AtomicsCompareExchange:
1030 case AtomicsExchange:
1036 m_dependentNodes.append(m_currentNode);
1040 case AtomicsIsLockFree: {
1041 setPrediction(SpecBoolean);
1045 case CPUIntrinsic: {
1046 if (m_currentNode->intrinsic() == CPURdtscIntrinsic)
1047 setPrediction(SpecInt32Only);
1049 setPrediction(SpecOther);
1056 case CheckTypeInfoFlags:
1058 case ArrayifyToStructure:
1059 case CheckTierUpInLoop:
1060 case CheckTierUpAtReturn:
1061 case CheckTierUpAndOSREnter:
1062 case InvalidationPoint:
1070 case BooleanToNumber:
1071 case PhantomNewObject:
1072 case PhantomNewFunction:
1073 case PhantomNewGeneratorFunction:
1074 case PhantomNewAsyncGeneratorFunction:
1075 case PhantomNewAsyncFunction:
1076 case PhantomCreateActivation:
1077 case PhantomDirectArguments:
1078 case PhantomCreateRest:
1080 case PhantomNewArrayWithSpread:
1081 case PhantomClonedArguments:
1082 case GetMyArgumentByVal:
1083 case GetMyArgumentByValOutOfBounds:
1085 case CheckStructureImmediate:
1086 case CheckStructureOrEmpty:
1087 case MaterializeNewObject:
1088 case MaterializeCreateActivation:
1092 case FencedStoreBarrier:
1094 case GetRegExpObjectLastIndex:
1095 case SetRegExpObjectLastIndex:
1096 case RecordRegExpCachedResult:
1097 case LazyJSConstant:
1099 // This node should never be visible at this stage of compilation.
1100 DFG_CRASH(m_graph, m_currentNode, "Unexpected node during prediction propagation");
1105 // Phis should not be visible here since we're iterating the all-but-Phi's
1106 // part of basic blocks.
1107 RELEASE_ASSERT_NOT_REACHED();
1112 // These don't get inserted until we go into SSA.
1113 RELEASE_ASSERT_NOT_REACHED();
1117 // These get ignored because they don't return anything.
1118 case PutByValDirect:
1119 case PutByValWithThis:
1120 case PutByIdWithThis:
1123 case PutToArguments:
1126 case ThrowStaticError:
1128 case DirectTailCall:
1129 case TailCallVarargs:
1130 case TailCallForwardVarargs:
1135 case MultiPutByOffset:
1138 case PutGetterSetterById:
1139 case PutGetterByVal:
1140 case PutSetterByVal:
1141 case DefineDataProperty:
1142 case DefineAccessorProperty:
1147 case ProfileControlFlow:
1150 case SetFunctionName:
1151 case CheckStructure:
1154 case CheckStringIdent:
1159 case PutGlobalVariable:
1161 case LogShadowChickenPrologue:
1162 case LogShadowChickenTail:
1166 case ConstantStoragePointer:
1171 case ForwardVarargs:
1173 case NukeStructureAndSetButterfly:
1174 case InitializeEntrypointArguments:
1179 // This gets ignored because it only pretends to produce a value.
1183 // This gets ignored because it already has a prediction.
1184 case ExtractOSREntryLocal:
1187 // These gets ignored because it doesn't do anything.
1188 case CountExecution:
1189 case SuperSamplerBegin:
1190 case SuperSamplerEnd:
1196 RELEASE_ASSERT_NOT_REACHED();
1205 SpeculatedType resultOfToPrimitive(SpeculatedType type)
1207 if (type & SpecObject) {
1208 // We try to be optimistic here about StringObjects since it's unlikely that
1209 // someone overrides the valueOf or toString methods.
1210 if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic))
1211 return mergeSpeculations(type & ~SpecObject, SpecString);
1213 return mergeSpeculations(type & ~SpecObject, SpecPrimitive);
1219 Vector<Node*> m_dependentNodes;
1220 Node* m_currentNode;
1222 PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation.
1225 } // Anonymous namespace.
1227 bool performPredictionPropagation(Graph& graph)
1229 return runPhase<PredictionPropagationPhase>(graph);
1232 } } // namespace JSC::DFG
1234 #endif // ENABLE(DFG_JIT)