⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 106879 in webkit


Ignore:
Timestamp:
Feb 6, 2012, 5:07:32 PM (15 years ago)
Author:
fpizlo@apple.com
Message:

ValueToNumber and ValueToDouble nodes don't do anything and should be removed
https://bugs.webkit.org/show_bug.cgi?id=77855
<rdar://problem/10811325>

Reviewed by Gavin Barraclough.

Removed ValueToNumber and ValueToDouble, because the only thing they were doing
was wasting registers.

This looks like a 1% win on V8 (with a 5% win on crypto) and a 2-3% win on Kraken,
mostly due to a >10% win on gaussian-blur. No win anywhere else.

  • dfg/DFGAbstractState.cpp:

(JSC::DFG::AbstractState::execute):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::getToInt32):
(ByteCodeParser):
(JSC::DFG::ByteCodeParser::handleMinMax):
(JSC::DFG::ByteCodeParser::handleIntrinsic):
(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGNode.h:

(DFG):
(JSC::DFG::Node::hasArithNodeFlags):

  • dfg/DFGPropagator.cpp:

(JSC::DFG::Propagator::propagateArithNodeFlags):
(JSC::DFG::Propagator::propagateNodePredictions):
(JSC::DFG::Propagator::vote):
(JSC::DFG::Propagator::doRoundOfDoubleVoting):
(Propagator):
(JSC::DFG::Propagator::fixupNode):
(JSC::DFG::Propagator::canonicalize):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):

  • dfg/DFGSpeculativeJIT32_64.cpp:

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

  • dfg/DFGSpeculativeJIT64.cpp:

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

