Changeset 95172 in webkit
- Timestamp:
- Sep 14, 2011 10:49:19 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r95170 r95172 1 2011-09-14 Filip Pizlo <fpizlo@apple.com> 2 3 DFG does not speculate aggressively enough on comparisons 4 https://bugs.webkit.org/show_bug.cgi?id=68138 5 6 Reviewed by Oliver Hunt. 7 8 This is a 75% speed-up on Kraken/ai-astar. It's a 1% win on 9 V8 and an 8.5% win on Kraken. Neutral on SunSpider. 10 11 * dfg/DFGSpeculativeJIT.cpp: 12 (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch): 13 (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality): 14 (JSC::DFG::SpeculativeJIT::compileObjectEquality): 15 (JSC::DFG::SpeculativeJIT::compare): 16 * dfg/DFGSpeculativeJIT.h: 17 (JSC::DFG::SpeculativeJIT::shouldSpeculateFinalObject): 18 (JSC::DFG::SpeculativeJIT::shouldSpeculateArray): 19 (JSC::DFG::SpeculativeJIT::shouldSpeculateObject): 20 (JSC::DFG::SpeculativeJIT::shouldSpeculateCell): 21 1 22 2011-09-14 Filip Pizlo <fpizlo@apple.com> 2 23 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r95170 r95172 34 34 GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat) 35 35 { 36 #if ENABLE(DFG_DEBUG_VERBOSE) 37 fprintf(stderr, "SpecInt@%d ", nodeIndex); 38 #endif 36 39 Node& node = m_jit.graph()[nodeIndex]; 37 40 VirtualRegister virtualRegister = node.virtualRegister(); … … 255 258 FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex) 256 259 { 260 #if ENABLE(DFG_DEBUG_VERBOSE) 261 fprintf(stderr, "SpecDouble@%d ", nodeIndex); 262 #endif 257 263 Node& node = m_jit.graph()[nodeIndex]; 258 264 VirtualRegister virtualRegister = node.virtualRegister(); … … 375 381 GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex) 376 382 { 383 #if ENABLE(DFG_DEBUG_VERBOSE) 384 fprintf(stderr, "SpecCell@%d ", nodeIndex); 385 #endif 377 386 Node& node = m_jit.graph()[nodeIndex]; 378 387 VirtualRegister virtualRegister = node.virtualRegister(); … … 437 446 GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex) 438 447 { 448 #if ENABLE(DFG_DEBUG_VERBOSE) 449 fprintf(stderr, "SpecBool@%d ", nodeIndex); 450 #endif 439 451 Node& node = m_jit.graph()[nodeIndex]; 440 452 VirtualRegister virtualRegister = node.virtualRegister(); … … 556 568 } 557 569 558 void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition , Z_DFGOperation_EJJ operation)570 void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition) 559 571 { 560 572 Node& branchNode = m_jit.graph()[branchNodeIndex]; … … 562 574 BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset()); 563 575 564 bool op1Numeric = isKnownNumeric(node.child1()); 565 bool op2Numeric = isKnownNumeric(node.child2()); 566 567 if (op1Numeric && op2Numeric) { 568 SpeculateDoubleOperand op1(this, node.child1()); 569 SpeculateDoubleOperand op2(this, node.child2()); 570 571 addBranch(m_jit.branchDouble(condition, op1.fpr(), op2.fpr()), taken); 572 } else if (op1Numeric) { 573 SpeculateDoubleOperand op1(this, node.child1()); 574 JSValueOperand op2(this, node.child2()); 575 576 FPRTemporary fprTmp(this); 577 GPRTemporary gprTmp(this); 578 579 FPRReg op1FPR = op1.fpr(); 580 GPRReg op2GPR = op2.gpr(); 581 FPRReg op2FPR = fprTmp.fpr(); 582 GPRReg gpr = gprTmp.gpr(); 583 584 JITCompiler::Jump slowPath = convertToDouble(op2GPR, op2FPR, gpr); 585 586 addBranch(m_jit.branchDouble(condition, op1FPR, op2FPR), taken); 587 addBranch(m_jit.jump(), notTaken); 588 589 slowPath.link(&m_jit); 590 591 boxDouble(op1FPR, gpr); 592 593 silentSpillAllRegisters(gpr); 594 setupStubArguments(gpr, op2GPR); 595 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 596 appendCallWithExceptionCheck(operation); 597 m_jit.move(GPRInfo::returnValueGPR, gpr); 598 silentFillAllRegisters(gpr); 599 600 addBranch(m_jit.branchTest8(JITCompiler::NonZero, gpr), taken); 601 } else { 602 JSValueOperand op1(this, node.child1()); 603 SpeculateDoubleOperand op2(this, node.child2()); 604 605 FPRTemporary fprTmp(this); 606 GPRTemporary gprTmp(this); 607 608 FPRReg op2FPR = op2.fpr(); 609 GPRReg op1GPR = op1.gpr(); 610 FPRReg op1FPR = fprTmp.fpr(); 611 GPRReg gpr = gprTmp.gpr(); 612 613 JITCompiler::Jump slowPath = convertToDouble(op1GPR, op1FPR, gpr); 614 615 addBranch(m_jit.branchDouble(condition, op1FPR, op2FPR), taken); 616 addBranch(m_jit.jump(), notTaken); 617 618 slowPath.link(&m_jit); 619 620 boxDouble(op2FPR, gpr); 621 622 silentSpillAllRegisters(gpr); 623 setupStubArguments(op1GPR, gpr); 624 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 625 appendCallWithExceptionCheck(operation); 626 m_jit.move(GPRInfo::returnValueGPR, gpr); 627 silentFillAllRegisters(gpr); 628 629 addBranch(m_jit.branchTest8(JITCompiler::NonZero, gpr), taken); 630 } 576 SpeculateDoubleOperand op1(this, node.child1()); 577 SpeculateDoubleOperand op2(this, node.child2()); 578 579 addBranch(m_jit.branchDouble(condition, op1.fpr(), op2.fpr()), taken); 631 580 632 581 if (notTaken != (m_block + 1)) 633 582 addBranch(m_jit.jump(), notTaken); 583 } 584 585 void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchNodeIndex, void* vptr) 586 { 587 Node& branchNode = m_jit.graph()[branchNodeIndex]; 588 BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset()); 589 BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset()); 590 591 MacroAssembler::RelationalCondition condition = MacroAssembler::Equal; 592 593 if (taken == (m_block + 1)) { 594 condition = MacroAssembler::NotEqual; 595 BlockIndex tmp = taken; 596 taken = notTaken; 597 notTaken = tmp; 598 } 599 600 SpeculateCellOperand op1(this, node.child1()); 601 SpeculateCellOperand op2(this, node.child2()); 602 603 GPRReg op1GPR = op1.gpr(); 604 GPRReg op2GPR = op2.gpr(); 605 606 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr))); 607 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr))); 608 609 addBranch(m_jit.branchPtr(condition, op1GPR, op2GPR), taken); 610 if (notTaken != (m_block + 1)) 611 addBranch(m_jit.jump(), notTaken); 612 } 613 614 void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr) 615 { 616 SpeculateCellOperand op1(this, node.child1()); 617 SpeculateCellOperand op2(this, node.child2()); 618 GPRTemporary result(this, op1); 619 620 GPRReg op1GPR = op1.gpr(); 621 GPRReg op2GPR = op2.gpr(); 622 GPRReg resultGPR = result.gpr(); 623 624 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr))); 625 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr))); 626 627 MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR); 628 m_jit.move(Imm32(ValueTrue), resultGPR); 629 MacroAssembler::Jump done = m_jit.jump(); 630 falseCase.link(&m_jit); 631 m_jit.move(Imm32(ValueFalse), resultGPR); 632 done.link(&m_jit); 633 634 jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean); 634 635 } 635 636 … … 648 649 use(node.child1()); 649 650 use(node.child2()); 650 } else if (isKnownNumeric(node.child1()) || isKnownNumeric(node.child2())) { 651 compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition, operation); 651 } else if (shouldSpeculateNumber(node.child1(), node.child2())) { 652 compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition); 653 use(node.child1()); 654 use(node.child2()); 655 } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) { 656 compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr); 657 use(node.child1()); 658 use(node.child2()); 659 } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) { 660 compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr); 652 661 use(node.child1()); 653 662 use(node.child2()); … … 658 667 return true; 659 668 } 660 661 if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) 669 670 if (shouldSpeculateFinalObject(node.child1(), node.child2())) 671 compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr); 672 else if (shouldSpeculateArray(node.child1(), node.child2())) 673 compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr); 674 else if (!shouldSpeculateNumber(node.child1()) && !shouldSpeculateNumber(node.child2())) 662 675 nonSpeculativeNonPeepholeCompare(node, condition, operation); 663 else { 676 else if ((shouldSpeculateNumber(node.child1()) || shouldSpeculateNumber(node.child2())) && !shouldSpeculateInteger(node.child1(), node.child2())) { 677 // Normal case, not fused to branch. 678 SpeculateDoubleOperand op1(this, node.child1()); 679 SpeculateDoubleOperand op2(this, node.child2()); 680 GPRTemporary result(this); 681 682 m_jit.move(TrustedImm32(ValueTrue), result.gpr()); 683 MacroAssembler::Jump trueCase = m_jit.branchDouble(doubleCondition, op1.fpr(), op2.fpr()); 684 m_jit.xorPtr(Imm32(true), result.gpr()); 685 trueCase.link(&m_jit); 686 687 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean); 688 } else { 664 689 // Normal case, not fused to branch. 665 690 SpeculateIntegerOperand op1(this, node.child1()); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r95147 r95172 428 428 } 429 429 430 bool shouldSpeculateFinalObject(NodeIndex nodeIndex) 431 { 432 PredictedType prediction; 433 if (isJSConstant(nodeIndex)) 434 prediction = predictionFromValue(valueOfJSConstant(nodeIndex)); 435 else 436 prediction = m_jit.graph().getPrediction(m_jit.graph()[nodeIndex]); 437 return isFinalObjectPrediction(prediction); 438 } 439 440 bool shouldSpeculateArray(NodeIndex nodeIndex) 441 { 442 PredictedType prediction; 443 if (isJSConstant(nodeIndex)) 444 prediction = predictionFromValue(valueOfJSConstant(nodeIndex)); 445 else 446 prediction = m_jit.graph().getPrediction(m_jit.graph()[nodeIndex]); 447 return isArrayPrediction(prediction); 448 } 449 450 bool shouldSpeculateObject(NodeIndex nodeIndex) 451 { 452 Node& node = m_jit.graph()[nodeIndex]; 453 if (node.op == ConvertThis) 454 return true; 455 PredictedType prediction; 456 if (isJSConstant(nodeIndex)) 457 prediction = predictionFromValue(valueOfJSConstant(nodeIndex)); 458 else 459 prediction = m_jit.graph().getPrediction(m_jit.graph()[nodeIndex]); 460 return isObjectPrediction(prediction); 461 } 462 463 bool shouldSpeculateCell(NodeIndex nodeIndex) 464 { 465 if (isJSConstant(nodeIndex) && valueOfJSConstant(nodeIndex).isCell()) 466 return true; 467 468 Node& node = m_jit.graph()[nodeIndex]; 469 470 if (isCellPrediction(m_jit.graph().getPrediction(node))) 471 return true; 472 473 VirtualRegister virtualRegister = node.virtualRegister(); 474 GenerationInfo& info = m_generationInfo[virtualRegister]; 475 476 if (info.isJSCell()) 477 return true; 478 479 return false; 480 } 481 430 482 bool shouldSpeculateInteger(NodeIndex op1, NodeIndex op2) 431 483 { … … 437 489 return shouldSpeculateNumber(op1) && shouldSpeculateNumber(op2); 438 490 } 439 491 492 bool shouldSpeculateFinalObject(NodeIndex op1, NodeIndex op2) 493 { 494 return shouldSpeculateFinalObject(op1) && shouldSpeculateObject(op2) 495 || shouldSpeculateObject(op1) && shouldSpeculateFinalObject(op2); 496 } 497 498 bool shouldSpeculateArray(NodeIndex op1, NodeIndex op2) 499 { 500 return shouldSpeculateArray(op1) && shouldSpeculateObject(op2) 501 || shouldSpeculateObject(op1) && shouldSpeculateArray(op2); 502 } 503 440 504 bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ); 441 505 void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition); 442 void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition, Z_DFGOperation_EJJ); 506 void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition); 507 void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex, void* vptr); 508 void compileObjectEquality(Node&, void* vptr); 443 509 444 510 JITCompiler::Jump convertToDouble(GPRReg value, FPRReg result, GPRReg tmp);
Note: See TracChangeset
for help on using the changeset viewer.