Ignore:
Timestamp:
Feb 13, 2014, 2:46:51 PM (11 years ago)
Author:
[email protected]
Message:

Hoist and combine array bounds checks
https://bugs.webkit.org/show_bug.cgi?id=125433

Source/JavaScriptCore:

Reviewed by Mark Hahnenberg.

This adds a phase for reasoning about overflow checks and array bounds checks. It's
block-local, and removes both overflow checks and bounds checks in one go.

This also improves reasoning about commutative operations, and CSE between
CheckOverflow and Unchecked arithmetic.

This strangely uncovered a DFG backend bug where we were trying to extract an int32
from a constant even when that constant was just simply a number. I fixed that bug.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::set):

  • dfg/DFGArgumentsSimplificationPhase.cpp:

(JSC::DFG::ArgumentsSimplificationPhase::run):

  • dfg/DFGArithMode.h:

(JSC::DFG::subsumes):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleIntrinsic):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::pureCSE):
(JSC::DFG::CSEPhase::int32ToDoubleCSE):
(JSC::DFG::CSEPhase::performNodeCSE):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGEdge.cpp:

(JSC::DFG::Edge::dump):

  • dfg/DFGEdge.h:

(JSC::DFG::Edge::sanitized):
(JSC::DFG::Edge::hash):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::valueOfInt32Constant):

  • dfg/DFGInsertionSet.h:

(JSC::DFG::InsertionSet::insertConstant):

  • dfg/DFGIntegerCheckCombiningPhase.cpp: Added.

(JSC::DFG::IntegerCheckCombiningPhase::IntegerCheckCombiningPhase):
(JSC::DFG::IntegerCheckCombiningPhase::run):
(JSC::DFG::IntegerCheckCombiningPhase::handleBlock):
(JSC::DFG::IntegerCheckCombiningPhase::rangeKeyAndAddend):
(JSC::DFG::IntegerCheckCombiningPhase::isValid):
(JSC::DFG::IntegerCheckCombiningPhase::insertAdd):
(JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd):
(JSC::DFG::performIntegerCheckCombining):

  • dfg/DFGIntegerCheckCombiningPhase.h: Added.
  • dfg/DFGNode.h:

(JSC::DFG::Node::willHaveCodeGenOrOSR):

  • dfg/DFGNodeType.h:
  • dfg/DFGPlan.cpp:

(JSC::DFG::Plan::compileInThreadImpl):

  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::safeToExecute):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileAdd):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

  • dfg/DFGStrengthReductionPhase.cpp:

(JSC::DFG::StrengthReductionPhase::handleNode):
(JSC::DFG::StrengthReductionPhase::handleCommutativity):

  • dfg/DFGTypeCheckHoistingPhase.cpp:

(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks):
(JSC::DFG::TypeCheckHoistingPhase::identifyRedundantArrayChecks):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileNode):

  • jsc.cpp:

(GlobalObject::finishCreation):
(functionFalse):

  • runtime/Identifier.h:
  • runtime/Intrinsic.h:
  • runtime/JSObject.h:
  • tests/stress/get-by-id-untyped.js: Added.

(foo):

  • tests/stress/inverted-additive-subsumption.js: Added.

(foo):

  • tests/stress/redundant-add-overflow-checks.js: Added.

(foo):

  • tests/stress/redundant-array-bounds-checks-addition-skip-first.js: Added.

(foo):
(arraycmp):

  • tests/stress/redundant-array-bounds-checks-addition.js: Added.

(foo):
(arraycmp):

  • tests/stress/redundant-array-bounds-checks-unchecked-addition.js: Added.

(foo):
(arraycmp):

  • tests/stress/redundant-array-bounds-checks.js: Added.

(foo):
(arraycmp):

  • tests/stress/tricky-array-bounds-checks.js: Added.

(foo):
(arraycmp):

Source/WTF:

Reviewed by Mark Hahnenberg.

  • GNUmakefile.list.am:
  • WTF.vcxproj/WTF.vcxproj:
  • WTF.xcodeproj/project.pbxproj:
  • wtf/CMakeLists.txt:
  • wtf/HashMethod.h: Added.

(WTF::HashMethod::operator()):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp

    r163946 r164059  
    128128    Node* pureCSE(Node* node)
    129129    {
    130         Edge child1 = node->child1();
    131         Edge child2 = node->child2();
    132         Edge child3 = node->child3();
     130        Edge child1 = node->child1().sanitized();
     131        Edge child2 = node->child2().sanitized();
     132        Edge child3 = node->child3().sanitized();
    133133       
    134134        for (unsigned i = endIndexForPureCSE(); i--;) {
     
    140140                continue;
    141141           
    142             if (node->hasArithMode()) {
    143                 if (node->arithMode() != otherNode->arithMode())
    144                     continue;
    145             }
    146            
    147             Edge otherChild = otherNode->child1();
     142            Edge otherChild = otherNode->child1().sanitized();
    148143            if (!otherChild)
    149144                return otherNode;
     
    151146                continue;
    152147           
    153             otherChild = otherNode->child2();
     148            otherChild = otherNode->child2().sanitized();
    154149            if (!otherChild)
    155150                return otherNode;
     
    157152                continue;
    158153           
    159             otherChild = otherNode->child3();
     154            otherChild = otherNode->child3().sanitized();
    160155            if (!otherChild)
    161156                return otherNode;
     
    176171            switch (otherNode->op()) {
    177172            case Int32ToDouble:
    178                 if (otherNode->child1() == node->child1())
     173                if (otherNode->child1().sanitized() == node->child1().sanitized())
    179174                    return otherNode;
    180175                break;
     
    10961091        case BitLShift:
    10971092        case BitURShift:
    1098         case ArithAdd:
    1099         case ArithSub:
    1100         case ArithNegate:
    1101         case ArithMul:
    1102         case ArithMod:
    1103         case ArithDiv:
    11041093        case ArithAbs:
    11051094        case ArithMin:
     
    11161105        case IsObject:
    11171106        case IsFunction:
    1118         case DoubleAsInt32:
    11191107        case LogicalNot:
    11201108        case SkipTopScope:
     
    11321120            setReplacement(pureCSE(node));
    11331121            break;
     1122           
     1123        case ArithAdd:
     1124        case ArithSub:
     1125        case ArithNegate:
     1126        case ArithMul:
     1127        case ArithDiv:
     1128        case ArithMod:
     1129        case UInt32ToNumber:
     1130        case DoubleAsInt32: {
     1131            if (cseMode == StoreElimination)
     1132                break;
     1133            Node* candidate = pureCSE(node);
     1134            if (!candidate)
     1135                break;
     1136            if (!subsumes(candidate->arithMode(), node->arithMode())) {
     1137                if (!subsumes(node->arithMode(), candidate->arithMode()))
     1138                    break;
     1139                candidate->setArithMode(node->arithMode());
     1140            }
     1141            setReplacement(candidate);
     1142            break;
     1143        }
    11341144           
    11351145        case Int32ToDouble:
     
    14081418        case Phantom:
    14091419            // FIXME: we ought to remove Phantom's that have no children.
     1420            // NB. It would be incorrect to do this for HardPhantom. In fact, the whole point
     1421            // of HardPhantom is that we *don't* do this for HardPhantoms, since they signify
     1422            // a more strict kind of liveness than the Phantom bytecode liveness.
    14101423            eliminateIrrelevantPhantomChildren(node);
    14111424            break;
Note: See TracChangeset for help on using the changeset viewer.