Changeset 193793 in webkit


Ignore:
Timestamp:
Dec 8, 2015 4:12:48 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

DFG and FTL should be resilient against cases where both snippet operands are constant.
https://bugs.webkit.org/show_bug.cgi?id=152017

Reviewed by Michael Saboff.

The DFG front end may not always constant fold cases where both operands are
constant. As a result, the DFG and FTL back ends needs to be resilient against
this when using snippet generators since the generators do not support the case
where both operands are constant. The strategy for handling this 2 const operands
case is to treat at least one of them as a variable if both are constant.

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileValueAdd):

  • Also remove the case for folding 2 constant operands. It is the front end's job to do so, not the back end here.

(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithMul):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::compileValueAdd):
(JSC::FTL::DFG::LowerDFGToLLVM::compileArithMul):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r193788 r193793  
     12015-12-08  Mark Lam  <mark.lam@apple.com>
     2
     3        DFG and FTL should be resilient against cases where both snippet operands are constant.
     4        https://bugs.webkit.org/show_bug.cgi?id=152017
     5
     6        Reviewed by Michael Saboff.
     7
     8        The DFG front end may not always constant fold cases where both operands are
     9        constant.  As a result, the DFG and FTL back ends needs to be resilient against
     10        this when using snippet generators since the generators do not support the case
     11        where both operands are constant.  The strategy for handling this 2 const operands
     12        case is to treat at least one of them as a variable if both are constant.
     13
     14        * dfg/DFGSpeculativeJIT.cpp:
     15        (JSC::DFG::SpeculativeJIT::compileValueAdd):
     16        - Also remove the case for folding 2 constant operands.  It is the front end's
     17          job to do so, not the back end here.
     18
     19        (JSC::DFG::SpeculativeJIT::compileArithSub):
     20        (JSC::DFG::SpeculativeJIT::compileArithMul):
     21        * ftl/FTLLowerDFGToLLVM.cpp:
     22        (JSC::FTL::DFG::LowerDFGToLLVM::compileValueAdd):
     23        (JSC::FTL::DFG::LowerDFGToLLVM::compileArithMul):
     24
    1252015-12-08  Mark Lam  <mark.lam@apple.com>
    226
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r193781 r193793  
    27892789void SpeculativeJIT::compileValueAdd(Node* node)
    27902790{
    2791     if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node())) {
    2792         JSValueOperand left(this, node->child1());
    2793         JSValueOperand right(this, node->child2());
     2791    Edge& leftChild = node->child1();
     2792    Edge& rightChild = node->child2();
     2793
     2794    if (isKnownNotNumber(leftChild.node()) || isKnownNotNumber(rightChild.node())) {
     2795        JSValueOperand left(this, leftChild);
     2796        JSValueOperand right(this, rightChild);
    27942797        JSValueRegs leftRegs = left.jsValueRegs();
    27952798        JSValueRegs rightRegs = right.jsValueRegs();
     
    28062809        m_jit.exceptionCheck();
    28072810   
    2808         jsValueResult(resultRegs, node);
    2809         return;
    2810     }
    2811 
    2812     bool leftIsConstInt32 = node->child1()->isInt32Constant();
    2813     bool rightIsConstInt32 = node->child2()->isInt32Constant();
    2814 
    2815     // The DFG does not always fold the sum of 2 constant int operands together.
    2816     if (leftIsConstInt32 && rightIsConstInt32) {
    2817 #if USE(JSVALUE64)
    2818         GPRTemporary result(this);
    2819         JSValueRegs resultRegs = JSValueRegs(result.gpr());
    2820 #else
    2821         GPRTemporary resultTag(this);
    2822         GPRTemporary resultPayload(this);
    2823         JSValueRegs resultRegs = JSValueRegs(resultPayload.gpr(), resultTag.gpr());
    2824 #endif
    2825         int64_t leftConst = node->child1()->asInt32();
    2826         int64_t rightConst = node->child2()->asInt32();
    2827         int64_t resultConst = leftConst + rightConst;
    2828         m_jit.moveValue(JSValue(resultConst), resultRegs);
    28292811        jsValueResult(resultRegs, node);
    28302812        return;
     
    28572839#endif
    28582840
    2859     SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
    2860     SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
    2861 
    2862     if (leftIsConstInt32)
    2863         leftOperand.setConstInt32(node->child1()->asInt32());
    2864     if (rightIsConstInt32)
    2865         rightOperand.setConstInt32(node->child2()->asInt32());
     2841    SnippetOperand leftOperand(m_state.forNode(leftChild).resultType());
     2842    SnippetOperand rightOperand(m_state.forNode(rightChild).resultType());
     2843
     2844    // The snippet generator does not support both operands being constant. If the left
     2845    // operand is already const, we'll ignore the right operand's constness.
     2846    if (leftChild->isInt32Constant())
     2847        leftOperand.setConstInt32(leftChild->asInt32());
     2848    else if (rightChild->isInt32Constant())
     2849        rightOperand.setConstInt32(rightChild->asInt32());
    28662850
    28672851    ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
    28682852
    28692853    if (!leftOperand.isConst()) {
    2870         left = JSValueOperand(this, node->child1());
     2854        left = JSValueOperand(this, leftChild);
    28712855        leftRegs = left->jsValueRegs();
    28722856    }
    28732857    if (!rightOperand.isConst()) {
    2874         right = JSValueOperand(this, node->child2());
     2858        right = JSValueOperand(this, rightChild);
    28752859        rightRegs = right->jsValueRegs();
    28762860    }
     
    28872871    silentSpillAllRegisters(resultRegs);
    28882872
    2889     if (leftIsConstInt32) {
     2873    if (leftOperand.isConst()) {
    28902874        leftRegs = resultRegs;
    2891         int64_t leftConst = node->child1()->asInt32();
    2892         m_jit.moveValue(JSValue(leftConst), leftRegs);
    2893     } else if (rightIsConstInt32) {
     2875        m_jit.moveValue(leftChild->asJSValue(), leftRegs);
     2876    } else if (rightOperand.isConst()) {
    28942877        rightRegs = resultRegs;
    2895         int64_t rightConst = node->child2()->asInt32();
    2896         m_jit.moveValue(JSValue(rightConst), rightRegs);
     2878        m_jit.moveValue(rightChild->asJSValue(), rightRegs);
    28972879    }
    28982880
     
    32103192
    32113193    case UntypedUse: {
    3212         JSValueOperand left(this, node->child1());
    3213         JSValueOperand right(this, node->child2());
     3194        Edge& leftChild = node->child1();
     3195        Edge& rightChild = node->child2();
     3196
     3197        JSValueOperand left(this, leftChild);
     3198        JSValueOperand right(this, rightChild);
    32143199
    32153200        JSValueRegs leftRegs = left.jsValueRegs();
     
    32363221#endif
    32373222
    3238         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
    3239         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
     3223        SnippetOperand leftOperand(m_state.forNode(leftChild).resultType());
     3224        SnippetOperand rightOperand(m_state.forNode(rightChild).resultType());
    32403225
    32413226        JITSubGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs,
     
    35023487        SnippetOperand rightOperand(m_state.forNode(rightChild).resultType());
    35033488
     3489        // The snippet generator does not support both operands being constant. If the left
     3490        // operand is already const, we'll ignore the right operand's constness.
    35043491        if (leftChild->isInt32Constant())
    35053492            leftOperand.setConstInt32(leftChild->asInt32());
    3506         if (rightChild->isInt32Constant())
     3493        else if (rightChild->isInt32Constant())
    35073494            rightOperand.setConstInt32(rightChild->asInt32());
    35083495
    3509         RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
     3496        ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
    35103497
    35113498        if (!leftOperand.isPositiveConstInt32()) {
     
    35323519            int64_t leftConst = leftOperand.asConstInt32();
    35333520            m_jit.moveValue(JSValue(leftConst), leftRegs);
    3534         }
    3535         if (rightOperand.isPositiveConstInt32()) {
     3521        } else if (rightOperand.isPositiveConstInt32()) {
    35363522            rightRegs = resultRegs;
    35373523            int64_t rightConst = rightOperand.asConstInt32();
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r193781 r193793  
    15281528        SnippetOperand rightOperand(abstractValue(rightChild).resultType());
    15291529
    1530         // The DFG does not always fold the sum of 2 constant int operands together.
    15311530        // Because the snippet does not support both operands being constant, if the left
    15321531        // operand is already a constant, we'll just pretend the right operand is not.
    15331532        if (leftChild->isInt32Constant())
    15341533            leftOperand.setConstInt32(leftChild->asInt32());
    1535         if (!leftOperand.isConst() && rightChild->isInt32Constant())
     1534        else if (rightChild->isInt32Constant())
    15361535            rightOperand.setConstInt32(rightChild->asInt32());
    15371536
     
    18531852            SnippetOperand rightOperand(abstractValue(rightChild).resultType());
    18541853
     1854            // Because the snippet does not support both operands being constant, if the left
     1855            // operand is already a constant, we'll just pretend the right operand is not.
    18551856            if (leftChild->isInt32Constant())
    18561857                leftOperand.setConstInt32(leftChild->asInt32());
    1857             if (rightChild->isInt32Constant())
     1858            else if (rightChild->isInt32Constant())
    18581859                rightOperand.setConstInt32(rightChild->asInt32());
    18591860
Note: See TracChangeset for help on using the changeset viewer.