Changeset 106879 in webkit
- Timestamp:
- Feb 6, 2012, 5:07:32 PM (15 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
-
ChangeLog (modified) (1 diff)
-
dfg/DFGAbstractState.cpp (modified) (1 diff)
-
dfg/DFGByteCodeParser.cpp (modified) (14 diffs)
-
dfg/DFGNode.h (modified) (2 diffs)
-
dfg/DFGPropagator.cpp (modified) (8 diffs)
-
dfg/DFGSpeculativeJIT.cpp (modified) (4 diffs)
-
dfg/DFGSpeculativeJIT32_64.cpp (modified) (1 diff)
-
dfg/DFGSpeculativeJIT64.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r106796 r106879 1 2012-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 1 41 2012-02-06 Patrick Gansterer <paroga@webkit.org> 2 42 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractState.cpp
r106502 r106879 263 263 break; 264 264 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 281 265 case ValueAdd: 282 266 case ArithAdd: { -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r106775 r106879 314 314 return toInt32(get(operand)); 315 315 } 316 NodeIndex getToNumber(int operand)317 {318 return toNumber(get(operand));319 }320 316 321 317 // Perform an ES5 ToInt32 operation - returns a node of type NodeResultInt32. … … 342 338 } 343 339 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 361 340 NodeIndex getJSConstantForValue(JSValue constantValue) 362 341 { … … 1199 1178 1200 1179 if (argumentCountIncludingThis == 2) { // Math.min(x) 1201 set(resultOperand, get ToNumber(registerOffset + argumentToOperand(1)));1180 set(resultOperand, get(registerOffset + argumentToOperand(1))); 1202 1181 return true; 1203 1182 } 1204 1183 1205 1184 if (argumentCountIncludingThis == 3) { // Math.min(x, y) 1206 set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), get ToNumber(registerOffset + argumentToOperand(1)), getToNumber(registerOffset + argumentToOperand(2))));1185 set(resultOperand, addToGraph(op, OpInfo(NodeUseBottom), get(registerOffset + argumentToOperand(1)), get(registerOffset + argumentToOperand(2)))); 1207 1186 return true; 1208 1187 } … … 1232 1211 return false; 1233 1212 1234 NodeIndex nodeIndex = addToGraph(ArithAbs, OpInfo(NodeUseBottom), get ToNumber(registerOffset + argumentToOperand(1)));1213 NodeIndex nodeIndex = addToGraph(ArithAbs, OpInfo(NodeUseBottom), get(registerOffset + argumentToOperand(1))); 1235 1214 if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, Overflow)) 1236 1215 m_graph[nodeIndex].mergeArithNodeFlags(NodeMayOverflow); … … 1257 1236 return false; 1258 1237 1259 set(resultOperand, addToGraph(ArithSqrt, get ToNumber(registerOffset + argumentToOperand(1))));1238 set(resultOperand, addToGraph(ArithSqrt, get(registerOffset + argumentToOperand(1)))); 1260 1239 return true; 1261 1240 } … … 1513 1492 case op_pre_inc: { 1514 1493 unsigned srcDst = currentInstruction[1].u.operand; 1515 NodeIndex op = get ToNumber(srcDst);1494 NodeIndex op = get(srcDst); 1516 1495 set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one()))); 1517 1496 NEXT_OPCODE(op_pre_inc); … … 1522 1501 unsigned srcDst = currentInstruction[2].u.operand; 1523 1502 ASSERT(result != srcDst); // Required for assumptions we make during OSR. 1524 NodeIndex op = get ToNumber(srcDst);1503 NodeIndex op = get(srcDst); 1525 1504 set(result, op); 1526 1505 set(srcDst, makeSafe(addToGraph(ArithAdd, OpInfo(NodeUseBottom), op, one()))); … … 1530 1509 case op_pre_dec: { 1531 1510 unsigned srcDst = currentInstruction[1].u.operand; 1532 NodeIndex op = get ToNumber(srcDst);1511 NodeIndex op = get(srcDst); 1533 1512 set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one()))); 1534 1513 NEXT_OPCODE(op_pre_dec); … … 1538 1517 unsigned result = currentInstruction[1].u.operand; 1539 1518 unsigned srcDst = currentInstruction[2].u.operand; 1540 NodeIndex op = get ToNumber(srcDst);1519 NodeIndex op = get(srcDst); 1541 1520 set(result, op); 1542 1521 set(srcDst, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op, one()))); … … 1550 1529 NodeIndex op2 = get(currentInstruction[3].u.operand); 1551 1530 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))); 1553 1532 else 1554 1533 set(currentInstruction[1].u.operand, makeSafe(addToGraph(ValueAdd, OpInfo(NodeUseBottom), op1, op2))); … … 1557 1536 1558 1537 case op_sub: { 1559 NodeIndex op1 = get ToNumber(currentInstruction[2].u.operand);1560 NodeIndex op2 = get ToNumber(currentInstruction[3].u.operand);1538 NodeIndex op1 = get(currentInstruction[2].u.operand); 1539 NodeIndex op2 = get(currentInstruction[3].u.operand); 1561 1540 set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithSub, OpInfo(NodeUseBottom), op1, op2))); 1562 1541 NEXT_OPCODE(op_sub); … … 1565 1544 case op_mul: { 1566 1545 // Multiply requires that the inputs are not truncated, unfortunately. 1567 NodeIndex op1 = get ToNumber(currentInstruction[2].u.operand);1568 NodeIndex op2 = get ToNumber(currentInstruction[3].u.operand);1546 NodeIndex op1 = get(currentInstruction[2].u.operand); 1547 NodeIndex op2 = get(currentInstruction[3].u.operand); 1569 1548 set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMul, OpInfo(NodeUseBottom), op1, op2))); 1570 1549 NEXT_OPCODE(op_mul); … … 1572 1551 1573 1552 case op_mod: { 1574 NodeIndex op1 = get ToNumber(currentInstruction[2].u.operand);1575 NodeIndex op2 = get ToNumber(currentInstruction[3].u.operand);1553 NodeIndex op1 = get(currentInstruction[2].u.operand); 1554 NodeIndex op2 = get(currentInstruction[3].u.operand); 1576 1555 set(currentInstruction[1].u.operand, makeSafe(addToGraph(ArithMod, OpInfo(NodeUseBottom), op1, op2))); 1577 1556 NEXT_OPCODE(op_mod); … … 1579 1558 1580 1559 case op_div: { 1581 NodeIndex op1 = get ToNumber(currentInstruction[2].u.operand);1582 NodeIndex op2 = get ToNumber(currentInstruction[3].u.operand);1560 NodeIndex op1 = get(currentInstruction[2].u.operand); 1561 NodeIndex op2 = get(currentInstruction[3].u.operand); 1583 1562 set(currentInstruction[1].u.operand, makeDivSafe(addToGraph(ArithDiv, OpInfo(NodeUseBottom), op1, op2))); 1584 1563 NEXT_OPCODE(op_div); -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r106775 r106879 212 212 macro(ArithMax, NodeResultNumber) \ 213 213 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) \219 214 \ 220 215 /* Add of values may either be arithmetic, or result in string concatenation. */\ … … 523 518 { 524 519 switch (op) { 525 case ValueToNumber:526 case ValueToDouble:527 520 case UInt32ToNumber: 528 521 case ArithAdd: -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r106775 r106879 139 139 } 140 140 141 case ValueToNumber:142 case ValueToDouble:143 141 case UInt32ToNumber: { 144 142 changed |= m_graph[node.child1()].mergeArithNodeFlags(flags); … … 361 359 else 362 360 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 else373 changed |= mergePrediction(PredictNumber);374 }375 376 361 break; 377 362 } … … 598 583 } 599 584 600 case ValueToDouble:601 585 case GetArrayLength: 602 586 case GetByteArrayLength: … … 680 664 { 681 665 switch (m_graph[nodeUse].op) { 682 case ValueToNumber:683 case ValueToDouble:684 666 case ValueToInt32: 685 667 case UInt32ToNumber: … … 776 758 break; 777 759 778 case ValueToNumber:779 case ValueToDouble:780 // Don't vote.781 break;782 783 760 case SetLocal: { 784 761 PredictedType prediction = m_graph[node.child1()].prediction(); … … 836 813 } 837 814 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 #endif844 m_graph[nodeUse].op = ValueToDouble;845 }846 }847 848 815 void fixupNode(Node& node) 849 816 { … … 858 825 859 826 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 && right867 && 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 && right890 && ((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 914 827 case GetById: { 915 828 if (!isInt32Prediction(m_graph[m_compileIndex].prediction())) … … 1004 917 if (nodeIndex == NoNode) 1005 918 return NoNode; 1006 1007 if (m_graph[nodeIndex].op == ValueToNumber)1008 nodeIndex = m_graph[nodeIndex].child1().index();1009 919 1010 920 if (m_graph[nodeIndex].op == ValueToInt32) -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r106775 r106879 1269 1269 // There are four possibilities: 1270 1270 // 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. 1280 1273 // 1281 1274 // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber … … 1298 1291 1299 1292 if (!found) { 1300 NodeIndex valueToNumberIndex = NoNode;1301 1293 NodeIndex valueToInt32Index = NoNode; 1302 1294 NodeIndex uint32ToNumberIndex = NoNode; … … 1312 1304 continue; 1313 1305 switch (node.op) { 1314 case ValueToNumber:1315 case ValueToDouble:1316 valueToNumberIndex = info.nodeIndex();1317 break;1318 1306 case ValueToInt32: 1319 1307 valueToInt32Index = info.nodeIndex(); … … 1328 1316 1329 1317 NodeIndex nodeIndexToUse; 1330 if (valueToNumberIndex != NoNode) 1331 nodeIndexToUse = valueToNumberIndex; 1332 else if (valueToInt32Index != NoNode) 1318 if (valueToInt32Index != NoNode) 1333 1319 nodeIndexToUse = valueToInt32Index; 1334 1320 else if (uint32ToNumberIndex != NoNode) -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r106775 r106879 1862 1862 } 1863 1863 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 1888 1864 case ValueAdd: 1889 1865 case ArithAdd: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r106775 r106879 1941 1941 } 1942 1942 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 1967 1943 case ValueAdd: 1968 1944 case ArithAdd:
Note:
See TracChangeset
for help on using the changeset viewer.