Changeset 89084 in webkit
- Timestamp:
- Jun 16, 2011 4:40:06 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r89077 r89084 1 2011-06-16 Gavin Barraclough <barraclough@apple.com> 2 3 Reviewed by Sam Weinig. 4 5 https://bugs.webkit.org/show_bug.cgi?id=62824 6 DFG JIT - add support for branch-fusion of compareEq, JSValue comparisons in SpeculativeJIT 7 8 CompareEq of non-integer values is the most common cause of speculation failure. 9 10 * dfg/DFGSpeculativeJIT.cpp: 11 (JSC::DFG::SpeculativeJIT::compilePeepHoleIntegerBranch): 12 - Support Equals. 13 (JSC::DFG::SpeculativeJIT::compilePeepHoleEq): 14 - new! - peephole optimized Eq of JSValues. 15 (JSC::DFG::SpeculativeJIT::compile): 16 - Add peephole optimization for CompareEq. 17 * dfg/DFGSpeculativeJIT.h: 18 (JSC::DFG::SpeculativeJIT::detectPeepHoleBranch): 19 - Add support for dead nodes between compare & branch. 20 (JSC::DFG::SpeculativeJIT::isInteger): 21 - Added to determine which form of peephole to do in CompareEq. 22 1 23 2011-06-16 Geoffrey Garen <ggaren@apple.com> 2 24 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r88280 r89084 234 234 } 235 235 236 void SpeculativeJIT::compilePeepHole Branch(Node& node, JITCompiler::RelationalCondition condition)237 { 238 Node& branchNode = m_jit.graph()[ m_compileIndex + 1];236 void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition condition) 237 { 238 Node& branchNode = m_jit.graph()[branchNodeIndex]; 239 239 BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset()); 240 240 BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset()); … … 267 267 } 268 268 269 void SpeculativeJIT::compilePeepHoleEq(Node& node, NodeIndex branchNodeIndex) 270 { 271 Node& branchNode = m_jit.graph()[branchNodeIndex]; 272 BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset()); 273 BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset()); 274 275 // The branch instruction will branch to the taken block. 276 // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through. 277 JITCompiler::ResultCondition condition = JITCompiler::NonZero; 278 if (taken == (m_block + 1)) { 279 condition = JITCompiler::Zero; 280 BlockIndex tmp = taken; 281 taken = notTaken; 282 notTaken = tmp; 283 } 284 285 JSValueOperand op1(this, node.child1); 286 JSValueOperand op2(this, node.child2); 287 GPRReg op1GPR = op1.gpr(); 288 GPRReg op2GPR = op2.gpr(); 289 flushRegisters(); 290 291 GPRResult result(this); 292 callOperation(operationCompareEq, result.gpr(), op1GPR, op2GPR); 293 addBranch(m_jit.branchTest8(condition, result.gpr()), taken); 294 295 // Check for fall through, otherwise we need to jump. 296 if (notTaken != (m_block + 1)) 297 addBranch(m_jit.jump(), notTaken); 298 } 299 269 300 void SpeculativeJIT::compile(Node& node) 270 301 { … … 550 581 case CompareLess: { 551 582 // Fused compare & branch. 552 if (detectPeepHoleBranch()) { 583 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 584 if (branchNodeIndex != NoNode) { 553 585 // detectPeepHoleBranch currently only permits the branch to be the very next node, 554 586 // so can be no intervening nodes to also reference the compare. 555 587 ASSERT(node.adjustedRefCount() == 1); 556 588 557 compilePeepHole Branch(node, JITCompiler::LessThan);589 compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::LessThan); 558 590 559 591 use(node.child1); 560 592 use(node.child2); 561 ++m_compileIndex;593 m_compileIndex = branchNodeIndex; 562 594 return; 563 595 } … … 578 610 case CompareLessEq: { 579 611 // Fused compare & branch. 580 if (detectPeepHoleBranch()) { 612 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 613 if (branchNodeIndex != NoNode) { 581 614 // detectPeepHoleBranch currently only permits the branch to be the very next node, 582 615 // so can be no intervening nodes to also reference the compare. 583 616 ASSERT(node.adjustedRefCount() == 1); 584 617 585 compilePeepHole Branch(node, JITCompiler::LessThanOrEqual);618 compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::LessThanOrEqual); 586 619 587 620 use(node.child1); 588 621 use(node.child2); 589 ++m_compileIndex;622 m_compileIndex = branchNodeIndex; 590 623 return; 591 624 } … … 605 638 606 639 case CompareEq: { 640 // Fused compare & branch. 641 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 642 if (branchNodeIndex != NoNode) { 643 // detectPeepHoleBranch currently only permits the branch to be the very next node, 644 // so can be no intervening nodes to also reference the compare. 645 ASSERT(node.adjustedRefCount() == 1); 646 647 if (isInteger(node.child1) || isInteger(node.child2)) 648 compilePeepHoleIntegerBranch(node, branchNodeIndex, JITCompiler::Equal); 649 else 650 compilePeepHoleEq(node, branchNodeIndex); 651 652 use(node.child1); 653 use(node.child2); 654 m_compileIndex = branchNodeIndex; 655 return; 656 } 657 607 658 SpeculateIntegerOperand op1(this, node.child1); 608 659 SpeculateIntegerOperand op2(this, node.child2); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r88280 r89084 139 139 void initializeVariableTypes(); 140 140 141 bool detectPeepHoleBranch() 142 { 143 // Check if the block contains precisely one more node. 144 if (m_compileIndex + 2 != m_jit.graph().m_blocks[m_block]->end) 145 return false; 141 // Returns the node index of the branch node if peephole is okay, NoNode otherwise. 142 NodeIndex detectPeepHoleBranch() 143 { 144 NodeIndex lastNodeIndex = m_jit.graph().m_blocks[m_block]->end - 1; 145 146 // Check that no intervening nodes will be generated. 147 for (NodeIndex index = m_compileIndex + 1; index < lastNodeIndex; ++index) { 148 if (m_jit.graph()[index].shouldGenerate()) 149 return NoNode; 150 } 146 151 147 152 // Check if the lastNode is a branch on this node. 148 Node& lastNode = m_jit.graph()[m_compileIndex + 1]; 149 return lastNode.op == Branch && lastNode.child1 == m_compileIndex; 150 } 151 152 void compilePeepHoleBranch(Node&, JITCompiler::RelationalCondition); 153 Node& lastNode = m_jit.graph()[lastNodeIndex]; 154 return lastNode.op == Branch && lastNode.child1 == m_compileIndex ? lastNodeIndex : NoNode; 155 } 156 157 bool isInteger(NodeIndex nodeIndex) 158 { 159 Node& node = m_jit.graph()[nodeIndex]; 160 if (node.hasInt32Result()) 161 return true; 162 163 VirtualRegister virtualRegister = node.virtualRegister(); 164 GenerationInfo& info = m_generationInfo[virtualRegister]; 165 166 return (info.registerFormat() | DataFormatJS) == DataFormatJSInteger; 167 } 168 169 void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition); 170 void compilePeepHoleEq(Node&, NodeIndex branchNodeIndex); 153 171 154 172 // Add a speculation check without additional recovery.
Note: See TracChangeset
for help on using the changeset viewer.