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/DFGNodeFlags.h

    r155482 r155497  
    3838// Entries in the NodeType enum (below) are composed of an id, a result type (possibly none)
    3939// and some additional informative flags (must generate, is constant, etc).
    40 #define NodeResultMask              0x7
    41 #define NodeResultJS                0x1
    42 #define NodeResultNumber            0x2
    43 #define NodeResultInt32             0x3
    44 #define NodeResultBoolean           0x4
    45 #define NodeResultStorage           0x5
     40#define NodeResultMask                   0x0007
     41#define NodeResultJS                     0x0001
     42#define NodeResultNumber                 0x0002
     43#define NodeResultInt32                  0x0003
     44#define NodeResultBoolean                0x0004
     45#define NodeResultStorage                0x0005
    4646                               
    47 #define NodeMustGenerate           0x08 // set on nodes that have side effects, and may not trivially be removed by DCE.
    48 #define NodeHasVarArgs             0x10
    49 #define NodeClobbersWorld          0x20
    50 #define NodeMightClobber           0x40
     47#define NodeMustGenerate                 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE.
     48#define NodeHasVarArgs                   0x0010
     49#define NodeClobbersWorld                0x0020
     50#define NodeMightClobber                 0x0040
    5151                               
    52 #define NodeBehaviorMask          0x180
    53 #define NodeMayOverflow           0x080
    54 #define NodeMayNegZero            0x100
     52#define NodeBehaviorMask                 0x0180
     53#define NodeMayOverflow                  0x0080
     54#define NodeMayNegZero                   0x0100
    5555                               
    56 #define NodeBackPropMask         0x1E00
    57 #define NodeUseBottom            0x0000
    58 #define NodeUsedAsNumber         0x0200 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results.
    59 #define NodeNeedsNegZero         0x0400 // The result of this computation may be used in a context that observes -0.
    60 #define NodeUsedAsOther          0x0800 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined).
    61 #define NodeUsedAsValue          (NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther)
    62 #define NodeUsedAsInt            0x1000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values.
     56#define NodeBytecodeBackPropMask         0x1E00
     57#define NodeBytecodeUseBottom            0x0000
     58#define NodeBytecodeUsesAsNumber         0x0200 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results.
     59#define NodeBytecodeNeedsNegZero         0x0400 // The result of this computation may be used in a context that observes -0.
     60#define NodeBytecodeUsesAsOther          0x0800 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined).
     61#define NodeBytecodeUsesAsValue          (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeUsesAsOther)
     62#define NodeBytecodeUsesAsInt            0x1000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values.
    6363
    64 #define NodeArithFlagsMask       (NodeBehaviorMask | NodeBackPropMask)
     64#define NodeArithFlagsMask               (NodeBehaviorMask | NodeBytecodeBackPropMask)
    6565
    66 #define NodeDoesNotExit          0x2000 // This flag is negated to make it natural for the default to be that a node does exit.
     66#define NodeDoesNotExit                  0x2000 // This flag is negated to make it natural for the default to be that a node does exit.
    6767
    68 #define NodeRelevantToOSR        0x4000
     68#define NodeRelevantToOSR                0x4000
    6969
    70 #define NodeExitsForward         0x8000
     70#define NodeExitsForward                 0x8000
    7171
    7272typedef uint32_t NodeFlags;
    7373
    74 static inline bool nodeUsedAsNumber(NodeFlags flags)
     74static inline bool bytecodeUsesAsNumber(NodeFlags flags)
    7575{
    76     return !!(flags & NodeUsedAsNumber);
     76    return !!(flags & NodeBytecodeUsesAsNumber);
    7777}
    7878
    79 static inline bool nodeCanTruncateInteger(NodeFlags flags)
     79static inline bool bytecodeCanTruncateInteger(NodeFlags flags)
    8080{
    81     return !nodeUsedAsNumber(flags);
     81    return !bytecodeUsesAsNumber(flags);
    8282}
    8383
    84 static inline bool nodeCanIgnoreNegativeZero(NodeFlags flags)
     84static inline bool bytecodeCanIgnoreNegativeZero(NodeFlags flags)
    8585{
    86     return !(flags & NodeNeedsNegZero);
     86    return !(flags & NodeBytecodeNeedsNegZero);
    8787}
    8888
     
    9292}
    9393
     94static inline bool nodeMayNegZero(NodeFlags flags)
     95{
     96    return !!(flags & NodeMayNegZero);
     97}
     98
    9499static inline bool nodeCanSpeculateInt32(NodeFlags flags)
    95100{
    96     if (flags & NodeMayOverflow)
    97         return !nodeUsedAsNumber(flags);
     101    if (nodeMayOverflow(flags))
     102        return !bytecodeUsesAsNumber(flags);
    98103   
    99     if (flags & NodeMayNegZero)
    100         return nodeCanIgnoreNegativeZero(flags);
     104    if (nodeMayNegZero(flags))
     105        return bytecodeCanIgnoreNegativeZero(flags);
    101106   
    102107    return true;
Note: See TracChangeset for help on using the changeset viewer.