diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp | 609 |
1 files changed, 192 insertions, 417 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp index 9283ae302..d859849a3 100644 --- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2016 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,10 +30,21 @@ #include "DFGGraph.h" #include "DFGPhase.h" -#include "JSCInlines.h" +#include "Operations.h" namespace JSC { namespace DFG { +SpeculatedType resultOfToPrimitive(SpeculatedType type) +{ + if (type & SpecObject) { + // Objects get turned into strings. So if the input has hints of objectness, + // the output will have hinsts of stringiness. + return mergeSpeculations(type & ~SpecObject, SpecString); + } + + return type; +} + class PredictionPropagationPhase : public Phase { public: PredictionPropagationPhase(Graph& graph) @@ -45,31 +56,9 @@ public: { ASSERT(m_graph.m_form == ThreadedCPS); ASSERT(m_graph.m_unificationState == GloballyUnified); - - propagateThroughArgumentPositions(); - - m_pass = PrimaryPass; - propagateToFixpoint(); - m_pass = RareCasePass; - propagateToFixpoint(); - - m_pass = DoubleVotingPass; - do { - m_changed = false; - doRoundOfDoubleVoting(); - if (!m_changed) - break; - m_changed = false; - propagateForward(); - } while (m_changed); - - return true; - } - -private: - void propagateToFixpoint() - { + // 1) propagate predictions + do { m_changed = false; @@ -86,8 +75,22 @@ private: m_changed = false; propagateBackward(); } while (m_changed); + + // 2) repropagate predictions while doing double voting. + + do { + m_changed = false; + doRoundOfDoubleVoting(); + if (!m_changed) + break; + m_changed = false; + propagateForward(); + } while (m_changed); + + return true; } +private: bool setPrediction(SpeculatedType prediction) { ASSERT(m_currentNode->hasResult()); @@ -110,14 +113,11 @@ private: SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value) { - SpeculatedType result = SpecDoubleReal; - if (value & SpecDoubleImpureNaN) - result |= SpecDoubleImpureNaN; - if (value & SpecDoublePureNaN) - result |= SpecDoublePureNaN; - if (!isFullNumberOrBooleanSpeculation(value)) - result |= SpecDoublePureNaN; - return result; + if (!isFullNumberSpeculation(value)) + return SpecDouble; + if (value & SpecDoubleNaN) + return SpecDouble; + return SpecDoubleReal; } SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right) @@ -132,23 +132,19 @@ private: bool changed = false; switch (op) { - case JSConstant: { - SpeculatedType type = speculationFromValue(node->asJSValue()); - if (type == SpecInt52AsDouble && enableInt52()) + case JSConstant: + case WeakJSConstant: { + SpeculatedType type = speculationFromValue(m_graph.valueOfJSConstant(node)); + if (type == SpecInt52AsDouble) type = SpecInt52; changed |= setPrediction(type); break; } - case DoubleConstant: { - SpeculatedType type = speculationFromValue(node->asJSValue()); - changed |= setPrediction(type); - break; - } case GetLocal: { VariableAccessData* variable = node->variableAccessData(); SpeculatedType prediction = variable->prediction(); - if (!variable->couldRepresentInt52() && (prediction & SpecInt52)) + if (variable->shouldNeverUnbox() && (prediction & SpecInt52)) prediction = (prediction | SpecInt52AsDouble) & ~SpecInt52; if (prediction) changed |= mergePrediction(prediction); @@ -167,8 +163,7 @@ private: case BitRShift: case BitLShift: case BitURShift: - case ArithIMul: - case ArithClz32: { + case ArithIMul: { changed |= setPrediction(SpecInt32); break; } @@ -177,60 +172,17 @@ private: case ArrayPush: case RegExpExec: case RegExpTest: - case StringReplace: case GetById: case GetByIdFlush: + case GetMyArgumentByValSafe: case GetByOffset: - case MultiGetByOffset: - case GetDirectPname: case Call: - case TailCallInlinedCaller: case Construct: - case CallVarargs: - case TailCallVarargsInlinedCaller: - case ConstructVarargs: - case CallForwardVarargs: - case ConstructForwardVarargs: - case TailCallForwardVarargsInlinedCaller: case GetGlobalVar: - case GetGlobalLexicalVariable: - case GetClosureVar: - case GetFromArguments: { + case GetClosureVar: { changed |= setPrediction(node->getHeapPrediction()); break; } - - case GetGetterSetterByOffset: - case GetExecutable: { - changed |= setPrediction(SpecCellOther); - break; - } - - case GetGetter: - case GetSetter: - case GetCallee: - case NewArrowFunction: - case NewFunction: - case NewGeneratorFunction: { - changed |= setPrediction(SpecFunction); - break; - } - - case GetArgumentCount: { - changed |= setPrediction(SpecInt32); - break; - } - - case GetRestLength: { - changed |= setPrediction(SpecInt32); - break; - } - - case GetTypedArrayByteOffset: - case GetArrayLength: { - changed |= setPrediction(SpecInt32); - break; - } case StringCharCodeAt: { changed |= setPrediction(SpecInt32); @@ -240,7 +192,7 @@ private: case UInt32ToNumber: { // FIXME: Support Int52. // https://bugs.webkit.org/show_bug.cgi?id=125704 - if (node->canSpeculateInt32(m_pass)) + if (nodeCanSpeculateInt32(node->arithNodeFlags())) changed |= mergePrediction(SpecInt32); else changed |= mergePrediction(SpecBytecodeNumber); @@ -252,31 +204,28 @@ private: SpeculatedType right = node->child2()->prediction(); if (left && right) { - if (isFullNumberOrBooleanSpeculationExpectingDefined(left) - && isFullNumberOrBooleanSpeculationExpectingDefined(right)) { - if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32) + if (isFullNumberSpeculationExpectingDefined(left) && isFullNumberSpeculationExpectingDefined(right)) { + if (m_graph.addSpeculationMode(node) != DontSpeculateInt32) changed |= mergePrediction(SpecInt32); else if (m_graph.addShouldSpeculateMachineInt(node)) changed |= mergePrediction(SpecInt52); else changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); - } else if ( - !(left & (SpecFullNumber | SpecBoolean)) - || !(right & (SpecFullNumber | SpecBoolean))) { + } else if (!(left & SpecFullNumber) || !(right & SpecFullNumber)) { // left or right is definitely something other than a number. changed |= mergePrediction(SpecString); } else - changed |= mergePrediction(SpecString | SpecInt32 | SpecBytecodeDouble); + changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble); } break; } - + case ArithAdd: { SpeculatedType left = node->child1()->prediction(); SpeculatedType right = node->child2()->prediction(); if (left && right) { - if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32) + if (m_graph.addSpeculationMode(node) != DontSpeculateInt32) changed |= mergePrediction(SpecInt32); else if (m_graph.addShouldSpeculateMachineInt(node)) changed |= mergePrediction(SpecInt52); @@ -289,27 +238,23 @@ private: case ArithSub: { SpeculatedType left = node->child1()->prediction(); SpeculatedType right = node->child2()->prediction(); - + if (left && right) { - if (isFullNumberOrBooleanSpeculationExpectingDefined(left) - && isFullNumberOrBooleanSpeculationExpectingDefined(right)) { - if (m_graph.addSpeculationMode(node, m_pass) != DontSpeculateInt32) - changed |= mergePrediction(SpecInt32); - else if (m_graph.addShouldSpeculateMachineInt(node)) - changed |= mergePrediction(SpecInt52); - else - changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); - } else - changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble); + if (m_graph.addSpeculationMode(node) != DontSpeculateInt32) + changed |= mergePrediction(SpecInt32); + else if (m_graph.addShouldSpeculateMachineInt(node)) + changed |= mergePrediction(SpecInt52); + else + changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); } break; } - + case ArithNegate: if (node->child1()->prediction()) { - if (m_graph.unaryArithShouldSpeculateInt32(node, m_pass)) + if (m_graph.negateShouldSpeculateInt32(node)) changed |= mergePrediction(SpecInt32); - else if (m_graph.unaryArithShouldSpeculateMachineInt(node, m_pass)) + else if (m_graph.negateShouldSpeculateMachineInt(node)) changed |= mergePrediction(SpecInt52); else changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction())); @@ -322,8 +267,8 @@ private: SpeculatedType right = node->child2()->prediction(); if (left && right) { - if (Node::shouldSpeculateInt32OrBooleanForArithmetic(node->child1().node(), node->child2().node()) - && node->canSpeculateInt32(m_pass)) + if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node()) + && nodeCanSpeculateInt32(node->arithNodeFlags())) changed |= mergePrediction(SpecInt32); else changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); @@ -336,71 +281,55 @@ private: SpeculatedType right = node->child2()->prediction(); if (left && right) { - if (isFullNumberOrBooleanSpeculationExpectingDefined(left) - && isFullNumberOrBooleanSpeculationExpectingDefined(right)) { - if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass)) - changed |= mergePrediction(SpecInt32); - else if (m_graph.binaryArithShouldSpeculateMachineInt(node, m_pass)) - changed |= mergePrediction(SpecInt52); - else - changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); - } else { - if (node->mayHaveNonIntResult()) - changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble); - else - changed |= mergePrediction(SpecInt32); - } + if (m_graph.mulShouldSpeculateInt32(node)) + changed |= mergePrediction(SpecInt32); + else if (m_graph.mulShouldSpeculateMachineInt(node)) + changed |= mergePrediction(SpecInt52); + else + changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right)); } break; } - - case ArithDiv: + + case ArithDiv: { + SpeculatedType left = node->child1()->prediction(); + SpeculatedType right = node->child2()->prediction(); + + if (left && right) { + if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node()) + && nodeCanSpeculateInt32(node->arithNodeFlags())) + changed |= mergePrediction(SpecInt32); + else + changed |= mergePrediction(SpecDouble); + } + break; + } + case ArithMod: { SpeculatedType left = node->child1()->prediction(); SpeculatedType right = node->child2()->prediction(); if (left && right) { - if (isFullNumberOrBooleanSpeculationExpectingDefined(left) - && isFullNumberOrBooleanSpeculationExpectingDefined(right)) { - if (m_graph.binaryArithShouldSpeculateInt32(node, m_pass)) - changed |= mergePrediction(SpecInt32); - else - changed |= mergePrediction(SpecBytecodeDouble); - } else - changed |= mergePrediction(SpecInt32 | SpecBytecodeDouble); + if (Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node()) + && nodeCanSpeculateInt32(node->arithNodeFlags())) + changed |= mergePrediction(SpecInt32); + else + changed |= mergePrediction(SpecDouble); } break; } - - case ArithPow: + case ArithSqrt: - case ArithFRound: case ArithSin: - case ArithCos: - case ArithLog: { - changed |= setPrediction(SpecBytecodeDouble); - break; - } - - case ArithRandom: { - changed |= setPrediction(SpecDoubleReal); - break; - } - - case ArithRound: - case ArithFloor: - case ArithCeil: { - if (isInt32OrBooleanSpeculation(node->getHeapPrediction()) && m_graph.roundShouldSpeculateInt32(node, m_pass)) - changed |= setPrediction(SpecInt32); - else - changed |= setPrediction(SpecBytecodeDouble); + case ArithCos: { + changed |= setPrediction(SpecDouble); break; } - + case ArithAbs: { SpeculatedType child = node->child1()->prediction(); - if (isInt32OrBooleanSpeculationForArithmetic(child) - && node->canSpeculateInt32(m_pass)) + if (isInt32SpeculationForArithmetic(child) + && nodeCanSpeculateInt32(node->arithNodeFlags())) changed |= mergePrediction(SpecInt32); else changed |= mergePrediction(speculatedDoubleTypeForPrediction(child)); @@ -413,77 +342,51 @@ private: case CompareGreater: case CompareGreaterEq: case CompareEq: + case CompareEqConstant: case CompareStrictEq: - case OverridesHasInstance: + case CompareStrictEqConstant: case InstanceOf: - case InstanceOfCustom: case IsUndefined: case IsBoolean: case IsNumber: case IsString: case IsObject: - case IsObjectOrNull: case IsFunction: { changed |= setPrediction(SpecBoolean); break; } case TypeOf: { - changed |= setPrediction(SpecStringIdent); + changed |= setPrediction(SpecString); break; } case GetByVal: { if (!node->child1()->prediction()) break; - - ArrayMode arrayMode = node->arrayMode().refine( - m_graph, node, - node->child1()->prediction(), - node->child2()->prediction(), - SpecNone); - - switch (arrayMode.type()) { - case Array::Int32: - if (arrayMode.isOutOfBounds()) - changed |= mergePrediction(node->getHeapPrediction() | SpecInt32); - else - changed |= mergePrediction(SpecInt32); - break; - case Array::Double: - if (arrayMode.isOutOfBounds()) - changed |= mergePrediction(node->getHeapPrediction() | SpecDoubleReal); - else - changed |= mergePrediction(SpecDoubleReal); + if (!node->getHeapPrediction()) break; - case Array::Float32Array: - case Array::Float64Array: - changed |= mergePrediction(SpecFullDouble); - break; - case Array::Uint32Array: - if (isInt32SpeculationForArithmetic(node->getHeapPrediction())) + + if (node->child1()->shouldSpeculateFloat32Array() + || node->child1()->shouldSpeculateFloat64Array()) + changed |= mergePrediction(SpecDouble); + else if (node->child1()->shouldSpeculateUint32Array()) { + if (isInt32Speculation(node->getHeapPrediction())) changed |= mergePrediction(SpecInt32); - else if (enableInt52()) - changed |= mergePrediction(SpecMachineInt); else - changed |= mergePrediction(SpecInt32 | SpecInt52AsDouble); - break; - case Array::Int8Array: - case Array::Uint8Array: - case Array::Int16Array: - case Array::Uint16Array: - case Array::Int32Array: - changed |= mergePrediction(SpecInt32); - break; - default: + changed |= mergePrediction(SpecInt52); + } else changed |= mergePrediction(node->getHeapPrediction()); - break; - } break; } - case GetButterfly: - case GetButterflyReadOnly: + case GetMyArgumentsLengthSafe: { + changed |= setPrediction(SpecInt32); + break; + } + + case GetClosureRegisters: + case GetButterfly: case GetIndexedPropertyStorage: case AllocatePropertyStorage: case ReallocatePropertyStorage: { @@ -492,69 +395,29 @@ private: } case ToThis: { - // ToThis in methods for primitive types should speculate primitive types in strict mode. - ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->isStrictMode() ? StrictMode : NotStrictMode; - if (ecmaMode == StrictMode) { - if (node->child1()->shouldSpeculateBoolean()) { - changed |= mergePrediction(SpecBoolean); - break; - } - - if (node->child1()->shouldSpeculateInt32()) { - changed |= mergePrediction(SpecInt32); - break; - } - - if (enableInt52() && node->child1()->shouldSpeculateMachineInt()) { - changed |= mergePrediction(SpecMachineInt); - break; - } - - if (node->child1()->shouldSpeculateNumber()) { - changed |= mergePrediction(SpecMachineInt); - break; - } - - if (node->child1()->shouldSpeculateSymbol()) { - changed |= mergePrediction(SpecSymbol); - break; - } - - if (node->child1()->shouldSpeculateStringIdent()) { - changed |= mergePrediction(SpecStringIdent); - break; - } - - if (node->child1()->shouldSpeculateString()) { - changed |= mergePrediction(SpecString); - break; - } - } else { - if (node->child1()->shouldSpeculateString()) { - changed |= mergePrediction(SpecStringObject); - break; - } - } - SpeculatedType prediction = node->child1()->prediction(); if (prediction) { if (prediction & ~SpecObject) { - // Wrapper objects are created only in sloppy mode. - if (ecmaMode != StrictMode) { - prediction &= SpecObject; - prediction = mergeSpeculations(prediction, SpecObjectOther); - } + prediction &= SpecObject; + prediction = mergeSpeculations(prediction, SpecObjectOther); } changed |= mergePrediction(prediction); } break; } + case GetMyScope: + case SkipTopScope: case SkipScope: { changed |= setPrediction(SpecObjectOther); break; } + case GetCallee: { + changed |= setPrediction(SpecFunction); + break; + } + case CreateThis: case NewObject: { changed |= setPrediction(SpecFinalObject); @@ -573,11 +436,7 @@ private: break; } - case NewRegexp: { - changed |= setPrediction(SpecRegExpObject); - break; - } - + case NewRegexp: case CreateActivation: { changed |= setPrediction(SpecObjectOther); break; @@ -589,10 +448,8 @@ private: break; } case StringCharAt: - case CallStringConstructor: case ToString: - case MakeRope: - case StrCat: { + case MakeRope: { changed |= setPrediction(SpecString); break; } @@ -609,66 +466,50 @@ private: break; } - case CreateDirectArguments: { - changed |= setPrediction(SpecDirectArguments); + case CreateArguments: { + changed |= setPrediction(SpecArguments); break; } - case CreateScopedArguments: { - changed |= setPrediction(SpecScopedArguments); + case NewFunction: { + SpeculatedType child = node->child1()->prediction(); + if (child & SpecEmpty) + changed |= mergePrediction((child & ~SpecEmpty) | SpecFunction); + else + changed |= mergePrediction(child); break; } - case CreateClonedArguments: { - changed |= setPrediction(SpecObjectOther); + case NewFunctionNoCheck: + case NewFunctionExpression: { + changed |= setPrediction(SpecFunction); break; } - case FiatInt52: { - RELEASE_ASSERT(enableInt52()); - changed |= setPrediction(SpecMachineInt); - break; - } - case PutByValAlias: + case GetArrayLength: + case GetTypedArrayByteOffset: + case Int32ToDouble: case DoubleAsInt32: case GetLocalUnlinked: + case GetMyArgumentsLength: + case GetMyArgumentByVal: + case PhantomPutStructure: + case PhantomArguments: case CheckArray: - case CheckTypeInfoFlags: case Arrayify: case ArrayifyToStructure: case CheckTierUpInLoop: case CheckTierUpAtReturn: case CheckTierUpAndOSREnter: - case CheckTierUpWithNestedTriggerAndOSREnter: case InvalidationPoint: + case Int52ToValue: + case Int52ToDouble: case CheckInBounds: - case ValueToInt32: - case DoubleRep: - case ValueRep: - case Int52Rep: - case Int52Constant: - case Identity: - case BooleanToNumber: - case PhantomNewObject: - case PhantomNewFunction: - case PhantomNewGeneratorFunction: - case PhantomCreateActivation: - case PhantomDirectArguments: - case PhantomClonedArguments: - case GetMyArgumentByVal: - case ForwardVarargs: - case PutHint: - case CheckStructureImmediate: - case MaterializeNewObject: - case MaterializeCreateActivation: - case PutStack: - case KillStack: - case StoreBarrier: - case GetStack: { + case ValueToInt32: { // This node should never be visible at this stage of compilation. It is // inserted by fixup(), which follows this phase. - DFG_CRASH(m_graph, node, "Unexpected node during prediction propagation"); + RELEASE_ASSERT_NOT_REACHED(); break; } @@ -679,101 +520,69 @@ private: break; case Upsilon: + case GetArgument: // These don't get inserted until we go into SSA. RELEASE_ASSERT_NOT_REACHED(); break; - + case GetScope: changed |= setPrediction(SpecObjectOther); break; - + case In: changed |= setPrediction(SpecBoolean); break; - case GetEnumerableLength: { - changed |= setPrediction(SpecInt32); - break; - } - case HasGenericProperty: - case HasStructureProperty: - case HasIndexedProperty: { - changed |= setPrediction(SpecBoolean); - break; - } - case GetPropertyEnumerator: { - changed |= setPrediction(SpecCell); - break; - } - case GetEnumeratorStructurePname: { - changed |= setPrediction(SpecCell | SpecOther); - break; - } - case GetEnumeratorGenericPname: { - changed |= setPrediction(SpecCell | SpecOther); - break; - } - case ToIndexString: { - changed |= setPrediction(SpecString); + case Identity: + changed |= mergePrediction(node->child1()->prediction()); break; - } #ifndef NDEBUG // These get ignored because they don't return anything. + case StoreBarrier: + case ConditionalStoreBarrier: + case StoreBarrierWithNullCheck: case PutByValDirect: case PutByVal: case PutClosureVar: - case PutToArguments: case Return: - case TailCall: - case TailCallVarargs: - case TailCallForwardVarargs: case Throw: case PutById: - case PutByIdFlush: case PutByIdDirect: case PutByOffset: - case MultiPutByOffset: - case PutGetterById: - case PutSetterById: - case PutGetterSetterById: - case PutGetterByVal: - case PutSetterByVal: case DFG::Jump: case Branch: case Switch: case Breakpoint: case ProfileWillCall: case ProfileDidCall: - case ProfileType: - case ProfileControlFlow: + case CheckHasInstance: case ThrowReferenceError: case ForceOSRExit: case SetArgument: case CheckStructure: - case CheckCell: - case CheckNotEmpty: - case CheckIdent: - case CheckBadCell: + case CheckExecutable: + case StructureTransitionWatchpoint: + case CheckFunction: case PutStructure: + case TearOffActivation: + case TearOffArguments: + case CheckArgumentsNotCreated: + case VariableWatchpoint: case VarInjectionWatchpoint: + case AllocationProfileWatchpoint: case Phantom: case Check: - case PutGlobalVariable: + case PutGlobalVar: case CheckWatchdogTimer: case Unreachable: case LoopHint: case NotifyWrite: + case FunctionReentryWatchpoint: + case TypedArrayWatchpoint: case ConstantStoragePointer: case MovHint: case ZombieHint: - case ExitOK: - case LoadVarargs: - case CopyRest: - break; - - // This gets ignored because it only pretends to produce a value. - case BottomValue: break; // This gets ignored because it already has a prediction. @@ -826,14 +635,8 @@ private: } } - void doDoubleVoting(Node* node, float weight) + void doDoubleVoting(Node* node) { - // Loop pre-headers created by OSR entrypoint creation may have NaN weight to indicate - // that we actually don't know they weight. Assume that they execute once. This turns - // out to be an OK assumption since the pre-header doesn't have any meaningful code. - if (weight != weight) - weight = 1; - switch (node->op()) { case ValueAdd: case ArithAdd: @@ -843,16 +646,15 @@ private: DoubleBallot ballot; - if (isFullNumberSpeculation(left) - && isFullNumberSpeculation(right) - && !m_graph.addShouldSpeculateInt32(node, m_pass) + if (isFullNumberSpeculationExpectingDefined(left) && isFullNumberSpeculationExpectingDefined(right) + && !m_graph.addShouldSpeculateInt32(node) && !m_graph.addShouldSpeculateMachineInt(node)) ballot = VoteDouble; else ballot = VoteValue; - m_graph.voteNode(node->child1(), ballot, weight); - m_graph.voteNode(node->child2(), ballot, weight); + m_graph.voteNode(node->child1(), ballot); + m_graph.voteNode(node->child2(), ballot); break; } @@ -862,16 +664,15 @@ private: DoubleBallot ballot; - if (isFullNumberSpeculation(left) - && isFullNumberSpeculation(right) - && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass) - && !m_graph.binaryArithShouldSpeculateMachineInt(node, m_pass)) + if (isFullNumberSpeculation(left) && isFullNumberSpeculation(right) + && !m_graph.mulShouldSpeculateInt32(node) + && !m_graph.mulShouldSpeculateMachineInt(node)) ballot = VoteDouble; else ballot = VoteValue; - m_graph.voteNode(node->child1(), ballot, weight); - m_graph.voteNode(node->child2(), ballot, weight); + m_graph.voteNode(node->child1(), ballot); + m_graph.voteNode(node->child2(), ballot); break; } @@ -884,47 +685,41 @@ private: DoubleBallot ballot; - if (isFullNumberSpeculation(left) - && isFullNumberSpeculation(right) - && !m_graph.binaryArithShouldSpeculateInt32(node, m_pass)) + if (isFullNumberSpeculation(left) && isFullNumberSpeculation(right) + && !(Node::shouldSpeculateInt32ForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInt32())) ballot = VoteDouble; else ballot = VoteValue; - m_graph.voteNode(node->child1(), ballot, weight); - m_graph.voteNode(node->child2(), ballot, weight); + m_graph.voteNode(node->child1(), ballot); + m_graph.voteNode(node->child2(), ballot); break; } case ArithAbs: DoubleBallot ballot; - if (node->child1()->shouldSpeculateNumber() - && !m_graph.unaryArithShouldSpeculateInt32(node, m_pass)) + if (!(node->child1()->shouldSpeculateInt32ForArithmetic() && node->canSpeculateInt32())) ballot = VoteDouble; else ballot = VoteValue; - m_graph.voteNode(node->child1(), ballot, weight); + m_graph.voteNode(node->child1(), ballot); break; case ArithSqrt: case ArithCos: case ArithSin: - case ArithLog: - if (node->child1()->shouldSpeculateNumber()) - m_graph.voteNode(node->child1(), VoteDouble, weight); - else - m_graph.voteNode(node->child1(), VoteValue, weight); + m_graph.voteNode(node->child1(), VoteDouble); break; case SetLocal: { SpeculatedType prediction = node->child1()->prediction(); if (isDoubleSpeculation(prediction)) - node->variableAccessData()->vote(VoteDouble, weight); + node->variableAccessData()->vote(VoteDouble); else if ( !isFullNumberSpeculation(prediction) || isInt32Speculation(prediction) || isMachineIntSpeculation(prediction)) - node->variableAccessData()->vote(VoteValue, weight); + node->variableAccessData()->vote(VoteValue); break; } @@ -934,14 +729,14 @@ private: Edge child1 = m_graph.varArgChild(node, 0); Edge child2 = m_graph.varArgChild(node, 1); Edge child3 = m_graph.varArgChild(node, 2); - m_graph.voteNode(child1, VoteValue, weight); - m_graph.voteNode(child2, VoteValue, weight); + m_graph.voteNode(child1, VoteValue); + m_graph.voteNode(child2, VoteValue); switch (node->arrayMode().type()) { case Array::Double: - m_graph.voteNode(child3, VoteDouble, weight); + m_graph.voteNode(child3, VoteDouble); break; default: - m_graph.voteNode(child3, VoteValue, weight); + m_graph.voteNode(child3, VoteValue); break; } break; @@ -952,7 +747,7 @@ private: break; default: - m_graph.voteChildren(node, VoteValue, weight); + m_graph.voteChildren(node, VoteValue); break; } } @@ -968,7 +763,7 @@ private: ASSERT(block->isReachable); for (unsigned i = 0; i < block->size(); ++i) { m_currentNode = block->at(i); - doDoubleVoting(m_currentNode, block->executionCount); + doDoubleVoting(m_currentNode); } } for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) { @@ -977,7 +772,8 @@ private: continue; m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat(); } - propagateThroughArgumentPositions(); + for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i) + m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness(); for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) { VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i]; if (!variableAccessData->isRoot()) @@ -986,29 +782,8 @@ private: } } - void propagateThroughArgumentPositions() - { - for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i) - m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness(); - } - - SpeculatedType resultOfToPrimitive(SpeculatedType type) - { - if (type & SpecObject) { - // We try to be optimistic here about StringObjects since it's unlikely that - // someone overrides the valueOf or toString methods. - if (type & SpecStringObject && m_graph.canOptimizeStringObjectAccess(m_currentNode->origin.semantic)) - return mergeSpeculations(type & ~SpecObject, SpecString); - - return mergeSpeculations(type & ~SpecObject, SpecPrimitive); - } - - return type; - } - Node* m_currentNode; bool m_changed; - PredictionPass m_pass; // We use different logic for considering predictions depending on how far along we are in propagation. }; bool performPredictionPropagation(Graph& graph) |