Ignore:
Timestamp:
Dec 8, 2015, 4:12:48 PM (10 years ago)
Author:
[email protected]
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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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();
Note: See TracChangeset for help on using the changeset viewer.