Changeset 156746 in webkit
- Timestamp:
- Oct 1, 2013 4:18:47 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r156734 r156746 1 2013-10-01 Nadav Rotem <nrotem@apple.com> 2 3 FTL: split overflow checks into non-overflow arithmetic and an additional call to the overflow intrinsic check. 4 https://bugs.webkit.org/show_bug.cgi?id=122170 5 6 Reviewed by Filip Pizlo. 7 8 Overflow intrinsics are preventing SCEV and other LLVM analysis passes from analyzing loops. This patch changes the FTL-IR gen by splitting arithmetic calculations into two parts: 9 1. Generate the arithmetic calculation (that may overflow) 10 2. Generate the overflow check (that is only used by the OSR-exit logic). 11 12 We trust LLVM (SelectionDAG) to merge these calculations into a single opcode. 13 14 This JS function: 15 16 function foo() { 17 for (i=0; i < 10000000; i++) { } 18 } 19 20 Is now compiled into this LLVM-IR: 21 22 "OSR exit continuation for @24<Int32>": ; preds = %"Block #0", %"OSR exit continuation for @24<Int32>2" 23 %4 = phi i64 [ %10, %"OSR exit continuation for @24<Int32>2" ], [ -281474976710656, %"Block #0" ] 24 %5 = trunc i64 %4 to i32 25 %6 = add i32 %5, 1 26 %7 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %5, i32 1) 27 %8 = extractvalue { i32, i1 } %7, 1 28 br i1 %8, label %"OSR exit failCase for @24<Int32>1", label %"OSR exit continuation for @24<Int32>2" 29 30 And into this assembly: 31 32 LBB0_1: ## %OSR exit continuation for @24<Int32> 33 ## =>This Inner Loop Header: Depth=1 34 movl %ecx, %esi 35 incl %esi 36 jo LBB0_4 37 38 * ftl/FTLLowerDFGToLLVM.cpp: 39 (JSC::FTL::LowerDFGToLLVM::compileAddSub): 40 (JSC::FTL::LowerDFGToLLVM::compileArithMul): 41 (JSC::FTL::LowerDFGToLLVM::compileArithNegate): 42 1 43 2013-10-01 Nadav Rotem <nrotem@apple.com> 2 44 -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r156734 r156746 663 663 LValue left = lowInt32(m_node->child1()); 664 664 LValue right = lowInt32(m_node->child2()); 665 665 LValue result = isSub ? m_out.sub(left, right) : m_out.add(left, right); 666 666 667 if (bytecodeCanTruncateInteger(m_node->arithNodeFlags())) { 667 setInt32( isSub ? m_out.sub(left, right) : m_out.add(left, right));668 setInt32(result); 668 669 break; 669 670 } 670 671 671 LValue result= isSub ? m_out.subWithOverflow32(left, right) : m_out.addWithOverflow32(left, right);672 673 speculate(Overflow, noValue(), 0, m_out.extractValue( result, 1));674 setInt32( m_out.extractValue(result, 0));672 LValue overflow = isSub ? m_out.subWithOverflow32(left, right) : m_out.addWithOverflow32(left, right); 673 674 speculate(Overflow, noValue(), 0, m_out.extractValue(overflow, 1)); 675 setInt32(result); 675 676 break; 676 677 } … … 688 689 LValue left = lowInt52(m_node->child1()); 689 690 LValue right = lowInt52(m_node->child2()); 690 LValue result = isSub ? m_out.subWithOverflow64(left, right) : m_out.addWithOverflow64(left, right); 691 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1)); 692 setInt52(m_out.extractValue(result, 0)); 691 LValue result = isSub ? m_out.sub(left, right) : m_out.add(left, right); 692 693 LValue overflow = isSub ? m_out.subWithOverflow64(left, right) : m_out.addWithOverflow64(left, right); 694 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflow, 1)); 695 setInt52(result); 693 696 break; 694 697 } … … 714 717 LValue left = lowInt32(m_node->child1()); 715 718 LValue right = lowInt32(m_node->child2()); 716 717 LValue result; 718 if (bytecodeCanTruncateInteger(m_node->arithNodeFlags())) 719 result = m_out.mul(left, right); 720 else { 719 LValue result = m_out.mul(left, right); 720 721 if (!bytecodeCanTruncateInteger(m_node->arithNodeFlags())) { 721 722 LValue overflowResult = m_out.mulWithOverflow32(left, right); 722 723 speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); 723 result = m_out.extractValue(overflowResult, 0);724 724 } 725 725 … … 745 745 LValue left = lowWhicheverInt52(m_node->child1(), kind); 746 746 LValue right = lowInt52(m_node->child2(), opposite(kind)); 747 747 LValue result = m_out.mul(left, right); 748 749 748 750 LValue overflowResult = m_out.mulWithOverflow64(left, right); 749 751 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); 750 LValue result = m_out.extractValue(overflowResult, 0); 751 752 752 753 if (!bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) { 753 754 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case")); … … 1051 1052 LValue value = lowInt32(m_node->child1()); 1052 1053 1053 LValue result; 1054 if (bytecodeCanTruncateInteger(m_node->arithNodeFlags())) 1055 result = m_out.neg(value); 1056 else if (bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) { 1057 // We don't have a negate-with-overflow intrinsic. Hopefully this 1058 // does the trick, though. 1059 LValue overflowResult = m_out.subWithOverflow32(m_out.int32Zero, value); 1060 speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); 1061 result = m_out.extractValue(overflowResult, 0); 1062 } else { 1063 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff))); 1064 result = m_out.neg(value); 1065 } 1066 1054 LValue result = m_out.neg(value); 1055 if (!bytecodeCanTruncateInteger(m_node->arithNodeFlags())) { 1056 if (bytecodeCanIgnoreNegativeZero(m_node->arithNodeFlags())) { 1057 // We don't have a negate-with-overflow intrinsic. Hopefully this 1058 // does the trick, though. 1059 LValue overflowResult = m_out.subWithOverflow32(m_out.int32Zero, value); 1060 speculate(Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); 1061 } else 1062 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff))); 1063 1064 } 1065 1067 1066 setInt32(result); 1068 1067 break; … … 1083 1082 LValue overflowResult = m_out.subWithOverflow64(m_out.int64Zero, value); 1084 1083 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(overflowResult, 1)); 1085 LValue result = m_out. extractValue(overflowResult, 0);1084 LValue result = m_out.neg(value); 1086 1085 speculate(NegativeZero, noValue(), 0, m_out.isZero64(result)); 1087 1086 setInt52(result);
Note: See TracChangeset
for help on using the changeset viewer.