Location:
trunk/Source/JavaScriptCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r106796 r106879  
     12012-02-06  Filip Pizlo  <fpizlo@apple.com>
     2
     3        ValueToNumber and ValueToDouble nodes don't do anything and should be removed
     4        https://bugs.webkit.org/show_bug.cgi?id=77855
     5        <rdar://problem/10811325>
     6
     7        Reviewed by Gavin Barraclough.
     8       
     9        Removed ValueToNumber and ValueToDouble, because the only thing they were doing
     10        was wasting registers.
     11       
     12        This looks like a 1% win on V8 (with a 5% win on crypto) and a 2-3% win on Kraken,
     13        mostly due to a >10% win on gaussian-blur. No win anywhere else.
     14
     15        * dfg/DFGAbstractState.cpp:
     16        (JSC::DFG::AbstractState::execute):
     17        * dfg/DFGByteCodeParser.cpp:
     18        (JSC::DFG::ByteCodeParser::getToInt32):
     19        (ByteCodeParser):
     20        (JSC::DFG::ByteCodeParser::handleMinMax):
     21        (JSC::DFG::ByteCodeParser::handleIntrinsic):
     22        (JSC::DFG::ByteCodeParser::parseBlock):
     23        * dfg/DFGNode.h:
     24        (DFG):
     25        (JSC::DFG::Node::hasArithNodeFlags):
     26        * dfg/DFGPropagator.cpp:
     27        (JSC::DFG::Propagator::propagateArithNodeFlags):
     28        (JSC::DFG::Propagator::propagateNodePredictions):
     29        (JSC::DFG::Propagator::vote):
     30        (JSC::DFG::Propagator::doRoundOfDoubleVoting):
     31        (Propagator):
     32        (JSC::DFG::Propagator::fixupNode):
     33        (JSC::DFG::Propagator::canonicalize):
     34        * dfg/DFGSpeculativeJIT.cpp:
     35        (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor):
     36        * dfg/DFGSpeculativeJIT32_64.cpp:
     37        (JSC::DFG::SpeculativeJIT::compile):
     38        * dfg/DFGSpeculativeJIT64.cpp:
     39        (JSC::DFG::SpeculativeJIT::compile):
     40
    1412012-02-06  Patrick Gansterer  <paroga@webkit.org>
    242
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp

    r106502 r106879  
    263263        break;
    264264           
    265     case ValueToNumber:
    266         if (m_graph[node.child1()].shouldNotSpeculateInteger()) {
    267             forNode(node.child1()).filter(PredictNumber);
    268             forNode(nodeIndex).set(PredictDouble);
    269             break;
    270         }
    271            
    272         forNode(node.child1()).filter(PredictInt32);
    273         forNode(nodeIndex).set(PredictInt32);
    274         break;
    275            
    276     case ValueToDouble:
    277         forNode(node.child1()).filter(PredictNumber);
    278         forNode(nodeIndex).set(PredictDouble);
    279         break;
    280            
    281265    case ValueAdd:
    282266    case ArithAdd: {
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r106775 r106879  
    314314        return toInt32(get(operand));
    315315    }
    316     NodeIndex getToNumber(int operand)
    317     {
    318         return toNumber(get(operand));
    319     }
    320316
    321317    // Perform an ES5 ToInt32 operation - returns a node of type NodeResultInt32.
     
    342338    }
    343339
    344     // Perform an ES5 ToNumber operation - returns a node of type NodeResultDouble.
    345     NodeIndex toNumber(NodeIndex index)
    346     {
    347         Node& node = m_graph[index];
    348 
    349         if (node.hasNumberResult())
    350             return index;
    351 
    352         if (node.op == JSConstant) {
    353             JSValue v = valueOfJSConstant(index);
    354             if (v.isNumber())
    355                 return getJSConstant(node.constantNumber());
    356         }
    357 
    358         return addToGraph(ValueToNumber, OpInfo(NodeUseBottom), index);
    359     }
    360    
    361340    NodeIndex getJSConstantForValue(JSValue constantValue)
    362341    {
     
    11991178     
    12001179    if (argumentCountIncludingThis == 2) { // Math.min(x)
    1201         set(resultOperand, getToNumber(registerOffset + argumentToOperand(1)));
     1180        set(resultOperand, get(registerOffset + argumentToOperand(1)));
    12021181        return true;
    12031182    }
    12041183   
    12051184    if (argumentCountIncludingThis == 3) { // Math.min(x, y)
    1206         set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), getToNumber(registerOffset + argumentToOperand(1)), getToNumber(registerOffset + argumentToOperand(2))));
     1185        set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), get(registerOffset + argumentToOperand(1)), get(registerOffset + argumentToOperand(2))));
    12071186        return true;
    12081187    }
     
    12321211            return false;
    12331212
    1234         NodeIndex nodeIndex = addToGraph(ArithAbs, OpInfo(NodeUseBottom), getToNumber(registerOffset + argumentToOperand(1)));
     1213        NodeIndex nodeIndex = addToGraph(ArithAbs, OpInfo(NodeUseBottom), get(registerOffset + argumentToOperand(1)));
    12351214        if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow))
    12361215            m_graph[nodeIndex].mergeArithNodeFlags(NodeMayOverflow);
     
    12571236            return false;
    12581237       
    1259         set(resultOperand, addToGraph(ArithSqrt, getToNumber(registerOffset + argumentToOperand(1))));
     1238        set(resultOperand, addToGraph(ArithSqrt, get(registerOffset + argumentToOperand(1))));
    12601239        return true;
    12611240    }
     
    15131492        case op_pre_inc: {
    15141493            unsigned srcDst = currentInstruction[1].u.operand;
    1515             NodeIndex op = getToNumber(srcDst);
     1494            NodeIndex op = get(srcDst);
    15161495            set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one())));
    15171496            NEXT_OPCODE(op_pre_inc);
     
    15221501            unsigned srcDst = currentInstruction[2].u.operand;
    15231502            ASSERT(result != srcDst); // Required for assumptions we make during OSR.
    1524             NodeIndex op = getToNumber(srcDst);
     1503            NodeIndex op = get(srcDst);
    15251504            set(result, op);
    15261505            set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one())));
     
    15301509        case op_pre_dec: {
    15311510            unsigned srcDst = currentInstruction[1].u.operand;
    1532             NodeIndex op = getToNumber(srcDst);
     1511            NodeIndex op = get(srcDst);
    15331512            set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one())));
    15341513            NEXT_OPCODE(op_pre_dec);
     
    15381517            unsigned result = currentInstruction[1].u.operand;
    15391518            unsigned srcDst = currentInstruction[2].u.operand;
    1540             NodeIndex op = getToNumber(srcDst);
     1519            NodeIndex op = get(srcDst);
    15411520            set(result, op);
    15421521            set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one())));
     
    15501529            NodeIndex op2 = get(currentInstruction[3].u.operand);
    15511530            if (m_graph[op1].hasNumberResult() && m_graph[op2].hasNumberResult())
    1552                 set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), toNumber(op1), toNumber(op2))));
     1531                set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op1, op2)));
    15531532            else
    15541533                set(currentInstruction[1].u.operand, makeSafe(addToGraph(ValueAdd, OpInfo(NodeUseBottom), op1, op2)));
     
    15571536
    15581537        case op_sub: {
    1559             NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
    1560             NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
     1538            NodeIndex op1 = get(currentInstruction[2].u.operand);
     1539            NodeIndex op2 = get(currentInstruction[3].u.operand);
    15611540            set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op1, op2)));
    15621541            NEXT_OPCODE(op_sub);
     
    15651544        case op_mul: {
    15661545            // Multiply requires that the inputs are not truncated, unfortunately.
    1567             NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
    1568             NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
     1546            NodeIndex op1 = get(currentInstruction[2].u.operand);
     1547            NodeIndex op2 = get(currentInstruction[3].u.operand);
    15691548            set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMul, OpInfo(NodeUseBottom), op1, op2)));
    15701549            NEXT_OPCODE(op_mul);
     
    15721551
    15731552        case op_mod: {
    1574             NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
    1575             NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
     1553            NodeIndex op1 = get(currentInstruction[2].u.operand);
     1554            NodeIndex op2 = get(currentInstruction[3].u.operand);
    15761555            set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMod, OpInfo(NodeUseBottom), op1, op2)));
    15771556            NEXT_OPCODE(op_mod);
     
    15791558
    15801559        case op_div: {
    1581             NodeIndex op1 = getToNumber(currentInstruction[2].u.operand);
    1582             NodeIndex op2 = getToNumber(currentInstruction[3].u.operand);
     1560            NodeIndex op1 = get(currentInstruction[2].u.operand);
     1561            NodeIndex op2 = get(currentInstruction[3].u.operand);
    15831562            set(currentInstruction[1].u.operand, makeDivSafe(addToGraph(ArithDiv, OpInfo(NodeUseBottom), op1, op2)));
    15841563            NEXT_OPCODE(op_div);
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r106775 r106879  
    212212    macro(ArithMax, NodeResultNumber) \
    213213    macro(ArithSqrt, NodeResultNumber) \
    214     /* Arithmetic operators call ToNumber on their operands. */\
    215     macro(ValueToNumber, NodeResultNumber | NodeMustGenerate) \
    216     \
    217     /* A variant of ValueToNumber, which a hint that the parents will always use this as a double. */\
    218     macro(ValueToDouble, NodeResultNumber | NodeMustGenerate) \
    219214    \
    220215    /* Add of values may either be arithmetic, or result in string concatenation. */\
     
    523518    {
    524519        switch (op) {
    525         case ValueToNumber:
    526         case ValueToDouble:
    527520        case UInt32ToNumber:
    528521        case ArithAdd:
  • trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp

    r106775 r106879  
    139139        }
    140140           
    141         case ValueToNumber:
    142         case ValueToDouble:
    143141        case UInt32ToNumber: {
    144142            changed |= m_graph[node.child1()].mergeArithNodeFlags(flags);
     
    361359            else
    362360                changed |= setPrediction(PredictNumber);
    363             break;
    364         }
    365 
    366         case ValueToNumber: {
    367             PredictedType prediction = m_graph[node.child1()].prediction();
    368            
    369             if (prediction) {
    370                 if (!(prediction & PredictDouble) && nodeCanSpeculateInteger(node.arithNodeFlags()))
    371                     changed |= mergePrediction(PredictInt32);
    372                 else
    373                     changed |= mergePrediction(PredictNumber);
    374             }
    375            
    376361            break;
    377362        }
     
    598583        }
    599584           
    600         case ValueToDouble:
    601585        case GetArrayLength:
    602586        case GetByteArrayLength:
     
    680664    {
    681665        switch (m_graph[nodeUse].op) {
    682         case ValueToNumber:
    683         case ValueToDouble:
    684666        case ValueToInt32:
    685667        case UInt32ToNumber:
     
    776758                break;
    777759               
    778             case ValueToNumber:
    779             case ValueToDouble:
    780                 // Don't vote.
    781                 break;
    782                
    783760            case SetLocal: {
    784761                PredictedType prediction = m_graph[node.child1()].prediction();
     
    836813    }
    837814   
    838     void toDouble(NodeUse nodeUse)
    839     {
    840         if (m_graph[nodeUse].op == ValueToNumber) {
    841 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
    842             printf("  @%u -> ValueToDouble", nodeUse.index());
    843 #endif
    844             m_graph[nodeUse].op = ValueToDouble;
    845         }
    846     }
    847 
    848815    void fixupNode(Node& node)
    849816    {
     
    858825       
    859826        switch (op) {
    860         case ValueAdd:
    861         case ArithAdd:
    862         case ArithSub: {
    863             PredictedType left = m_graph[node.child1()].prediction();
    864             PredictedType right = m_graph[node.child2()].prediction();
    865            
    866             if (left && right
    867                 && isNumberPrediction(left) && isNumberPrediction(right)
    868                 && !m_graph.addShouldSpeculateInteger(node, m_codeBlock)) {
    869                 toDouble(node.child1());
    870                 toDouble(node.child2());
    871             }
    872             break;
    873         }
    874            
    875         case ArithMul:
    876         case ArithMin:
    877         case ArithMax:
    878         case ArithMod:
    879         case ArithDiv: {
    880             if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
    881                 toDouble(node.child1());
    882                 toDouble(node.child2());
    883                 break;
    884             }
    885            
    886             PredictedType left = m_graph[node.child1()].prediction();
    887             PredictedType right = m_graph[node.child2()].prediction();
    888            
    889             if (left && right
    890                 && ((left & PredictDouble) || (right & PredictDouble))) {
    891                 toDouble(node.child1());
    892                 toDouble(node.child2());
    893             }
    894             break;
    895         }
    896            
    897         case ArithAbs: {
    898             if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
    899                 toDouble(node.child1());
    900                 break;
    901             }
    902            
    903             PredictedType prediction = m_graph[node.child1()].prediction();
    904             if (prediction & PredictDouble)
    905                 toDouble(node.child1());
    906             break;
    907         }
    908            
    909         case ArithSqrt: {
    910             toDouble(node.child1());
    911             break;
    912         }
    913            
    914827        case GetById: {
    915828            if (!isInt32Prediction(m_graph[m_compileIndex].prediction()))
     
    1004917        if (nodeIndex == NoNode)
    1005918            return NoNode;
    1006        
    1007         if (m_graph[nodeIndex].op == ValueToNumber)
    1008             nodeIndex = m_graph[nodeIndex].child1().index();
    1009919       
    1010920        if (m_graph[nodeIndex].op == ValueToInt32)
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r106775 r106879  
    12691269            // There are four possibilities:
    12701270            //
    1271             // ValueToNumber: If the only live version of the value is a ValueToNumber node
    1272             //    then it means that all remaining uses of the value would have performed a
    1273             //    ValueToNumber conversion anyway. Thus, we can substitute ValueToNumber.
    1274             //
    1275             // ValueToInt32: Likewise, if the only remaining live version of the value is
    1276             //    ValueToInt32, then we can use it. But if there is both a ValueToInt32
    1277             //    and a ValueToNumber, then we better go with ValueToNumber because it
    1278             //    means that some remaining uses would have converted to number while
    1279             //    others would have converted to Int32.
     1271            // ValueToInt32: If the only remaining live version of the value is
     1272            //    ValueToInt32, then we can use it.
    12801273            //
    12811274            // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
     
    12981291       
    12991292            if (!found) {
    1300                 NodeIndex valueToNumberIndex = NoNode;
    13011293                NodeIndex valueToInt32Index = NoNode;
    13021294                NodeIndex uint32ToNumberIndex = NoNode;
     
    13121304                        continue;
    13131305                    switch (node.op) {
    1314                     case ValueToNumber:
    1315                     case ValueToDouble:
    1316                         valueToNumberIndex = info.nodeIndex();
    1317                         break;
    13181306                    case ValueToInt32:
    13191307                        valueToInt32Index = info.nodeIndex();
     
    13281316           
    13291317                NodeIndex nodeIndexToUse;
    1330                 if (valueToNumberIndex != NoNode)
    1331                     nodeIndexToUse = valueToNumberIndex;
    1332                 else if (valueToInt32Index != NoNode)
     1318                if (valueToInt32Index != NoNode)
    13331319                    nodeIndexToUse = valueToInt32Index;
    13341320                else if (uint32ToNumberIndex != NoNode)
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r106775 r106879  
    18621862    }
    18631863
    1864     case ValueToNumber: {
    1865         if (at(node.child1()).shouldNotSpeculateInteger()) {
    1866             SpeculateDoubleOperand op1(this, node.child1());
    1867             FPRTemporary result(this, op1);
    1868             m_jit.moveDouble(op1.fpr(), result.fpr());
    1869             doubleResult(result.fpr(), m_compileIndex);
    1870             break;
    1871         }
    1872        
    1873         SpeculateIntegerOperand op1(this, node.child1());
    1874         GPRTemporary result(this, op1);
    1875         m_jit.move(op1.gpr(), result.gpr());
    1876         integerResult(result.gpr(), m_compileIndex, op1.format());
    1877         break;
    1878     }
    1879 
    1880     case ValueToDouble: {
    1881         SpeculateDoubleOperand op1(this, node.child1());
    1882         FPRTemporary result(this, op1);
    1883         m_jit.moveDouble(op1.fpr(), result.fpr());
    1884         doubleResult(result.fpr(), m_compileIndex);
    1885         break;
    1886     }
    1887 
    18881864    case ValueAdd:
    18891865    case ArithAdd:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r106775 r106879  
    19411941    }
    19421942
    1943     case ValueToNumber: {
    1944         if (at(node.child1()).shouldNotSpeculateInteger()) {
    1945             SpeculateDoubleOperand op1(this, node.child1());
    1946             FPRTemporary result(this, op1);
    1947             m_jit.moveDouble(op1.fpr(), result.fpr());
    1948             doubleResult(result.fpr(), m_compileIndex);
    1949             break;
    1950         }
    1951        
    1952         SpeculateIntegerOperand op1(this, node.child1());
    1953         GPRTemporary result(this, op1);
    1954         m_jit.move(op1.gpr(), result.gpr());
    1955         integerResult(result.gpr(), m_compileIndex, op1.format());
    1956         break;
    1957     }
    1958 
    1959     case ValueToDouble: {
    1960         SpeculateDoubleOperand op1(this, node.child1());
    1961         FPRTemporary result(this, op1);
    1962         m_jit.moveDouble(op1.fpr(), result.fpr());
    1963         doubleResult(result.fpr(), m_compileIndex);
    1964         break;
    1965     }
    1966 
    19671943    case ValueAdd:
    19681944    case ArithAdd:
Note: See TracChangeset for help on using the changeset viewer.