Ignore:
Timestamp:
Feb 17, 2016, 3:35:11 PM (9 years ago)
Author:
[email protected]
Message:

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

Patch by Benjamin Poulain <[email protected]> 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):

File:
1 edited

Legend:

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