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));
465 case NormalizeMapKey: {
466 SpeculatedType prediction = node->child1()->prediction();
468 changed |= mergePrediction(prediction);
476 m_changed |= changed;
479 void propagateForward()
481 for (Node* node : m_dependentNodes) {
482 m_currentNode = node;
483 propagate(m_currentNode);
487 void propagateBackward()
489 for (unsigned i = m_dependentNodes.size(); i--;) {
490 m_currentNode = m_dependentNodes[i];
491 propagate(m_currentNode);
495 void doDoubleVoting(Node* node, float weight)
497 // Loop pre-headers created by OSR entrypoint creation may have NaN weight to indicate
498 // that we actually don't know they weight. Assume that they execute once. This turns
499 // out to be an OK assumption since the pre-header doesn't have any meaningful code.
500 if (weight != weight)
503 switch (node->op()) {
507 SpeculatedType left = node->child1()->prediction();
508 SpeculatedType right = node->child2()->prediction();
512 if (isFullNumberSpeculation(left)
513 && isFullNumberSpeculation(right)
514 && !m_graph.addShouldSpeculateInt32(node, m_pass)
515 && !m_graph.addShouldSpeculateAnyInt(node))
520 m_graph.voteNode(node->child1(), ballot, weight);
521 m_graph.voteNode(node->child2(), ballot, weight);
526 SpeculatedType left = node->child1()->prediction();
527 SpeculatedType right = node->child2()->prediction();
531 if (isFullNumberSpeculation(left)
532 && isFullNumberSpeculation(right)
533 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass)
534 && !m_graph.binaryArithShouldSpeculateAnyInt(node, m_pass))
539 m_graph.voteNode(node->child1(), ballot, weight);
540 m_graph.voteNode(node->child2(), ballot, weight);
548 SpeculatedType left = node->child1()->prediction();
549 SpeculatedType right = node->child2()->prediction();
553 if (isFullNumberSpeculation(left)
554 && isFullNumberSpeculation(right)
555 && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass))
560 m_graph.voteNode(node->child1(), ballot, weight);
561 m_graph.voteNode(node->child2(), ballot, weight);
567 if (node->child1()->shouldSpeculateNumber()
568 && !m_graph.unaryArithShouldSpeculateInt32(node, m_pass))
573 m_graph.voteNode(node->child1(), ballot, weight);
578 if (node->child1()->shouldSpeculateNumber())
579 m_graph.voteNode(node->child1(), VoteDouble, weight);
581 m_graph.voteNode(node->child1(), VoteValue, weight);
585 SpeculatedType prediction = node->child1()->prediction();
586 if (isDoubleSpeculation(prediction))
587 node->variableAccessData()->vote(VoteDouble, weight);
588 else if (!isFullNumberSpeculation(prediction)
589 || isInt32Speculation(prediction) || isAnyIntSpeculation(prediction))
590 node->variableAccessData()->vote(VoteValue, weight);
596 case PutByValAlias: {
597 Edge child1 = m_graph.varArgChild(node, 0);
598 Edge child2 = m_graph.varArgChild(node, 1);
599 Edge child3 = m_graph.varArgChild(node, 2);
600 m_graph.voteNode(child1, VoteValue, weight);
601 m_graph.voteNode(child2, VoteValue, weight);
602 switch (node->arrayMode().type()) {
604 m_graph.voteNode(child3, VoteDouble, weight);
607 m_graph.voteNode(child3, VoteValue, weight);
614 // Ignore these since they have no effect on in-DFG execution.
618 m_graph.voteChildren(node, VoteValue, weight);
623 void doRoundOfDoubleVoting()
625 for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
626 m_graph.m_variableAccessData[i].find()->clearVotes();
627 for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
628 BasicBlock* block = m_graph.block(blockIndex);
631 ASSERT(block->isReachable);
632 for (unsigned i = 0; i < block->size(); ++i) {
633 m_currentNode = block->at(i);
634 doDoubleVoting(m_currentNode, block->executionCount);
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->tallyVotesForShouldUseDoubleFormat();
643 propagateThroughArgumentPositions();
644 for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
645 VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
646 if (!variableAccessData->isRoot())
648 m_changed |= variableAccessData->makePredictionForDoubleFormat();
652 void propagateThroughArgumentPositions()
654 for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
655 m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
658 // Sets any predictions that do not depends on other nodes.
659 void processInvariants()
661 for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
662 for (Node* node : *block) {
663 m_currentNode = node;
664 processInvariantsForNode();
669 void processInvariantsForNode()
671 switch (m_currentNode->op()) {
673 SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
674 if (type == SpecAnyIntAsDouble && enableInt52())
675 type = SpecInt52Only;
679 case DoubleConstant: {
680 SpeculatedType type = speculationFromValue(m_currentNode->asJSValue());
692 setPrediction(SpecInt32Only);
701 case StringReplaceRegExp:
704 case GetByIdWithThis:
706 case GetByValWithThis:
708 case MultiGetByOffset:
712 case TailCallInlinedCaller:
713 case DirectTailCallInlinedCaller:
715 case DirectConstruct:
718 case TailCallVarargsInlinedCaller:
719 case ConstructVarargs:
720 case CallForwardVarargs:
721 case ConstructForwardVarargs:
722 case TailCallForwardVarargsInlinedCaller:
724 case GetGlobalLexicalVariable:
726 case GetFromArguments:
727 case LoadKeyFromMapBucket:
728 case LoadValueFromMapBucket:
731 case CallObjectConstructor:
736 case ExtractValueFromWeakMapGet: {
737 setPrediction(m_currentNode->getHeapPrediction());
742 case ResolveScopeForHoistingFuncDeclInEval: {
743 setPrediction(SpecBytecodeTop);
747 case GetGetterSetterByOffset:
748 case GetExecutable: {
749 setPrediction(SpecCellOther);
757 case NewGeneratorFunction:
758 case NewAsyncGeneratorFunction:
759 case NewAsyncFunction: {
760 setPrediction(SpecFunction);
764 case GetArgumentCountIncludingThis: {
765 setPrediction(SpecInt32Only);
770 setPrediction(SpecInt32Only);
774 case GetMapBucketHead:
775 case GetMapBucketNext:
776 setPrediction(SpecCellOther);
781 setPrediction(SpecInt32Only);
785 case GetTypedArrayByteOffset:
787 case GetVectorLength: {
788 setPrediction(SpecInt32Only);
792 case StringCharCodeAt: {
793 setPrediction(SpecInt32Only);
799 setPrediction(SpecString);
806 setPrediction(SpecBytecodeDouble);
814 if (isInt32OrBooleanSpeculation(m_currentNode->getHeapPrediction())
815 && m_graph.roundShouldSpeculateInt32(m_currentNode, m_pass))
816 setPrediction(SpecInt32Only);
818 setPrediction(SpecBytecodeDouble);
823 setPrediction(SpecDoubleReal);
832 case CompareGreaterEq:
836 case CompareStrictEq:
838 case OverridesHasInstance:
840 case InstanceOfCustom:
849 case IsTypedArrayView: {
850 setPrediction(SpecBoolean);
855 setPrediction(SpecStringIdent);
859 case GetIndexedPropertyStorage:
860 case AllocatePropertyStorage:
861 case ReallocatePropertyStorage: {
862 setPrediction(SpecOther);
870 case GetGlobalObject: {
871 setPrediction(SpecObjectOther);
876 setPrediction(SpecObject);
880 setPrediction(SpecObjectOther);
886 setPrediction(SpecFinalObject);
891 case NewArrayWithSpread:
893 case NewArrayWithSize:
895 case NewArrayBuffer: {
896 setPrediction(SpecArray);
901 setPrediction(SpecCellOther);
904 case NewTypedArray: {
905 setPrediction(speculationFromTypedArrayType(m_currentNode->typedArrayType()));
910 setPrediction(SpecRegExpObject);
915 case CreateActivation: {
916 setPrediction(SpecObjectOther);
920 case StringFromCharCode: {
921 setPrediction(SpecString);
922 m_currentNode->child1()->mergeFlags(NodeBytecodeUsesAsNumber | NodeBytecodeUsesAsInt);
926 case CallStringConstructor:
928 case NumberToStringWithRadix:
929 case NumberToStringWithValidRadixConstant:
932 setPrediction(SpecString);
935 case NewStringObject: {
936 setPrediction(SpecStringObject);
940 case CreateDirectArguments: {
941 setPrediction(SpecDirectArguments);
945 case CreateScopedArguments: {
946 setPrediction(SpecScopedArguments);
950 case CreateClonedArguments: {
951 setPrediction(SpecObjectOther);
956 RELEASE_ASSERT(enableInt52());
957 setPrediction(SpecAnyInt);
962 setPrediction(SpecObjectOther);
966 setPrediction(SpecBoolean);
970 setPrediction(SpecBoolean);
973 case GetEnumerableLength: {
974 setPrediction(SpecInt32Only);
977 case HasGenericProperty:
978 case HasStructureProperty:
979 case HasIndexedProperty: {
980 setPrediction(SpecBoolean);
983 case GetPropertyEnumerator: {
984 setPrediction(SpecCell);
987 case GetEnumeratorStructurePname: {
988 setPrediction(SpecCell | SpecOther);
991 case GetEnumeratorGenericPname: {
992 setPrediction(SpecCell | SpecOther);
995 case ToIndexString: {
996 setPrediction(SpecString);
1000 // We expect this node to almost always produce an int32. However,
1001 // it's possible it produces NaN or integers out of int32 range. We
1002 // rely on the heap prediction since the parseInt() call profiled
1004 setPrediction(m_currentNode->getHeapPrediction());
1008 case IdentityWithProfile: {
1009 setPrediction(m_currentNode->getForcedPrediction());
1013 case ExtractCatchLocal: {
1014 setPrediction(m_currentNode->catchLocalPrediction());
1020 case UInt32ToNumber:
1034 case NormalizeMapKey:
1037 case AtomicsCompareExchange:
1038 case AtomicsExchange:
1044 m_dependentNodes.append(m_currentNode);
1048 case AtomicsIsLockFree: {
1049 setPrediction(SpecBoolean);
1053 case CPUIntrinsic: {
1054 if (m_currentNode->intrinsic() == CPURdtscIntrinsic)
1055 setPrediction(SpecInt32Only);
1057 setPrediction(SpecOther);
1064 case CheckTypeInfoFlags:
1066 case ArrayifyToStructure:
1067 case CheckTierUpInLoop:
1068 case CheckTierUpAtReturn:
1069 case CheckTierUpAndOSREnter:
1070 case InvalidationPoint:
1078 case BooleanToNumber:
1079 case PhantomNewObject:
1080 case PhantomNewFunction:
1081 case PhantomNewGeneratorFunction:
1082 case PhantomNewAsyncGeneratorFunction:
1083 case PhantomNewAsyncFunction:
1084 case PhantomCreateActivation:
1085 case PhantomDirectArguments:
1086 case PhantomCreateRest:
1088 case PhantomNewArrayWithSpread:
1089 case PhantomNewArrayBuffer:
1090 case PhantomClonedArguments:
1091 case GetMyArgumentByVal:
1092 case GetMyArgumentByValOutOfBounds:
1094 case CheckStructureImmediate:
1095 case CheckStructureOrEmpty:
1096 case MaterializeNewObject:
1097 case MaterializeCreateActivation:
1101 case FencedStoreBarrier:
1103 case GetRegExpObjectLastIndex:
1104 case SetRegExpObjectLastIndex:
1105 case RecordRegExpCachedResult:
1106 case LazyJSConstant:
1108 // This node should never be visible at this stage of compilation.
1109 DFG_CRASH(m_graph, m_currentNode, "Unexpected node during prediction propagation");
1114 // Phis should not be visible here since we're iterating the all-but-Phi's
1115 // part of basic blocks.
1116 RELEASE_ASSERT_NOT_REACHED();
1121 // These don't get inserted until we go into SSA.
1122 RELEASE_ASSERT_NOT_REACHED();
1126 // These get ignored because they don't return anything.
1127 case PutByValDirect:
1128 case PutByValWithThis:
1129 case PutByIdWithThis:
1132 case PutToArguments:
1135 case ThrowStaticError:
1137 case DirectTailCall:
1138 case TailCallVarargs:
1139 case TailCallForwardVarargs:
1144 case MultiPutByOffset:
1147 case PutGetterSetterById:
1148 case PutGetterByVal:
1149 case PutSetterByVal:
1150 case DefineDataProperty:
1151 case DefineAccessorProperty:
1156 case ProfileControlFlow:
1159 case SetFunctionName:
1160 case CheckStructure:
1163 case CheckStringIdent:
1168 case PutGlobalVariable:
1170 case LogShadowChickenPrologue:
1171 case LogShadowChickenTail:
1175 case ConstantStoragePointer:
1180 case ForwardVarargs:
1182 case NukeStructureAndSetButterfly:
1183 case InitializeEntrypointArguments:
1188 // This gets ignored because it only pretends to produce a value.
1192 // This gets ignored because it already has a prediction.
1193 case ExtractOSREntryLocal:
1196 // These gets ignored because it doesn't do anything.
1197 case CountExecution:
1198 case SuperSamplerBegin:
1199 case SuperSamplerEnd:
1205 RELEASE_ASSERT_NOT_REACHED();
1214 SpeculatedType resultOfToPrimitive(SpeculatedType type)
1216 if (type & SpecObject) {
1217 // We try to be optimistic here about StringObjects since it's unlikely that
1218 // someone overrides the valueOf or toString methods.
1219 if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic))
1220 return mergeSpeculations(type & ~SpecObject, SpecString);
1222 return mergeSpeculations(type & ~SpecObject, SpecPrimitive);
1228 Vector<Node*> m_dependentNodes;
1229 Node* m_currentNode;
1231 PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation.
1234 } // Anonymous namespace.
1236 bool performPredictionPropagation(Graph& graph)
1238 return runPhase<PredictionPropagationPhase>(graph);
1241 } } // namespace JSC::DFG
1243 #endif // ENABLE(DFG_JIT)