1. 02 Jan, 2014 1 commit
    • fpizlo@apple.com's avatar
      Rationalize DFG DCE · 9775655d
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=125523
      
      Reviewed by Mark Hahnenberg.
              
      Adds the ability to DCE more things. It's now the case that if a node is completely
      pure, we clear NodeMustGenerate and the node becomes a DCE candidate.
      
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::cleanVariables):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::clobbersWorld):
      * dfg/DFGNodeType.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileAdd):
      * dfg/DFGSpeculativeJIT.h:
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileValueAdd):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@161218 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9775655d
  2. 29 Dec, 2013 1 commit
    • fpizlo@apple.com's avatar
      Get rid of DFG forward exiting · 9df7fef8
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=125531
      
      Reviewed by Oliver Hunt.
              
      This finally gets rid of forward exiting. Forward exiting was always a fragile concept
      since it involved the compiler trying to figure out how to "roll forward" the
      execution from some DFG node to the next bytecode index. It was always easy to find
      counterexamples where it broke, and it has always served as an obstacle to adding
      compiler improvements - the latest being http://webkit.org/b/125523, which tried to
      make DCE work for more things.
              
      This change finishes the work of removing forward exiting. A lot of forward exiting
      was already removed in some other bugs, but SetLocal still did forward exits. SetLocal
      is in many ways the hardest to remove, since the forward exiting of SetLocal also
      implied that any conversion nodes inserted before the SetLocal would then also be
      marked as forward-exiting. Hence SetLocal's forward-exiting made a bunch of other
      things also forward-exiting, and this was always a source of weirdo bugs.
              
      SetLocal must be able to exit in case it performs a hoisted type speculation. Nodes
      inserted just before SetLocal must also be able to exit - for example type check
      hoisting may insert a CheckStructure, or fixup phase may insert something like
      Int32ToDouble. But if any of those nodes tried to backward exit, then this could lead
      to the reexecution of a side-effecting operation, for example:
              
          a: Call(...)
          b: SetLocal(@a, r1)
              
      For a long time it seemed like SetLocal *had* to exit forward because of this. But
      this change side-steps the problem by changing the ByteCodeParser to always emit a
      kind of "two-phase commit" for stores to local variables. Now when the ByteCodeParser
      wishes to store to a local, it first emits a MovHint and then enqueues a SetLocal.
      The SetLocal isn't actually emitted until the beginning of the next bytecode
      instruction (which the exception of op_enter and op_ret, which emit theirs immediately
      since it's always safe to reexecute those bytecode instructions and since deferring
      SetLocals would be weird there - op_enter has many SetLocals and op_ret is a set
      followed by a jump in case of inlining, so we'd have to emit the SetLocal "after" the
      jump and that would be awkward). This means that the above IR snippet would look
      something like:
              
          a: Call(..., bc#42)
          b: MovHint(@a, r1, bc#42)
          c: SetLocal(@a, r1, bc#47)
              
      Where the SetLocal exits "backwards" but appears at the beginning of the next bytecode
      instruction. This means that by the time we get to that SetLocal, the OSR exit
      analysis already knows that r1 is associated with @a, and it means that the SetLocal
      or anything hoisted above it can exit backwards as normal.
              
      This change also means that the "forward rewiring" can be killed. Previously, we might
      have inserted a conversion node on SetLocal and then the SetLocal died (i.e. turned
      into a MovHint) and the conversion node either died completely or had its lifetime
      truncated to be less than the actual value's bytecode lifetime. This no longer happens
      since conversion nodes are only inserted at SetLocals.
              
      More precisely, this change introduces two laws that we were basically already
      following anyway:
              
      1) A MovHint's child should never be changed except if all other uses of that child
         are also replaced. Specifically, this prohibits insertion of conversion nodes at
         MovHints.
              
      2) Anytime any child is replaced with something else, and all other uses aren't also
         replaced, we must insert a Phantom use of the original child.
      
      This is a slight compile-time regression but has no effect on code-gen. It unlocks a
      bunch of optimization opportunities so I think it's worth it.
      
      * bytecode/CodeBlock.cpp:
      (JSC::CodeBlock::dumpAssumingJITType):
      * bytecode/CodeBlock.h:
      (JSC::CodeBlock::instructionCount):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      * dfg/DFGArrayifySlowPathGenerator.h:
      (JSC::DFG::ArrayifySlowPathGenerator::ArrayifySlowPathGenerator):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::setDirect):
      (JSC::DFG::ByteCodeParser::DelayedSetLocal::DelayedSetLocal):
      (JSC::DFG::ByteCodeParser::DelayedSetLocal::execute):
      (JSC::DFG::ByteCodeParser::handleInlining):
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::eliminate):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGCommon.h:
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::run):
      (JSC::DFG::DCEPhase::fixupBlock):
      (JSC::DFG::DCEPhase::cleanVariables):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixEdge):
      (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
      * dfg/DFGLICMPhase.cpp:
      (JSC::DFG::LICMPhase::run):
      (JSC::DFG::LICMPhase::attemptHoist):
      * dfg/DFGMinifiedNode.cpp:
      (JSC::DFG::MinifiedNode::fromNode):
      * dfg/DFGMinifiedNode.h:
      (JSC::DFG::belongsInMinifiedGraph):
      (JSC::DFG::MinifiedNode::constantNumber):
      (JSC::DFG::MinifiedNode::weakConstant):
      * dfg/DFGNode.cpp:
      (JSC::DFG::Node::hasVariableAccessData):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::convertToPhantom):
      (JSC::DFG::Node::convertToPhantomUnchecked):
      (JSC::DFG::Node::convertToIdentity):
      (JSC::DFG::Node::containsMovHint):
      (JSC::DFG::Node::hasUnlinkedLocal):
      (JSC::DFG::Node::willHaveCodeGenOrOSR):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      * dfg/DFGNodeFlags.h:
      * dfg/DFGNodeType.h:
      * dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
      (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
      * dfg/DFGOSREntrypointCreationPhase.cpp:
      (JSC::DFG::OSREntrypointCreationPhase::run):
      * dfg/DFGOSRExit.cpp:
      * dfg/DFGOSRExit.h:
      * dfg/DFGOSRExitBase.cpp:
      * dfg/DFGOSRExitBase.h:
      (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
      * dfg/DFGSSAConversionPhase.cpp:
      (JSC::DFG::SSAConversionPhase::run):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::safeToExecute):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::speculationCheck):
      (JSC::DFG::SpeculativeJIT::emitInvalidationPoint):
      (JSC::DFG::SpeculativeJIT::typeCheck):
      (JSC::DFG::SpeculativeJIT::compileMovHint):
      (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
      (JSC::DFG::SpeculativeJIT::checkArgumentTypes):
      (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::needsTypeCheck):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::run):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validateCPS):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::VariableAccessData):
      * dfg/DFGVariableEventStream.cpp:
      (JSC::DFG::VariableEventStream::reconstruct):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileMovHint):
      (JSC::FTL::LowerDFGToLLVM::compileZombieHint):
      (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble):
      (JSC::FTL::LowerDFGToLLVM::speculate):
      (JSC::FTL::LowerDFGToLLVM::typeCheck):
      (JSC::FTL::LowerDFGToLLVM::appendTypeCheck):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      * ftl/FTLOSRExit.cpp:
      * ftl/FTLOSRExit.h:
      * tests/stress/dead-int32-to-double.js: Added.
      (foo):
      * tests/stress/dead-uint32-to-number.js: Added.
      (foo):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@161126 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      9df7fef8
  3. 18 Sep, 2013 1 commit
    • fpizlo@apple.com's avatar
      DFG should support Int52 for local variables · 6921b29b
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=121064
      
      Source/JavaScriptCore: 
      
      Reviewed by Oliver Hunt.
              
      This adds Int52 support for local variables to the DFG and FTL. It's a speed-up on
      programs that have local int32 overflows but where a larger int representation can
      prevent us from having to convert all the way up to double.
              
      It's a small speed-up for now. But we're just supporting Int52 for a handful of
      operations (add, sub, mul, neg, compare, bitops, typed array access) and this lays
      the groundwork for adding Int52 to JSValue, which will probably be a bigger
      speed-up.
              
      The basic approach is:
              
      - We have a notion of Int52 in our typesystem. Int52 doesn't belong to BytecodeTop
        or HeapTop - i.e. it doesn't arise from JSValues.
              
      - DFG treats Int52 as being part of its FullTop and will treat it as being a
        subtype of double unless instructed otherwise.
              
      - Prediction propagator creates Int52s whenever we have a node going doubly but due
        to large values rather than fractional values, and that node is known to be able
        to produce Int52 natively in the DFG backend.
              
      - Fixup phase converts edges to MachineIntUses in nodes that are known to be able
        to deal with Int52, and where we have a subtype of Int32|Int52 as the predicted
        input.
              
      - The DFG backend and FTL LLVM IR lowering have two notions of Int52s - ones that
        are left-shifted by 16 (great for overflow checks) and ones that are
        sign-extended. Both backends know how to convert between Int52s and the other
        representations.
      
      * assembler/MacroAssemblerX86_64.h:
      (JSC::MacroAssemblerX86_64::rshift64):
      (JSC::MacroAssemblerX86_64::mul64):
      (JSC::MacroAssemblerX86_64::branchMul64):
      (JSC::MacroAssemblerX86_64::branchNeg64):
      (JSC::MacroAssemblerX86_64::convertInt64ToDouble):
      * assembler/X86Assembler.h:
      (JSC::X86Assembler::imulq_rr):
      (JSC::X86Assembler::cvtsi2sdq_rr):
      * bytecode/DataFormat.h:
      (JSC::dataFormatToString):
      * bytecode/ExitKind.cpp:
      (JSC::exitKindToString):
      * bytecode/ExitKind.h:
      * bytecode/OperandsInlines.h:
      (JSC::::dumpInContext):
      * bytecode/SpeculatedType.cpp:
      (JSC::dumpSpeculation):
      (JSC::speculationToAbbreviatedString):
      (JSC::speculationFromValue):
      * bytecode/SpeculatedType.h:
      (JSC::isInt32SpeculationForArithmetic):
      (JSC::isInt52Speculation):
      (JSC::isMachineIntSpeculationForArithmetic):
      (JSC::isInt52AsDoubleSpeculation):
      (JSC::isBytecodeRealNumberSpeculation):
      (JSC::isFullRealNumberSpeculation):
      (JSC::isBytecodeNumberSpeculation):
      (JSC::isFullNumberSpeculation):
      (JSC::isBytecodeNumberSpeculationExpectingDefined):
      (JSC::isFullNumberSpeculationExpectingDefined):
      * bytecode/ValueRecovery.h:
      (JSC::ValueRecovery::alreadyInJSStackAsUnboxedInt52):
      (JSC::ValueRecovery::inGPR):
      (JSC::ValueRecovery::displacedInJSStack):
      (JSC::ValueRecovery::isAlreadyInJSStack):
      (JSC::ValueRecovery::gpr):
      (JSC::ValueRecovery::virtualRegister):
      (JSC::ValueRecovery::dumpInContext):
      * dfg/DFGAbstractInterpreter.h:
      (JSC::DFG::AbstractInterpreter::needsTypeCheck):
      (JSC::DFG::AbstractInterpreter::filterByType):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      * dfg/DFGAbstractValue.cpp:
      (JSC::DFG::AbstractValue::set):
      (JSC::DFG::AbstractValue::checkConsistency):
      * dfg/DFGAbstractValue.h:
      (JSC::DFG::AbstractValue::couldBeType):
      (JSC::DFG::AbstractValue::isType):
      (JSC::DFG::AbstractValue::checkConsistency):
      (JSC::DFG::AbstractValue::validateType):
      * dfg/DFGArrayMode.cpp:
      (JSC::DFG::ArrayMode::refine):
      * dfg/DFGAssemblyHelpers.h:
      (JSC::DFG::AssemblyHelpers::boxInt52):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::makeSafe):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::pureCSE):
      (JSC::DFG::CSEPhase::getByValLoadElimination):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGClobberize.h:
      (JSC::DFG::clobberize):
      * dfg/DFGCommon.h:
      (JSC::DFG::enableInt52):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::fixupBlock):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::run):
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::fixupSetLocalsInBlock):
      (JSC::DFG::FixupPhase::fixupUntypedSetLocalsInBlock):
      (JSC::DFG::FixupPhase::observeUseKindOnNode):
      (JSC::DFG::FixupPhase::fixEdge):
      (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
      (JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
      * dfg/DFGFlushFormat.cpp:
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h:
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      * dfg/DFGGenerationInfo.h:
      (JSC::DFG::GenerationInfo::initInt52):
      (JSC::DFG::GenerationInfo::initStrictInt52):
      (JSC::DFG::GenerationInfo::isFormat):
      (JSC::DFG::GenerationInfo::isInt52):
      (JSC::DFG::GenerationInfo::isStrictInt52):
      (JSC::DFG::GenerationInfo::fillInt52):
      (JSC::DFG::GenerationInfo::fillStrictInt52):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::addShouldSpeculateMachineInt):
      (JSC::DFG::Graph::mulShouldSpeculateMachineInt):
      (JSC::DFG::Graph::negateShouldSpeculateMachineInt):
      * dfg/DFGInPlaceAbstractState.cpp:
      (JSC::DFG::InPlaceAbstractState::mergeStateAtTail):
      * dfg/DFGJITCode.cpp:
      (JSC::DFG::JITCode::reconstruct):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::noticeOSREntry):
      * dfg/DFGMinifiedNode.h:
      (JSC::DFG::belongsInMinifiedGraph):
      (JSC::DFG::MinifiedNode::hasChild):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::shouldSpeculateNumber):
      (JSC::DFG::Node::shouldSpeculateNumberExpectingDefined):
      (JSC::DFG::Node::canSpeculateInt52):
      * dfg/DFGNodeFlags.h:
      (JSC::DFG::nodeCanSpeculateInt52):
      * dfg/DFGNodeType.h:
      (JSC::DFG::permitsOSRBackwardRewiring):
      (JSC::DFG::forwardRewiringSelectionScore):
      * dfg/DFGOSREntry.cpp:
      (JSC::DFG::prepareOSREntry):
      * dfg/DFGOSREntry.h:
      * dfg/DFGOSRExitCompiler.cpp:
      * dfg/DFGOSRExitCompiler64.cpp:
      (JSC::DFG::OSRExitCompiler::compileExit):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::speculatedDoubleTypeForPrediction):
      (JSC::DFG::PredictionPropagationPhase::propagate):
      (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
      * dfg/DFGSafeToExecute.h:
      (JSC::DFG::SafeToExecuteEdge::operator()):
      (JSC::DFG::safeToExecute):
      * dfg/DFGSilentRegisterSavePlan.h:
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
      (JSC::DFG::SpeculativeJIT::silentFill):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compileInlineStart):
      (JSC::DFG::SpeculativeJIT::compileDoublePutByVal):
      (JSC::DFG::SpeculativeJIT::compileValueToInt32):
      (JSC::DFG::SpeculativeJIT::compileInt32ToDouble):
      (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
      (JSC::DFG::SpeculativeJIT::compileAdd):
      (JSC::DFG::SpeculativeJIT::compileArithSub):
      (JSC::DFG::SpeculativeJIT::compileArithNegate):
      (JSC::DFG::SpeculativeJIT::compileArithMul):
      (JSC::DFG::SpeculativeJIT::compare):
      (JSC::DFG::SpeculativeJIT::compileStrictEq):
      (JSC::DFG::SpeculativeJIT::speculateMachineInt):
      (JSC::DFG::SpeculativeJIT::speculateNumber):
      (JSC::DFG::SpeculativeJIT::speculateRealNumber):
      (JSC::DFG::SpeculativeJIT::speculate):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::canReuse):
      (JSC::DFG::SpeculativeJIT::isFilled):
      (JSC::DFG::SpeculativeJIT::isFilledDouble):
      (JSC::DFG::SpeculativeJIT::use):
      (JSC::DFG::SpeculativeJIT::isKnownInteger):
      (JSC::DFG::SpeculativeJIT::isKnownCell):
      (JSC::DFG::SpeculativeJIT::isKnownNotNumber):
      (JSC::DFG::SpeculativeJIT::int52Result):
      (JSC::DFG::SpeculativeJIT::strictInt52Result):
      (JSC::DFG::SpeculativeJIT::initConstantInfo):
      (JSC::DFG::SpeculativeJIT::isInteger):
      (JSC::DFG::SpeculativeJIT::betterUseStrictInt52):
      (JSC::DFG::SpeculativeJIT::generationInfo):
      (JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
      (JSC::DFG::SpeculateInt52Operand::~SpeculateInt52Operand):
      (JSC::DFG::SpeculateInt52Operand::edge):
      (JSC::DFG::SpeculateInt52Operand::node):
      (JSC::DFG::SpeculateInt52Operand::gpr):
      (JSC::DFG::SpeculateInt52Operand::use):
      (JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
      (JSC::DFG::SpeculateStrictInt52Operand::~SpeculateStrictInt52Operand):
      (JSC::DFG::SpeculateStrictInt52Operand::edge):
      (JSC::DFG::SpeculateStrictInt52Operand::node):
      (JSC::DFG::SpeculateStrictInt52Operand::gpr):
      (JSC::DFG::SpeculateStrictInt52Operand::use):
      (JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
      (JSC::DFG::SpeculateWhicheverInt52Operand::~SpeculateWhicheverInt52Operand):
      (JSC::DFG::SpeculateWhicheverInt52Operand::edge):
      (JSC::DFG::SpeculateWhicheverInt52Operand::node):
      (JSC::DFG::SpeculateWhicheverInt52Operand::gpr):
      (JSC::DFG::SpeculateWhicheverInt52Operand::use):
      (JSC::DFG::SpeculateWhicheverInt52Operand::format):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::boxInt52):
      (JSC::DFG::SpeculativeJIT::fillJSValue):
      (JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
      (JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
      (JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
      (JSC::DFG::SpeculativeJIT::fillSpeculateCell):
      (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
      (JSC::DFG::SpeculativeJIT::compileInt52Compare):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleInt52Branch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGUseKind.cpp:
      (WTF::printInternal):
      * dfg/DFGUseKind.h:
      (JSC::DFG::typeFilterFor):
      (JSC::DFG::isNumerical):
      * dfg/DFGValueSource.cpp:
      (JSC::DFG::ValueSource::dump):
      * dfg/DFGValueSource.h:
      (JSC::DFG::dataFormatToValueSourceKind):
      (JSC::DFG::valueSourceKindToDataFormat):
      (JSC::DFG::ValueSource::forFlushFormat):
      (JSC::DFG::ValueSource::valueRecovery):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):
      (JSC::DFG::VariableAccessData::flushFormat):
      * ftl/FTLCArgumentGetter.cpp:
      (JSC::FTL::CArgumentGetter::loadNextAndBox):
      * ftl/FTLCArgumentGetter.h:
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLExitValue.cpp:
      (JSC::FTL::ExitValue::dumpInContext):
      * ftl/FTLExitValue.h:
      (JSC::FTL::ExitValue::inJSStackAsInt52):
      * ftl/FTLIntrinsicRepository.h:
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
      (JSC::FTL::LowerDFGToLLVM::compilePhi):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      (JSC::FTL::LowerDFGToLLVM::compilePutByVal):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
      (JSC::FTL::LowerDFGToLLVM::lowInt32):
      (JSC::FTL::LowerDFGToLLVM::lowInt52):
      (JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::betterUseStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::bestInt52Kind):
      (JSC::FTL::LowerDFGToLLVM::opposite):
      (JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
      (JSC::FTL::LowerDFGToLLVM::lowCell):
      (JSC::FTL::LowerDFGToLLVM::lowBoolean):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (JSC::FTL::LowerDFGToLLVM::lowJSValue):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToInt32):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToJSValue):
      (JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue):
      (JSC::FTL::LowerDFGToLLVM::strictInt52ToInt52):
      (JSC::FTL::LowerDFGToLLVM::int52ToStrictInt52):
      (JSC::FTL::LowerDFGToLLVM::speculateRealNumber):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      (JSC::FTL::LowerDFGToLLVM::setInt52):
      (JSC::FTL::LowerDFGToLLVM::setStrictInt52):
      * ftl/FTLOSRExitCompiler.cpp:
      (JSC::FTL::compileStub):
      * ftl/FTLOutput.h:
      (JSC::FTL::Output::addWithOverflow64):
      (JSC::FTL::Output::subWithOverflow64):
      (JSC::FTL::Output::mulWithOverflow64):
      * ftl/FTLValueFormat.cpp:
      (WTF::printInternal):
      * ftl/FTLValueFormat.h:
      * ftl/FTLValueSource.cpp:
      (JSC::FTL::ValueSource::dump):
      * ftl/FTLValueSource.h:
      * interpreter/Register.h:
      (JSC::Register::unboxedInt52):
      * runtime/Arguments.cpp:
      (JSC::Arguments::tearOffForInlineCallFrame):
      * runtime/IndexingType.cpp:
      (JSC::leastUpperBoundOfIndexingTypeAndType):
      * runtime/JSCJSValue.h:
      * runtime/JSCJSValueInlines.h:
      (JSC::JSValue::isMachineInt):
      (JSC::JSValue::asMachineInt):
      
      Source/WTF: 
      
      Reviewed by Oliver Hunt.
      
      * wtf/PrintStream.h:
      (WTF::ValueIgnoringContext::ValueIgnoringContext):
      (WTF::ValueIgnoringContext::dump):
      (WTF::ignoringContext):
      
      Tools: 
      
      Reviewed by Oliver Hunt.
      
      * Scripts/run-jsc-stress-tests:
      
      LayoutTests: 
      
      Reviewed by Oliver Hunt.
      
      * js/dfg-int-overflow-large-constants-in-a-line-expected.txt:
      * js/regress/large-int-captured-expected.txt: Added.
      * js/regress/large-int-captured.html: Added.
      * js/regress/large-int-expected.txt: Added.
      * js/regress/large-int-neg-expected.txt: Added.
      * js/regress/large-int-neg.html: Added.
      * js/regress/large-int.html: Added.
      * js/regress/marsaglia-larger-ints-expected.txt: Added.
      * js/regress/marsaglia-larger-ints.html: Added.
      * js/regress/script-tests/large-int-captured.js: Added.
      (.bar):
      (foo):
      * js/regress/script-tests/large-int-neg.js: Added.
      (foo):
      * js/regress/script-tests/large-int.js: Added.
      (foo):
      * js/regress/script-tests/marsaglia-larger-ints.js: Added.
      (uint):
      (marsaglia):
      * js/script-tests/dfg-int-overflow-large-constants-in-a-line.js:
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@156047 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      6921b29b
  4. 25 Jul, 2013 3 commits
    • oliver@apple.com's avatar
      fourthTier: DFG should do a high-level LICM before going to FTL · e17632e6
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118749
      
      Reviewed by Oliver Hunt.
      
      Implements LICM hoisting for nodes that never write anything and never read
      things that are clobbered by the loop. There are some other preconditions for
      hoisting, see DFGLICMPhase.cpp.
      
      Also did a few fixes:
      
      - ClobberSet::add was failing to switch Super entries to Direct entries in
        some cases.
      
      - DFGClobberize.cpp needed to #include "Operations.h".
      
      - DCEPhase needs to process the graph in reverse DFS order, when we're in SSA.
      
      - AbstractInterpreter can now execute a Node without knowing its indexInBlock.
        Knowing the indexInBlock is an optional optimization that all other clients
        of AI still opt into, but LICM doesn't.
      
      This makes the FTL a 2.19x speed-up on imaging-gaussian-blur.
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * dfg/DFGAbstractInterpreter.h:
      (AbstractInterpreter):
      * dfg/DFGAbstractInterpreterInlines.h:
      (JSC::DFG::::executeEffects):
      (JSC::DFG::::execute):
      (DFG):
      (JSC::DFG::::clobberWorld):
      (JSC::DFG::::clobberStructures):
      * dfg/DFGAtTailAbstractState.cpp: Added.
      (DFG):
      (JSC::DFG::AtTailAbstractState::AtTailAbstractState):
      (JSC::DFG::AtTailAbstractState::~AtTailAbstractState):
      (JSC::DFG::AtTailAbstractState::createValueForNode):
      (JSC::DFG::AtTailAbstractState::forNode):
      * dfg/DFGAtTailAbstractState.h: Added.
      (DFG):
      (AtTailAbstractState):
      (JSC::DFG::AtTailAbstractState::initializeTo):
      (JSC::DFG::AtTailAbstractState::forNode):
      (JSC::DFG::AtTailAbstractState::variables):
      (JSC::DFG::AtTailAbstractState::block):
      (JSC::DFG::AtTailAbstractState::isValid):
      (JSC::DFG::AtTailAbstractState::setDidClobber):
      (JSC::DFG::AtTailAbstractState::setIsValid):
      (JSC::DFG::AtTailAbstractState::setBranchDirection):
      (JSC::DFG::AtTailAbstractState::setFoundConstants):
      (JSC::DFG::AtTailAbstractState::haveStructures):
      (JSC::DFG::AtTailAbstractState::setHaveStructures):
      * dfg/DFGBasicBlock.h:
      (JSC::DFG::BasicBlock::insertBeforeLast):
      * dfg/DFGBasicBlockInlines.h:
      (DFG):
      * dfg/DFGClobberSet.cpp:
      (JSC::DFG::ClobberSet::add):
      (JSC::DFG::ClobberSet::addAll):
      * dfg/DFGClobberize.cpp:
      (JSC::DFG::doesWrites):
      * dfg/DFGClobberize.h:
      (DFG):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::DCEPhase):
      (JSC::DFG::DCEPhase::run):
      (JSC::DFG::DCEPhase::fixupBlock):
      (DCEPhase):
      * dfg/DFGEdgeDominates.h: Added.
      (DFG):
      (EdgeDominates):
      (JSC::DFG::EdgeDominates::EdgeDominates):
      (JSC::DFG::EdgeDominates::operator()):
      (JSC::DFG::EdgeDominates::result):
      (JSC::DFG::edgesDominate):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::checkArray):
      * dfg/DFGLICMPhase.cpp: Added.
      (LICMPhase):
      (JSC::DFG::LICMPhase::LICMPhase):
      (JSC::DFG::LICMPhase::run):
      (JSC::DFG::LICMPhase::attemptHoist):
      (DFG):
      (JSC::DFG::performLICM):
      * dfg/DFGLICMPhase.h: Added.
      (DFG):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153295 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      e17632e6
    • oliver@apple.com's avatar
      fourthTier: DFG should have an SSA form for use by FTL · 827d2cf7
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118338
      
      Source/JavaScriptCore:
      
      Reviewed by Mark Hahnenberg.
      
      Adds an SSA form to the DFG. We can convert ThreadedCPS form into SSA form
      after breaking critical edges. The conversion algorithm follows Aycock and
      Horspool, and the SSA form itself follows something I've done before, where
      instead of having Phi functions specify input nodes corresponding to block
      predecessors, we instead have Upsilon functions in the predecessors that
      specify which value in that block goes into which subsequent Phi. Upsilons
      don't have to dominate Phis (usually they don't) and they correspond to a
      non-SSA "mov" into the Phi's "variable". This gives all of the good
      properties of SSA, while ensuring that a bunch of CFG transformations don't
      have to be SSA-aware.
      
      So far the only DFG phases that are SSA-aware are DCE and CFA. CFG
      simplification is probably SSA-aware by default, though I haven't tried it.
      Constant folding probably needs a few tweaks, but is likely ready. Ditto
      for CSE, though it's not clear that we'd want to use block-local CSE when
      we could be doing GVN.
      
      Currently only the FTL can generate code from the SSA form, and there is no
      way to convert from SSA to ThreadedCPS or LoadStore. There probably will
      never be such a capability.
      
      In order to handle OSR exit state in the SSA, we place MovHints at Phi
      points. Other than that, you can reconstruct state-at-exit by forward
      propagating MovHints. Note that MovHint is the new SetLocal in SSA.
      SetLocal and GetLocal only survive into SSA if they are on captured
      variables, or in the case of flushes. A "live SetLocal" will be
      NodeMustGenerate and will always correspond to a flush. Computing the
      state-at-exit requires running SSA liveness analysis, OSR availability
      analysis, and flush liveness analysis. The FTL runs all of these prior to
      generating code. While OSR exit continues to be tricky, much of the logic
      is now factored into separate phases and the backend has to do less work
      to reason about what happened outside of the basic block that is being
      lowered.
      
      Conversion from DFG SSA to LLVM SSA is done by ensuring that we generate
      code in depth-first order, thus guaranteeing that a node will always be
      lowered (and hence have a LValue) before any of the blocks dominated by
      that node's block have code generated. For Upsilon/Phi, we just use
      alloca's. We could do something more clever there, but it's probably not
      worth it, at least not now.
      
      Finally, while the SSA form is currently only being converted to LLVM IR,
      there is nothing that prevents us from considering other backends in the
      future - with the caveat that this form is designed to be first lowered to
      a lower-level SSA before actual machine code generation commences. So we
      ought to either use LLVM (the intended path) or we will have to write our
      own SSA low-level backend.
      
      This runs all of the code that the FTL was known to run previously. No
      change in performance for now. But it does open some exciting
      possibilities!
      
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * bytecode/Operands.h:
      (JSC::OperandValueTraits::dump):
      (JSC::Operands::fill):
      (Operands):
      (JSC::Operands::clear):
      (JSC::Operands::operator==):
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::beginBasicBlock):
      (JSC::DFG::setLiveValues):
      (DFG):
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::endBasicBlock):
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::mergeStateAtTail):
      (JSC::DFG::AbstractState::merge):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      * dfg/DFGAdjacencyList.h:
      (JSC::DFG::AdjacencyList::justOneChild):
      (AdjacencyList):
      * dfg/DFGBasicBlock.cpp: Added.
      (DFG):
      (JSC::DFG::BasicBlock::BasicBlock):
      (JSC::DFG::BasicBlock::~BasicBlock):
      (JSC::DFG::BasicBlock::ensureLocals):
      (JSC::DFG::BasicBlock::isInPhis):
      (JSC::DFG::BasicBlock::isInBlock):
      (JSC::DFG::BasicBlock::removePredecessor):
      (JSC::DFG::BasicBlock::replacePredecessor):
      (JSC::DFG::BasicBlock::dump):
      (JSC::DFG::BasicBlock::SSAData::SSAData):
      (JSC::DFG::BasicBlock::SSAData::~SSAData):
      * dfg/DFGBasicBlock.h:
      (BasicBlock):
      (JSC::DFG::BasicBlock::operator[]):
      (JSC::DFG::BasicBlock::successor):
      (JSC::DFG::BasicBlock::successorForCondition):
      (SSAData):
      * dfg/DFGBasicBlockInlines.h:
      (DFG):
      * dfg/DFGBlockInsertionSet.cpp: Added.
      (DFG):
      (JSC::DFG::BlockInsertionSet::BlockInsertionSet):
      (JSC::DFG::BlockInsertionSet::~BlockInsertionSet):
      (JSC::DFG::BlockInsertionSet::insert):
      (JSC::DFG::BlockInsertionSet::insertBefore):
      (JSC::DFG::BlockInsertionSet::execute):
      * dfg/DFGBlockInsertionSet.h: Added.
      (DFG):
      (BlockInsertionSet):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::run):
      * dfg/DFGCFGSimplificationPhase.cpp:
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock):
      * dfg/DFGCommon.cpp:
      (WTF::printInternal):
      * dfg/DFGCommon.h:
      (JSC::DFG::doesKill):
      (DFG):
      (JSC::DFG::killStatusForDoesKill):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (JSC::DFG::ConstantFoldingPhase::isCapturedAtOrAfter):
      * dfg/DFGCriticalEdgeBreakingPhase.cpp: Added.
      (DFG):
      (CriticalEdgeBreakingPhase):
      (JSC::DFG::CriticalEdgeBreakingPhase::CriticalEdgeBreakingPhase):
      (JSC::DFG::CriticalEdgeBreakingPhase::run):
      (JSC::DFG::CriticalEdgeBreakingPhase::breakCriticalEdge):
      (JSC::DFG::performCriticalEdgeBreaking):
      * dfg/DFGCriticalEdgeBreakingPhase.h: Added.
      (DFG):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::run):
      (JSC::DFG::DCEPhase::findTypeCheckRoot):
      (JSC::DFG::DCEPhase::countNode):
      (DCEPhase):
      (JSC::DFG::DCEPhase::countEdge):
      (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGEdge.cpp:
      (JSC::DFG::Edge::dump):
      * dfg/DFGEdge.h:
      (JSC::DFG::Edge::Edge):
      (JSC::DFG::Edge::setNode):
      (JSC::DFG::Edge::useKindUnchecked):
      (JSC::DFG::Edge::setUseKind):
      (JSC::DFG::Edge::setProofStatus):
      (JSC::DFG::Edge::willNotHaveCheck):
      (JSC::DFG::Edge::willHaveCheck):
      (Edge):
      (JSC::DFG::Edge::killStatusUnchecked):
      (JSC::DFG::Edge::killStatus):
      (JSC::DFG::Edge::setKillStatus):
      (JSC::DFG::Edge::doesKill):
      (JSC::DFG::Edge::doesNotKill):
      (JSC::DFG::Edge::shift):
      (JSC::DFG::Edge::makeWord):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGFlushFormat.cpp: Added.
      (WTF):
      (WTF::printInternal):
      * dfg/DFGFlushFormat.h: Added.
      (DFG):
      (JSC::DFG::resultFor):
      (JSC::DFG::useKindFor):
      (WTF):
      * dfg/DFGFlushLivenessAnalysisPhase.cpp: Added.
      (DFG):
      (FlushLivenessAnalysisPhase):
      (JSC::DFG::FlushLivenessAnalysisPhase::FlushLivenessAnalysisPhase):
      (JSC::DFG::FlushLivenessAnalysisPhase::run):
      (JSC::DFG::FlushLivenessAnalysisPhase::process):
      (JSC::DFG::FlushLivenessAnalysisPhase::setForNode):
      (JSC::DFG::FlushLivenessAnalysisPhase::flushFormat):
      (JSC::DFG::performFlushLivenessAnalysis):
      * dfg/DFGFlushLivenessAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::dumpBlockHeader):
      (DFG):
      (JSC::DFG::Graph::addForDepthFirstSort):
      (JSC::DFG::Graph::getBlocksInDepthFirstOrder):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::convertToConstant):
      (JSC::DFG::Graph::valueProfileFor):
      (Graph):
      * dfg/DFGInsertionSet.h:
      (DFG):
      (JSC::DFG::InsertionSet::execute):
      * dfg/DFGLivenessAnalysisPhase.cpp: Added.
      (DFG):
      (LivenessAnalysisPhase):
      (JSC::DFG::LivenessAnalysisPhase::LivenessAnalysisPhase):
      (JSC::DFG::LivenessAnalysisPhase::run):
      (JSC::DFG::LivenessAnalysisPhase::process):
      (JSC::DFG::LivenessAnalysisPhase::addChildUse):
      (JSC::DFG::performLivenessAnalysis):
      * dfg/DFGLivenessAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGNode.cpp:
      (JSC::DFG::Node::hasVariableAccessData):
      (DFG):
      * dfg/DFGNode.h:
      (DFG):
      (Node):
      (JSC::DFG::Node::hasLocal):
      (JSC::DFG::Node::variableAccessData):
      (JSC::DFG::Node::hasPhi):
      (JSC::DFG::Node::phi):
      (JSC::DFG::Node::takenBlock):
      (JSC::DFG::Node::notTakenBlock):
      (JSC::DFG::Node::successor):
      (JSC::DFG::Node::successorForCondition):
      (JSC::DFG::nodeComparator):
      (JSC::DFG::nodeListDump):
      (JSC::DFG::nodeMapDump):
      * dfg/DFGNodeFlags.cpp:
      (JSC::DFG::dumpNodeFlags):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOSRAvailabilityAnalysisPhase.cpp: Added.
      (DFG):
      (OSRAvailabilityAnalysisPhase):
      (JSC::DFG::OSRAvailabilityAnalysisPhase::OSRAvailabilityAnalysisPhase):
      (JSC::DFG::OSRAvailabilityAnalysisPhase::run):
      (JSC::DFG::performOSRAvailabilityAnalysis):
      * dfg/DFGOSRAvailabilityAnalysisPhase.h: Added.
      (DFG):
      * dfg/DFGPlan.cpp:
      (JSC::DFG::Plan::compileInThreadImpl):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSSAConversionPhase.cpp: Added.
      (DFG):
      (SSAConversionPhase):
      (JSC::DFG::SSAConversionPhase::SSAConversionPhase):
      (JSC::DFG::SSAConversionPhase::run):
      (JSC::DFG::SSAConversionPhase::forwardPhiChildren):
      (JSC::DFG::SSAConversionPhase::forwardPhi):
      (JSC::DFG::SSAConversionPhase::forwardPhiEdge):
      (JSC::DFG::SSAConversionPhase::deduplicateChildren):
      (JSC::DFG::SSAConversionPhase::addFlushedLocalOp):
      (JSC::DFG::SSAConversionPhase::addFlushedLocalEdge):
      (JSC::DFG::performSSAConversion):
      * dfg/DFGSSAConversionPhase.h: Added.
      (DFG):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validate):
      (Validate):
      (JSC::DFG::Validate::validateCPS):
      * dfg/DFGVariableAccessData.h:
      (JSC::DFG::VariableAccessData::flushFormat):
      (VariableAccessData):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lower):
      (JSC::FTL::LowerDFGToLLVM::createPhiVariables):
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileNode):
      (JSC::FTL::LowerDFGToLLVM::compileUpsilon):
      (LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::compilePhi):
      (JSC::FTL::LowerDFGToLLVM::compileJSConstant):
      (JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant):
      (JSC::FTL::LowerDFGToLLVM::compileGetArgument):
      (JSC::FTL::LowerDFGToLLVM::compileGetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileSetLocal):
      (JSC::FTL::LowerDFGToLLVM::compileAdd):
      (JSC::FTL::LowerDFGToLLVM::compileArithSub):
      (JSC::FTL::LowerDFGToLLVM::compileArithMul):
      (JSC::FTL::LowerDFGToLLVM::compileArithDiv):
      (JSC::FTL::LowerDFGToLLVM::compileArithMod):
      (JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
      (JSC::FTL::LowerDFGToLLVM::compileArithAbs):
      (JSC::FTL::LowerDFGToLLVM::compileArithNegate):
      (JSC::FTL::LowerDFGToLLVM::compileBitAnd):
      (JSC::FTL::LowerDFGToLLVM::compileBitOr):
      (JSC::FTL::LowerDFGToLLVM::compileBitXor):
      (JSC::FTL::LowerDFGToLLVM::compileBitRShift):
      (JSC::FTL::LowerDFGToLLVM::compileBitLShift):
      (JSC::FTL::LowerDFGToLLVM::compileBitURShift):
      (JSC::FTL::LowerDFGToLLVM::compileUInt32ToNumber):
      (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble):
      (JSC::FTL::LowerDFGToLLVM::compileGetButterfly):
      (JSC::FTL::LowerDFGToLLVM::compileGetArrayLength):
      (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
      (JSC::FTL::LowerDFGToLLVM::compileGetByOffset):
      (JSC::FTL::LowerDFGToLLVM::compileGetGlobalVar):
      (JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLess):
      (JSC::FTL::LowerDFGToLLVM::compileCompareLessEq):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreater):
      (JSC::FTL::LowerDFGToLLVM::compileCompareGreaterEq):
      (JSC::FTL::LowerDFGToLLVM::compileLogicalNot):
      (JSC::FTL::LowerDFGToLLVM::speculateBackward):
      (JSC::FTL::LowerDFGToLLVM::lowInt32):
      (JSC::FTL::LowerDFGToLLVM::lowCell):
      (JSC::FTL::LowerDFGToLLVM::lowBoolean):
      (JSC::FTL::LowerDFGToLLVM::lowDouble):
      (JSC::FTL::LowerDFGToLLVM::lowJSValue):
      (JSC::FTL::LowerDFGToLLVM::lowStorage):
      (JSC::FTL::LowerDFGToLLVM::speculate):
      (JSC::FTL::LowerDFGToLLVM::speculateBoolean):
      (JSC::FTL::LowerDFGToLLVM::isLive):
      (JSC::FTL::LowerDFGToLLVM::use):
      (JSC::FTL::LowerDFGToLLVM::initializeOSRExitStateForBlock):
      (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
      (JSC::FTL::LowerDFGToLLVM::emitOSRExitCall):
      (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
      (JSC::FTL::LowerDFGToLLVM::linkOSRExitsAndCompleteInitializationBlocks):
      (JSC::FTL::LowerDFGToLLVM::setInt32):
      (JSC::FTL::LowerDFGToLLVM::setJSValue):
      (JSC::FTL::LowerDFGToLLVM::setBoolean):
      (JSC::FTL::LowerDFGToLLVM::setStorage):
      (JSC::FTL::LowerDFGToLLVM::setDouble):
      (JSC::FTL::LowerDFGToLLVM::isValid):
      * ftl/FTLLoweredNodeValue.h: Added.
      (FTL):
      (LoweredNodeValue):
      (JSC::FTL::LoweredNodeValue::LoweredNodeValue):
      (JSC::FTL::LoweredNodeValue::isSet):
      (JSC::FTL::LoweredNodeValue::operator!):
      (JSC::FTL::LoweredNodeValue::value):
      (JSC::FTL::LoweredNodeValue::block):
      * ftl/FTLValueFromBlock.h:
      (JSC::FTL::ValueFromBlock::ValueFromBlock):
      (ValueFromBlock):
      * ftl/FTLValueSource.cpp:
      (JSC::FTL::ValueSource::dump):
      * ftl/FTLValueSource.h:
      
      Source/WTF:
      
      Reviewed by Mark Hahnenberg.
      
      - Extend variadicity of PrintStream and dataLog.
      
      - Give HashSet the ability to add a span of things.
      
      - Give HashSet the ability to == another HashSet.
      
      - Note FIXME's in HashTable concerning copying performance, that affects
        the way that the DFG now uses HashSets and HashMaps.
      
      - Factor out the bulk-insertion logic of JSC::DFG::InsertionSet into
        WTF::Insertion, so that it can be used in more places.
      
      - Create a dumper for lists and maps.
      
      * WTF.xcodeproj/project.pbxproj:
      * wtf/DataLog.h:
      (WTF):
      (WTF::dataLog):
      * wtf/HashSet.h:
      (HashSet):
      (WTF):
      (WTF::::add):
      (WTF::=):
      * wtf/HashTable.h:
      (WTF::::HashTable):
      (WTF::=):
      * wtf/Insertion.h: Added.
      (WTF):
      (Insertion):
      (WTF::Insertion::Insertion):
      (WTF::Insertion::index):
      (WTF::Insertion::element):
      (WTF::Insertion::operator<):
      (WTF::executeInsertions):
      * wtf/ListDump.h: Added.
      (WTF):
      (ListDump):
      (WTF::ListDump::ListDump):
      (WTF::ListDump::dump):
      (MapDump):
      (WTF::MapDump::MapDump):
      (WTF::MapDump::dump):
      (WTF::listDump):
      (WTF::sortedListDump):
      (WTF::lessThan):
      (WTF::mapDump):
      (WTF::sortedMapDump):
      * wtf/PrintStream.h:
      (PrintStream):
      (WTF::PrintStream::print):
      
      Conflicts:
      	Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153274 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      827d2cf7
    • oliver@apple.com's avatar
      fourthTier: DFG should refer to BasicBlocks by BasicBlock* and not BlockIndex · 426f5b02
      oliver@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=118339
      
      Reviewed by Michael Saboff.
      
      This accomplishes two goals:
      
      1) Simplifies a bunch of code. You can now much more directly get to a successor
         or predecessor, since you just get the pointer directly. The backend(s) always
         hold onto a pointer to the block they're on, so you don't have to do work to
         get the block from the index.
      
      2) It allows for the possibility of inserting blocks into the program.
         Previously, if you did that, you'd have to edit all references to blocks since
         those references would have outdated indexing after an insertion. Now, if you
         change the indexing, you just have to invalidate some analyses and make sure
         that you change each block's BasicBlock::index accordingly.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::initialize):
      (JSC::DFG::AbstractState::endBasicBlock):
      (JSC::DFG::AbstractState::mergeToSuccessors):
      * dfg/DFGAbstractState.h:
      (AbstractState):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::run):
      * dfg/DFGBasicBlock.h:
      (DFG):
      (JSC::DFG::BasicBlock::BasicBlock):
      (JSC::DFG::BasicBlock::size):
      (JSC::DFG::BasicBlock::isEmpty):
      (JSC::DFG::BasicBlock::at):
      (JSC::DFG::BasicBlock::operator[]):
      (JSC::DFG::BasicBlock::last):
      (JSC::DFG::BasicBlock::resize):
      (JSC::DFG::BasicBlock::grow):
      (BasicBlock):
      (JSC::DFG::BasicBlock::append):
      (JSC::DFG::BasicBlock::numSuccessors):
      (JSC::DFG::BasicBlock::successor):
      (JSC::DFG::BasicBlock::successorForCondition):
      (JSC::DFG::BasicBlock::dump):
      (UnlinkedBlock):
      (JSC::DFG::UnlinkedBlock::UnlinkedBlock):
      (JSC::DFG::getBytecodeBeginForBlock):
      (JSC::DFG::blockForBytecodeOffset):
      * dfg/DFGByteCodeParser.cpp:
      (ByteCodeParser):
      (InlineStackEntry):
      (JSC::DFG::ByteCodeParser::handleInlining):
      (JSC::DFG::ByteCodeParser::parseBlock):
      (JSC::DFG::ByteCodeParser::linkBlock):
      (JSC::DFG::ByteCodeParser::linkBlocks):
      (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
      (JSC::DFG::ByteCodeParser::parseCodeBlock):
      (JSC::DFG::ByteCodeParser::parse):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::performBlockCFA):
      (JSC::DFG::CFAPhase::performForwardCFA):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (JSC::DFG::CFGSimplificationPhase::run):
      (JSC::DFG::CFGSimplificationPhase::convertToJump):
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::freeUnnecessaryNodes):
      (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlocks):
      (JSC::DFG::CPSRethreadingPhase::propagatePhis):
      (CPSRethreadingPhase):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::run):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::run):
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::run):
      * dfg/DFGDisassembler.cpp:
      (JSC::DFG::Disassembler::Disassembler):
      (JSC::DFG::Disassembler::createDumpList):
      * dfg/DFGDisassembler.h:
      (JSC::DFG::Disassembler::setForBlockIndex):
      * dfg/DFGDominators.cpp:
      (JSC::DFG::Dominators::compute):
      (JSC::DFG::Dominators::iterateForBlock):
      * dfg/DFGDominators.h:
      (JSC::DFG::Dominators::dominates):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::run):
      (JSC::DFG::FixupPhase::fixupNode):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::dump):
      (JSC::DFG::Graph::dumpBlockHeader):
      (JSC::DFG::Graph::handleSuccessor):
      (JSC::DFG::Graph::determineReachability):
      (JSC::DFG::Graph::resetReachability):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::numBlocks):
      (JSC::DFG::Graph::block):
      (JSC::DFG::Graph::lastBlock):
      (Graph):
      (JSC::DFG::Graph::appendBlock):
      (JSC::DFG::Graph::killBlock):
      (DFG):
      * dfg/DFGJITCompiler.cpp:
      (JSC::DFG::JITCompiler::JITCompiler):
      (JSC::DFG::JITCompiler::link):
      * dfg/DFGJITCompiler.h:
      (JSC::DFG::JITCompiler::setForBlockIndex):
      * dfg/DFGNaturalLoops.cpp:
      (JSC::DFG::NaturalLoop::dump):
      (JSC::DFG::NaturalLoops::compute):
      (JSC::DFG::NaturalLoops::loopsOf):
      * dfg/DFGNaturalLoops.h:
      (JSC::DFG::NaturalLoop::NaturalLoop):
      (JSC::DFG::NaturalLoop::addBlock):
      (JSC::DFG::NaturalLoop::header):
      (JSC::DFG::NaturalLoop::at):
      (JSC::DFG::NaturalLoop::operator[]):
      (JSC::DFG::NaturalLoop::contains):
      (NaturalLoop):
      (JSC::DFG::NaturalLoops::headerOf):
      (NaturalLoops):
      * dfg/DFGNode.h:
      (DFG):
      (JSC::DFG::SwitchCase::SwitchCase):
      (JSC::DFG::SwitchCase::withBytecodeIndex):
      (SwitchCase):
      (JSC::DFG::SwitchCase::targetBytecodeIndex):
      (JSC::DFG::SwitchData::SwitchData):
      (JSC::DFG::SwitchData::setFallThroughBytecodeIndex):
      (JSC::DFG::SwitchData::fallThroughBytecodeIndex):
      (SwitchData):
      (JSC::DFG::Node::setTakenBlock):
      (JSC::DFG::Node::setNotTakenBlock):
      (JSC::DFG::Node::takenBlock):
      (JSC::DFG::Node::notTakenBlock):
      (JSC::DFG::Node::successor):
      (JSC::DFG::Node::successorForCondition):
      * dfg/DFGPredictionInjectionPhase.cpp:
      (JSC::DFG::PredictionInjectionPhase::run):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagateForward):
      (JSC::DFG::PredictionPropagationPhase::propagateBackward):
      (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
      (JSC::DFG::SpeculativeJIT::nonSpeculativeCompare):
      (JSC::DFG::SpeculativeJIT::nonSpeculativeStrictEq):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::compileCurrentBlock):
      (JSC::DFG::SpeculativeJIT::compile):
      (JSC::DFG::SpeculativeJIT::createOSREntries):
      (JSC::DFG::SpeculativeJIT::linkOSREntries):
      (JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
      (JSC::DFG::SpeculativeJIT::compileStrictEq):
      (JSC::DFG::SpeculativeJIT::compileRegExpExec):
      (JSC::DFG::SpeculativeJIT::addBranch):
      (JSC::DFG::SpeculativeJIT::linkBranches):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::nextBlock):
      (SpeculativeJIT):
      (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch):
      (JSC::DFG::SpeculativeJIT::branchDouble):
      (JSC::DFG::SpeculativeJIT::branchDoubleNonZero):
      (JSC::DFG::SpeculativeJIT::branch32):
      (JSC::DFG::SpeculativeJIT::branchTest32):
      (JSC::DFG::SpeculativeJIT::branch64):
      (JSC::DFG::SpeculativeJIT::branch8):
      (JSC::DFG::SpeculativeJIT::branchPtr):
      (JSC::DFG::SpeculativeJIT::branchTestPtr):
      (JSC::DFG::SpeculativeJIT::branchTest8):
      (JSC::DFG::SpeculativeJIT::jump):
      (JSC::DFG::SpeculativeJIT::addBranch):
      (JSC::DFG::SpeculativeJIT::StringSwitchCase::StringSwitchCase):
      (StringSwitchCase):
      (JSC::DFG::SpeculativeJIT::BranchRecord::BranchRecord):
      (BranchRecord):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::emitBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativeCompareNull):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
      (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
      (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
      (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch):
      (JSC::DFG::SpeculativeJIT::emitBranch):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGTypeCheckHoistingPhase.cpp:
      (JSC::DFG::TypeCheckHoistingPhase::run):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
      (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):
      (JSC::DFG::TypeCheckHoistingPhase::disableHoistingAcrossOSREntries):
      * dfg/DFGUnificationPhase.cpp:
      (JSC::DFG::UnificationPhase::run):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validate):
      (JSC::DFG::Validate::checkOperand):
      (JSC::DFG::Validate::reportValidationContext):
      * dfg/DFGVirtualRegisterAllocationPhase.cpp:
      (JSC::DFG::VirtualRegisterAllocationPhase::run):
      * ftl/FTLCapabilities.cpp:
      (JSC::FTL::canCompile):
      * ftl/FTLLowerDFGToLLVM.cpp:
      (JSC::FTL::LowerDFGToLLVM::LowerDFGToLLVM):
      (JSC::FTL::LowerDFGToLLVM::lower):
      (JSC::FTL::LowerDFGToLLVM::compileBlock):
      (JSC::FTL::LowerDFGToLLVM::compileJump):
      (JSC::FTL::LowerDFGToLLVM::compileBranch):
      (JSC::FTL::LowerDFGToLLVM::lowBlock):
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      426f5b02
  5. 20 Mar, 2013 1 commit
    • fpizlo@apple.com's avatar
      DFG implementation of op_strcat should inline rope allocations · 4463e44f
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=112780
      
      Reviewed by Oliver Hunt.
              
      This gets rid of the StrCat node and adds a MakeRope node. The MakeRope node can
      take either two or three operands, and allocates a rope string with either two or
      three fibers. (The magic choice of three children for non-VarArg nodes happens to
      match exactly with the magic choice of three fibers for rope strings.)
              
      ValueAdd on KnownString is replaced with MakeRope with two children.
              
      StrCat gets replaced by an appropriate sequence of MakeRope's.
              
      MakeRope does not do the dynamic check to see if its children are empty strings.
      This is replaced by a static check, instead. The downside is that we may use more
      memory if the strings passed to MakeRope turn out to dynamically be empty. The
      upside is that we do fewer checks in the cases where either the strings are not
      empty, or where the strings are statically known to be empty. I suspect both of
      those cases are more common, than the case where the string is dynamically empty.
              
      This also results in some badness for X86. MakeRope needs six registers if it is
      allocating a three-rope. We don't have six registers to spare on X86. Currently,
      the code side-steps this problem by just never usign three-ropes in optimized
      code on X86. All other architectures, including X86_64, don't have this problem.
              
      This is a shocking speed-up. 9% progressions on both V8/splay and
      SunSpider/date-format-xparb. 1% progression on V8v7 overall, and ~0.5% progression
      on SunSpider. 2x speed-up on microbenchmarks that test op_strcat.
      
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      * dfg/DFGAdjacencyList.h:
      (AdjacencyList):
      (JSC::DFG::AdjacencyList::removeEdge):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild):
      * dfg/DFGBackwardsPropagationPhase.cpp:
      (JSC::DFG::BackwardsPropagationPhase::propagate):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::parseBlock):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::putStructureStoreElimination):
      (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::createToString):
      (JSC::DFG::FixupPhase::attemptToForceStringArrayModeByToStringConversion):
      (JSC::DFG::FixupPhase::convertStringAddUse):
      (FixupPhase):
      (JSC::DFG::FixupPhase::convertToMakeRope):
      (JSC::DFG::FixupPhase::fixupMakeRope):
      (JSC::DFG::FixupPhase::attemptToMakeFastStringAdd):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGOperations.cpp:
      * dfg/DFGOperations.h:
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::compileAdd):
      (JSC::DFG::SpeculativeJIT::compileMakeRope):
      (DFG):
      * dfg/DFGSpeculativeJIT.h:
      (JSC::DFG::SpeculativeJIT::callOperation):
      (SpeculativeJIT):
      (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand):
      (JSC::DFG::SpeculateCellOperand::~SpeculateCellOperand):
      (JSC::DFG::SpeculateCellOperand::gpr):
      (JSC::DFG::SpeculateCellOperand::use):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * runtime/JSString.h:
      (JSRopeString):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@146382 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      4463e44f
  6. 19 Mar, 2013 1 commit
  7. 07 Mar, 2013 1 commit
    • fpizlo@apple.com's avatar
      DFG should not get corrupted IR in the case of code that is dead, unreachable,... · fce81034
      fpizlo@apple.com authored
      DFG should not get corrupted IR in the case of code that is dead, unreachable, and contains a chain of nodes that use each other in an untyped way
      https://bugs.webkit.org/show_bug.cgi?id=111783
      
      Source/JavaScriptCore: 
      
      Reviewed by Mark Hahnenberg.
              
      Unreachable code is not touched by CFA and so thinks that even untyped uses are checked.
      But dead untyped uses don't need checks and hence don't need to be Phantom'd. The DCE knew
      this in findTypeCheckRoot() but not in eliminateIrrelevantPhantomChildren(), leading to a
      Phantom node that had another Phantom node as one of its kids.
      
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
      
      LayoutTests: 
      
      Reviewed by Mark Hahnenberg.
      
      * fast/js/dfg-dead-unreachable-code-with-chain-of-dead-unchecked-nodes-expected.txt: Added.
      * fast/js/dfg-dead-unreachable-code-with-chain-of-dead-unchecked-nodes.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-dead-unreachable-code-with-chain-of-dead-unchecked-nodes.js: Added.
      (foo.bar):
      (foo):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@145145 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      fce81034
  8. 06 Mar, 2013 2 commits
    • fpizlo@apple.com's avatar
      Unreviewed, fix an incorrect comment. The comment was a holdover from a... · 3ed34d08
      fpizlo@apple.com authored
      Unreviewed, fix an incorrect comment. The comment was a holdover from a work-in-progress version of this code.
      
      * dfg/DFGDCEPhase.cpp:
      (JSC::DFG::DCEPhase::run):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@144864 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      3ed34d08
    • fpizlo@apple.com's avatar
      DFG DCE might eliminate checks unsoundly · 06f82b56
      fpizlo@apple.com authored
      https://bugs.webkit.org/show_bug.cgi?id=109389
      
      Source/JavaScriptCore: 
      
      Reviewed by Oliver Hunt.
              
      This gets rid of all eager reference counting, and does all dead code elimination
      in one phase - the DCEPhase. This phase also sets up the node reference counts,
      which are then used not just for DCE but also register allocation and stack slot
      allocation.
              
      Doing this required a number of surgical changes in places that previously relied
      on always having liveness information. For example, the structure check hoisting
      phase must now consult whether a VariableAccessData is profitable for unboxing to
      make sure that it doesn't try to do hoisting on set SetLocals. The arguments
      simplification phase employs its own light-weight liveness analysis. Both phases
      previously just used reference counts.
              
      The largest change is that now, dead nodes get turned into Phantoms. Those
      Phantoms will retain those child edges that are not proven. This ensures that any
      type checks performed by a dead node remain even after the node is killed. On the
      other hand, this Phantom conversion means that we need special handling for
      SetLocal. I decided to make the four forms of SetLocal explicit:
              
      MovHint(@a, rK): Just indicates that node @a contains the value that would have
           now been placed into virtual register rK. Does not actually cause @a to be
           stored into rK. This would have previously been a dead SetLocal with @a
           being live. MovHints are always dead.
              
      ZombieHint(rK): Indicates that at this point, register rK will contain a dead
           value and OSR should put Undefined into it. This would have previously been
           a dead SetLocal with @a being dead also. ZombieHints are always dead.
              
      MovHintAndCheck(@a, rK): Identical to MovHint except @a is also type checked,
           according to whatever UseKind the edge to @a has. The type check is always a
           forward exit. MovHintAndChecks are always live, since they are
           NodeMustGenerate. Previously this would have been a dead SetLocal with a
           live @a, and the check would have disappeared. This is one of the bugs that
           this patch solves.
              
      SetLocal(@a, rK): This still does exactly what it does now, if the SetLocal is
           live.
              
      Basically this patch makes it so that dead SetLocals eventually decay to MovHint,
      ZombieHint, or MovHintAndCheck depending on the situation. If the child @a is
      also dead, then you get a ZombieHint. If the child @a is live but the SetLocal
      has a type check and @a's type hasn't been proven to have that type then you get
      a MovHintAndCheck. Otherwise you get a MovHint.
              
      This is performance neutral.
      
      * CMakeLists.txt:
      * GNUmakefile.list.am:
      * JavaScriptCore.xcodeproj/project.pbxproj:
      * Target.pri:
      * dfg/DFGAbstractState.cpp:
      (JSC::DFG::AbstractState::executeEffects):
      (JSC::DFG::AbstractState::mergeStateAtTail):
      * dfg/DFGArgumentsSimplificationPhase.cpp:
      (JSC::DFG::ArgumentsSimplificationPhase::run):
      (ArgumentsSimplificationPhase):
      (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild):
      * dfg/DFGBasicBlock.h:
      (BasicBlock):
      * dfg/DFGBasicBlockInlines.h:
      (DFG):
      * dfg/DFGByteCodeParser.cpp:
      (JSC::DFG::ByteCodeParser::addToGraph):
      (JSC::DFG::ByteCodeParser::insertPhiNode):
      (JSC::DFG::ByteCodeParser::emitFunctionChecks):
      * dfg/DFGCFAPhase.cpp:
      (JSC::DFG::CFAPhase::run):
      * dfg/DFGCFGSimplificationPhase.cpp:
      (JSC::DFG::CFGSimplificationPhase::run):
      (JSC::DFG::CFGSimplificationPhase::keepOperandAlive):
      * dfg/DFGCPSRethreadingPhase.cpp:
      (JSC::DFG::CPSRethreadingPhase::run):
      (JSC::DFG::CPSRethreadingPhase::addPhiSilently):
      * dfg/DFGCSEPhase.cpp:
      (JSC::DFG::CSEPhase::eliminateIrrelevantPhantomChildren):
      (JSC::DFG::CSEPhase::setReplacement):
      (JSC::DFG::CSEPhase::performNodeCSE):
      * dfg/DFGCommon.cpp:
      (WTF::printInternal):
      (WTF):
      * dfg/DFGCommon.h:
      (WTF):
      * dfg/DFGConstantFoldingPhase.cpp:
      (JSC::DFG::ConstantFoldingPhase::foldConstants):
      (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck):
      (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode):
      * dfg/DFGDCEPhase.cpp: Added.
      (DFG):
      (DCEPhase):
      (JSC::DFG::DCEPhase::DCEPhase):
      (JSC::DFG::DCEPhase::run):
      (JSC::DFG::DCEPhase::findTypeCheckRoot):
      (JSC::DFG::DCEPhase::countEdge):
      (JSC::DFG::DCEPhase::eliminateIrrelevantPhantomChildren):
      (JSC::DFG::performDCE):
      * dfg/DFGDCEPhase.h: Added.
      (DFG):
      * dfg/DFGDriver.cpp:
      (JSC::DFG::compile):
      * dfg/DFGFixupPhase.cpp:
      (JSC::DFG::FixupPhase::fixupNode):
      (JSC::DFG::FixupPhase::checkArray):
      (JSC::DFG::FixupPhase::blessArrayOperation):
      (JSC::DFG::FixupPhase::fixIntEdge):
      (JSC::DFG::FixupPhase::injectInt32ToDoubleNode):
      (JSC::DFG::FixupPhase::truncateConstantToInt32):
      * dfg/DFGGraph.cpp:
      (JSC::DFG::Graph::Graph):
      (JSC::DFG::Graph::dump):
      (DFG):
      * dfg/DFGGraph.h:
      (JSC::DFG::Graph::changeChild):
      (JSC::DFG::Graph::changeEdge):
      (JSC::DFG::Graph::compareAndSwap):
      (JSC::DFG::Graph::clearAndDerefChild):
      (JSC::DFG::Graph::performSubstitution):
      (JSC::DFG::Graph::performSubstitutionForEdge):
      (Graph):
      (JSC::DFG::Graph::substitute):
      * dfg/DFGInsertionSet.h:
      (InsertionSet):
      * dfg/DFGNode.h:
      (JSC::DFG::Node::Node):
      (JSC::DFG::Node::convertToConstant):
      (JSC::DFG::Node::convertToGetLocalUnlinked):
      (JSC::DFG::Node::containsMovHint):
      (Node):
      (JSC::DFG::Node::hasVariableAccessData):
      (JSC::DFG::Node::willHaveCodeGenOrOSR):
      * dfg/DFGNodeType.h:
      (DFG):
      * dfg/DFGPredictionPropagationPhase.cpp:
      (JSC::DFG::PredictionPropagationPhase::propagate):
      * dfg/DFGSpeculativeJIT.cpp:
      (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward):
      (JSC::DFG::SpeculativeJIT::compileMovHint):
      (JSC::DFG::SpeculativeJIT::compileMovHintAndCheck):
      (DFG):
      (JSC::DFG::SpeculativeJIT::compileInlineStart):
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT.h:
      (SpeculativeJIT):
      * dfg/DFGSpeculativeJIT32_64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGSpeculativeJIT64.cpp:
      (JSC::DFG::SpeculativeJIT::compile):
      * dfg/DFGStructureCheckHoistingPhase.cpp:
      (JSC::DFG::StructureCheckHoistingPhase::run):
      (JSC::DFG::StructureCheckHoistingPhase::shouldConsiderForHoisting):
      (StructureCheckHoistingPhase):
      * dfg/DFGValidate.cpp:
      (JSC::DFG::Validate::validate):
      
      LayoutTests: 
      
      Reviewed by Oliver Hunt.
      
      * fast/js/dfg-arguments-osr-exit-multiple-blocks-before-exit-expected.txt: Added.
      * fast/js/dfg-arguments-osr-exit-multiple-blocks-before-exit.html: Added.
      * fast/js/dfg-arguments-osr-exit-multiple-blocks-expected.txt: Added.
      * fast/js/dfg-arguments-osr-exit-multiple-blocks.html: Added.
      * fast/js/jsc-test-list:
      * fast/js/script-tests/dfg-arguments-osr-exit-multiple-blocks-before-exit.js: Added.
      (baz):
      (foo):
      (bar):
      * fast/js/script-tests/dfg-arguments-osr-exit-multiple-blocks.js: Added.
      (baz):
      (foo):
      (bar):
      
      
      
      git-svn-id: http://svn.webkit.org/repository/webkit/trunk@144862 268f45cc-cd09-0410-ab3c-d52691b4dbfc
      06f82b56