Changeset 196726 in webkit


Ignore:
Timestamp:
Feb 17, 2016 3:35:11 PM (8 years ago)
Author:
commit-queue@webkit.org
Message:

[JSC] Remove the overflow check on ArithAbs when possible
https://bugs.webkit.org/show_bug.cgi?id=154325

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-02-17
Reviewed by Filip Pizlo.

This patch adds support for ArithMode for ArithAbs.

It is useful for kraken tests where Math.abs() is used
on values for which the range is known.

For example, imaging-gaussian-blur has two Math.abs() with
integers that are always in a small range around zero.
The IntegerRangeOptimizationPhase detects the range correctly
so we can just update the ArithMode depending on the input.

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGIntegerRangeOptimizationPhase.cpp:
  • dfg/DFGNode.h:

(JSC::DFG::Node::convertToArithNegate):
(JSC::DFG::Node::hasArithMode):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::compileArithAbs):

  • tests/stress/arith-abs-integer-range-optimization.js: Added.

(negativeRange):
(negativeRangeIncludingZero):
(negativeRangeWithOverflow):
(positiveRange):
(positiveRangeIncludingZero):
(rangeWithoutOverflow):

  • tests/stress/arith-abs-with-bitwise-or-zero.js: Added.

(opaqueAbs):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r196723 r196726  
     12016-02-17  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        [JSC] Remove the overflow check on ArithAbs when possible
     4        https://bugs.webkit.org/show_bug.cgi?id=154325
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This patch adds support for ArithMode for ArithAbs.
     9
     10        It is useful for kraken tests where Math.abs() is used
     11        on values for which the range is known.
     12
     13        For example, imaging-gaussian-blur has two Math.abs() with
     14        integers that are always in a small range around zero.
     15        The IntegerRangeOptimizationPhase detects the range correctly
     16        so we can just update the ArithMode depending on the input.
     17
     18        * dfg/DFGFixupPhase.cpp:
     19        (JSC::DFG::FixupPhase::fixupNode):
     20        * dfg/DFGIntegerRangeOptimizationPhase.cpp:
     21        * dfg/DFGNode.h:
     22        (JSC::DFG::Node::convertToArithNegate):
     23        (JSC::DFG::Node::hasArithMode):
     24        * dfg/DFGSpeculativeJIT64.cpp:
     25        (JSC::DFG::SpeculativeJIT::compile):
     26        * ftl/FTLLowerDFGToLLVM.cpp:
     27        (JSC::FTL::DFG::LowerDFGToLLVM::compileArithAbs):
     28        * tests/stress/arith-abs-integer-range-optimization.js: Added.
     29        (negativeRange):
     30        (negativeRangeIncludingZero):
     31        (negativeRangeWithOverflow):
     32        (positiveRange):
     33        (positiveRangeIncludingZero):
     34        (rangeWithoutOverflow):
     35        * tests/stress/arith-abs-with-bitwise-or-zero.js: Added.
     36        (opaqueAbs):
     37
    1382016-02-17  Chris Dumez  <cdumez@apple.com>
    239
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r196642 r196726  
    335335            if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) {
    336336                fixIntOrBooleanEdge(node->child1());
     337                if (bytecodeCanTruncateInteger(node->arithNodeFlags()))
     338                    node->setArithMode(Arith::Unchecked);
     339                else
     340                    node->setArithMode(Arith::CheckOverflow);
    337341                break;
    338342            }
  • trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp

    r195585 r196726  
    12041204                // call executeNode() before we optimize.
    12051205                switch (node->op()) {
     1206                case ArithAbs: {
     1207                    if (node->child1().useKind() != Int32Use)
     1208                        break;
     1209
     1210                    auto iter = m_relationships.find(node->child1().node());
     1211                    if (iter == m_relationships.end())
     1212                        break;
     1213
     1214                    int minValue = std::numeric_limits<int>::min();
     1215                    int maxValue = std::numeric_limits<int>::max();
     1216                    for (Relationship relationship : iter->value) {
     1217                        minValue = std::max(minValue, relationship.minValueOfLeft());
     1218                        maxValue = std::min(maxValue, relationship.maxValueOfLeft());
     1219                    }
     1220
     1221                    executeNode(block->at(nodeIndex));
     1222
     1223                    if (minValue >= 0) {
     1224                        node->convertToIdentityOn(node->child1().node());
     1225                        changed = true;
     1226                        break;
     1227                    }
     1228                    if (maxValue <= 0) {
     1229                        node->convertToArithNegate();
     1230                        if (minValue > std::numeric_limits<int>::min())
     1231                            node->setArithMode(Arith::Unchecked);
     1232                        changed = true;
     1233                        break;
     1234                    }
     1235                    if (minValue > std::numeric_limits<int>::min()) {
     1236                        node->setArithMode(Arith::Unchecked);
     1237                        changed = true;
     1238                        break;
     1239                    }
     1240
     1241                    break;
     1242                }
    12061243                case ArithAdd: {
    12071244                    if (!node->isBinaryUseKind(Int32Use))
     
    13081345            setRelationship(Relationship::safeCreate(node->child1().node(), node->child2().node(), Relationship::LessThan));
    13091346            setRelationship(Relationship::safeCreate(node->child1().node(), m_zero, Relationship::GreaterThan, -1));
     1347            break;
     1348        }
     1349
     1350        case ArithAbs: {
     1351            if (node->child1().useKind() != Int32Use)
     1352                break;
     1353            setRelationship(Relationship(node, m_zero, Relationship::GreaterThan, -1));
    13101354            break;
    13111355        }
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r194613 r196726  
    650650        child2() = Edge();
    651651        m_op = ArithSqrt;
     652    }
     653
     654    void convertToArithNegate()
     655    {
     656        ASSERT(m_op == ArithAbs && child1().useKind() == Int32Use);
     657        m_op = ArithNegate;
    652658    }
    653659   
     
    16791685    {
    16801686        switch (op()) {
     1687        case ArithAbs:
    16811688        case ArithAdd:
    16821689        case ArithSub:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r195488 r196726  
    23032303            m_jit.add32(scratch.gpr(), result.gpr());
    23042304            m_jit.xor32(scratch.gpr(), result.gpr());
    2305             speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
     2305            if (shouldCheckOverflow(node->arithMode()))
     2306                speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
    23062307            int32Result(result.gpr(), node);
    23072308            break;
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r196685 r196726  
    21252125        case Int32Use: {
    21262126            LValue value = lowInt32(m_node->child1());
    2127            
     2127
    21282128            LValue mask = m_out.aShr(value, m_out.constInt32(31));
    21292129            LValue result = m_out.bitXor(mask, m_out.add(mask, value));
    2130            
    2131             speculate(Overflow, noValue(), 0, m_out.equal(result, m_out.constInt32(1 << 31)));
    2132            
     2130
     2131            if (shouldCheckOverflow(m_node->arithMode()))
     2132                speculate(Overflow, noValue(), 0, m_out.equal(result, m_out.constInt32(1 << 31)));
     2133
    21332134            setInt32(result);
    21342135            break;
Note: See TracChangeset for help on using the changeset viewer.