Ignore:
Timestamp:
Sep 10, 2013, 8:24:09 PM (12 years ago)
Author:
[email protected]
Message:

Be explicit about backwards propagation properties that care about escaping to bytecode, as opposed to just escaping within DFG code.

Rubber stamped by Mark Hahnenberg.

We need to care about escaping to bytecode if we're doing a lossy optimization,
i.e. the optimization means we produce less information and so we can't rescue
ourselves during OSR exit.

We only need to care about escaping within the DFG code (and can ignore what
might happen in bytecode) if we're doing an optimization that is lossless, i.e.
we can always still reconstruct the values that bytecode wants.

Example #1:

Large int32 + int32 which overflows. We want to optimize away the overflow
check and just do a 32-bit add.


This is lossy; the result should have one extra bit but we simply throw
that bit away by doing a check-less 32-bit add. Hence we need to know that
even the bytecode wouldn't have cared about that bit. This is true in cases
like (a + b) | 0.


Example #2:

Larbe int32 + int32 which overflows. We want to optimize away the overflow
check by doing a 64-bit add.


This is lossless. We can always convert the resulting 64-bit int back to a
double if that's what bytecode wants. Hence we only need to know that the
DFG code won't want to do something to this value that would make 64-bit
ints either unprofitable or unsound.


The backwards propagator's notions of flags (NodeUsedAsValue, etc) are for lossy
optimizations and so should be named in a way that reflects this. This patch
calls then NodeBytecodeUsesAsValue, etc.

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::::executeEffects):

  • dfg/DFGArrayMode.cpp:

(JSC::DFG::ArrayMode::refine):

  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::mergeDefaultFlags):
(JSC::DFG::BackwardsPropagationPhase::propagate):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::addImmediateShouldSpeculateInt32):

  • dfg/DFGNode.h:

(JSC::DFG::Node::arithNodeFlags):

  • dfg/DFGNodeFlags.cpp:

(JSC::DFG::dumpNodeFlags):

  • dfg/DFGNodeFlags.h:

(JSC::DFG::bytecodeUsesAsNumber):
(JSC::DFG::bytecodeCanTruncateInteger):
(JSC::DFG::bytecodeCanIgnoreNegativeZero):
(JSC::DFG::nodeMayNegZero):
(JSC::DFG::nodeCanSpeculateInt32):

  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileDoubleAsInt32):
(JSC::DFG::SpeculativeJIT::compileAdd):
(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithNegate):
(JSC::DFG::SpeculativeJIT::compileArithMul):
(JSC::DFG::SpeculativeJIT::compileArithDiv):
(JSC::DFG::SpeculativeJIT::compileArithMod):

  • dfg/DFGVariableAccessData.h:

(JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileAdd):
(JSC::FTL::LowerDFGToLLVM::compileArithSub):
(JSC::FTL::LowerDFGToLLVM::compileArithMul):
(JSC::FTL::LowerDFGToLLVM::compileArithDiv):
(JSC::FTL::LowerDFGToLLVM::compileArithMod):
(JSC::FTL::LowerDFGToLLVM::compileArithNegate):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r155482 r155497  
    24262426
    24272427    JITCompiler::JumpList failureCases;
    2428     bool negZeroCheck = !nodeCanIgnoreNegativeZero(node->arithNodeFlags());
     2428    bool negZeroCheck = !bytecodeCanIgnoreNegativeZero(node->arithNodeFlags());
    24292429    m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR, negZeroCheck);
    24302430    forwardSpeculationCheck(Overflow, JSValueRegs(), 0, failureCases, ValueRecovery::inFPR(valueFPR));
     
    29302930            GPRTemporary result(this);
    29312931
    2932             if (nodeCanTruncateInteger(node->arithNodeFlags())) {
     2932            if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
    29332933                m_jit.move(op2.gpr(), result.gpr());
    29342934                m_jit.add32(Imm32(imm1), result.gpr());
     
    29452945            GPRTemporary result(this);
    29462946               
    2947             if (nodeCanTruncateInteger(node->arithNodeFlags())) {
     2947            if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
    29482948                m_jit.move(op1.gpr(), result.gpr());
    29492949                m_jit.add32(Imm32(imm2), result.gpr());
     
    29632963        GPRReg gprResult = result.gpr();
    29642964
    2965         if (nodeCanTruncateInteger(node->arithNodeFlags())) {
     2965        if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
    29662966            if (gpr1 == gprResult)
    29672967                m_jit.add32(gpr2, gprResult);
     
    30843084            GPRTemporary result(this);
    30853085
    3086             if (nodeCanTruncateInteger(node->arithNodeFlags())) {
     3086            if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
    30873087                m_jit.move(op1.gpr(), result.gpr());
    30883088                m_jit.sub32(Imm32(imm2), result.gpr());
     
    31063106               
    31073107            m_jit.move(Imm32(imm1), result.gpr());
    3108             if (nodeCanTruncateInteger(node->arithNodeFlags()))
     3108            if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
    31093109                m_jit.sub32(op2.gpr(), result.gpr());
    31103110            else
     
    31193119        GPRTemporary result(this);
    31203120
    3121         if (nodeCanTruncateInteger(node->arithNodeFlags())) {
     3121        if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
    31223122            m_jit.move(op1.gpr(), result.gpr());
    31233123            m_jit.sub32(op2.gpr(), result.gpr());
     
    31573157        m_jit.move(op1.gpr(), result.gpr());
    31583158
    3159         if (nodeCanTruncateInteger(node->arithNodeFlags()))
     3159        if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
    31603160            m_jit.neg32(result.gpr());
    31613161        else {
    31623162            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr()));
    3163             if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags()))
     3163            if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags()))
    31643164                speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::Zero, result.gpr()));
    31653165        }
     
    32133213        // fixup phase could not prove that it would be safe, it would have turned us into
    32143214        // a double multiplication.
    3215         if (nodeCanTruncateInteger(node->arithNodeFlags())) {
     3215        if (bytecodeCanTruncateInteger(node->arithNodeFlags())) {
    32163216            m_jit.move(reg1, result.gpr());
    32173217            m_jit.mul32(reg2, result.gpr());
     
    32233223           
    32243224        // Check for negative zero, if the users of this node care about such things.
    3225         if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3225        if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
    32263226            MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
    32273227            speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
     
    32873287   
    32883288        JITCompiler::JumpList done;
    3289         if (nodeUsedAsNumber(node->arithNodeFlags())) {
     3289        if (bytecodeUsesAsNumber(node->arithNodeFlags())) {
    32903290            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
    32913291            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
     
    33153315        // If the user cares about negative zero, then speculate that we're not about
    33163316        // to produce negative zero.
    3317         if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3317        if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
    33183318            MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
    33193319            speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
     
    33353335        // Check that there was no remainder. If there had been, then we'd be obligated to
    33363336        // produce a double result instead.
    3337         if (nodeUsedAsNumber(node->arithNodeFlags()))
     3337        if (bytecodeUsesAsNumber(node->arithNodeFlags()))
    33383338            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
    33393339       
     
    33503350        // If the user cares about negative zero, then speculate that we're not about
    33513351        // to produce negative zero.
    3352         if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3352        if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
    33533353            MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
    33543354            speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
     
    33603360        // Check that there was no remainder. If there had been, then we'd be obligated to
    33613361        // produce a double result instead.
    3362         if (nodeUsedAsNumber(node->arithNodeFlags())) {
     3362        if (bytecodeUsesAsNumber(node->arithNodeFlags())) {
    33633363            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotient.gpr(), op2GPR, multiplyAnswer.gpr()));
    33643364            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::NotEqual, multiplyAnswer.gpr(), op1GPR));
     
    34493449                m_jit.add32(dividendGPR, resultGPR);
    34503450               
    3451                 if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3451                if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
    34523452                    // Check that we're not about to create negative zero.
    34533453                    JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
     
    34863486                m_jit.assembler().cdq();
    34873487                m_jit.assembler().idivl_r(scratchGPR);
    3488                 if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3488                if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
    34893489                    JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
    34903490                    speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
     
    35433543        // FIXME: -2^31 / -1 will actually yield negative zero, so we could have a
    35443544        // separate case for that. But it probably doesn't matter so much.
    3545         if (nodeUsedAsNumber(node->arithNodeFlags())) {
     3545        if (bytecodeUsesAsNumber(node->arithNodeFlags())) {
    35463546            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
    35473547            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
     
    35823582
    35833583        // Check that we're not about to create negative zero.
    3584         if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3584        if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
    35853585            JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
    35863586            speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
     
    36093609        // If the user cares about negative zero, then speculate that we're not about
    36103610        // to produce negative zero.
    3611         if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
     3611        if (!bytecodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
    36123612            // Check that we're not about to create negative zero.
    36133613            JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
Note: See TracChangeset for help on using the changeset viewer.