Changeset 196726 in webkit
- Timestamp:
- Feb 17, 2016 3:35:11 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r196723 r196726 1 2016-02-17 Benjamin Poulain <bpoulain@apple.com> 2 3 [JSC] Remove the overflow check on ArithAbs when possible 4 https://bugs.webkit.org/show_bug.cgi?id=154325 5 6 Reviewed by Filip Pizlo. 7 8 This patch adds support for ArithMode for ArithAbs. 9 10 It is useful for kraken tests where Math.abs() is used 11 on values for which the range is known. 12 13 For example, imaging-gaussian-blur has two Math.abs() with 14 integers that are always in a small range around zero. 15 The IntegerRangeOptimizationPhase detects the range correctly 16 so we can just update the ArithMode depending on the input. 17 18 * dfg/DFGFixupPhase.cpp: 19 (JSC::DFG::FixupPhase::fixupNode): 20 * dfg/DFGIntegerRangeOptimizationPhase.cpp: 21 * dfg/DFGNode.h: 22 (JSC::DFG::Node::convertToArithNegate): 23 (JSC::DFG::Node::hasArithMode): 24 * dfg/DFGSpeculativeJIT64.cpp: 25 (JSC::DFG::SpeculativeJIT::compile): 26 * ftl/FTLLowerDFGToLLVM.cpp: 27 (JSC::FTL::DFG::LowerDFGToLLVM::compileArithAbs): 28 * tests/stress/arith-abs-integer-range-optimization.js: Added. 29 (negativeRange): 30 (negativeRangeIncludingZero): 31 (negativeRangeWithOverflow): 32 (positiveRange): 33 (positiveRangeIncludingZero): 34 (rangeWithoutOverflow): 35 * tests/stress/arith-abs-with-bitwise-or-zero.js: Added. 36 (opaqueAbs): 37 1 38 2016-02-17 Chris Dumez <cdumez@apple.com> 2 39 -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r196642 r196726 335 335 if (m_graph.unaryArithShouldSpeculateInt32(node, FixupPass)) { 336 336 fixIntOrBooleanEdge(node->child1()); 337 if (bytecodeCanTruncateInteger(node->arithNodeFlags())) 338 node->setArithMode(Arith::Unchecked); 339 else 340 node->setArithMode(Arith::CheckOverflow); 337 341 break; 338 342 } -
trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp
r195585 r196726 1204 1204 // call executeNode() before we optimize. 1205 1205 switch (node->op()) { 1206 case ArithAbs: { 1207 if (node->child1().useKind() != Int32Use) 1208 break; 1209 1210 auto iter = m_relationships.find(node->child1().node()); 1211 if (iter == m_relationships.end()) 1212 break; 1213 1214 int minValue = std::numeric_limits<int>::min(); 1215 int maxValue = std::numeric_limits<int>::max(); 1216 for (Relationship relationship : iter->value) { 1217 minValue = std::max(minValue, relationship.minValueOfLeft()); 1218 maxValue = std::min(maxValue, relationship.maxValueOfLeft()); 1219 } 1220 1221 executeNode(block->at(nodeIndex)); 1222 1223 if (minValue >= 0) { 1224 node->convertToIdentityOn(node->child1().node()); 1225 changed = true; 1226 break; 1227 } 1228 if (maxValue <= 0) { 1229 node->convertToArithNegate(); 1230 if (minValue > std::numeric_limits<int>::min()) 1231 node->setArithMode(Arith::Unchecked); 1232 changed = true; 1233 break; 1234 } 1235 if (minValue > std::numeric_limits<int>::min()) { 1236 node->setArithMode(Arith::Unchecked); 1237 changed = true; 1238 break; 1239 } 1240 1241 break; 1242 } 1206 1243 case ArithAdd: { 1207 1244 if (!node->isBinaryUseKind(Int32Use)) … … 1308 1345 setRelationship(Relationship::safeCreate(node->child1().node(), node->child2().node(), Relationship::LessThan)); 1309 1346 setRelationship(Relationship::safeCreate(node->child1().node(), m_zero, Relationship::GreaterThan, -1)); 1347 break; 1348 } 1349 1350 case ArithAbs: { 1351 if (node->child1().useKind() != Int32Use) 1352 break; 1353 setRelationship(Relationship(node, m_zero, Relationship::GreaterThan, -1)); 1310 1354 break; 1311 1355 } -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r194613 r196726 650 650 child2() = Edge(); 651 651 m_op = ArithSqrt; 652 } 653 654 void convertToArithNegate() 655 { 656 ASSERT(m_op == ArithAbs && child1().useKind() == Int32Use); 657 m_op = ArithNegate; 652 658 } 653 659 … … 1679 1685 { 1680 1686 switch (op()) { 1687 case ArithAbs: 1681 1688 case ArithAdd: 1682 1689 case ArithSub: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r195488 r196726 2303 2303 m_jit.add32(scratch.gpr(), result.gpr()); 2304 2304 m_jit.xor32(scratch.gpr(), result.gpr()); 2305 speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31))); 2305 if (shouldCheckOverflow(node->arithMode())) 2306 speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31))); 2306 2307 int32Result(result.gpr(), node); 2307 2308 break; -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r196685 r196726 2125 2125 case Int32Use: { 2126 2126 LValue value = lowInt32(m_node->child1()); 2127 2127 2128 2128 LValue mask = m_out.aShr(value, m_out.constInt32(31)); 2129 2129 LValue result = m_out.bitXor(mask, m_out.add(mask, value)); 2130 2131 speculate(Overflow, noValue(), 0, m_out.equal(result, m_out.constInt32(1 << 31))); 2132 2130 2131 if (shouldCheckOverflow(m_node->arithMode())) 2132 speculate(Overflow, noValue(), 0, m_out.equal(result, m_out.constInt32(1 << 31))); 2133 2133 2134 setInt32(result); 2134 2135 break;
Note: See TracChangeset
for help on using the changeset viewer.