Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: src/hydrogen-instructions.cc

Issue 16206004: Add smi support to all binops minus shr, sar, shl, div and mod. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 } 247 }
248 248
249 249
250 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { 250 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) {
251 return guarantee->IsBoundsCheckBaseIndexInformation() 251 return guarantee->IsBoundsCheckBaseIndexInformation()
252 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check() 252 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check()
253 : guarantee; 253 : guarantee;
254 } 254 }
255 255
256 256
257 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { 257 static int32_t ConvertAndSetOverflow(Representation r,
258 if (result > kMaxInt) { 258 int64_t result,
259 *overflow = true; 259 bool* overflow) {
260 return kMaxInt; 260 if (r.IsSmi()) {
261 } 261 if (result > Smi::kMaxValue) {
262 if (result < kMinInt) { 262 *overflow = true;
263 *overflow = true; 263 return Smi::kMaxValue;
264 return kMinInt; 264 }
265 if (result < Smi::kMinValue) {
266 *overflow = true;
267 return Smi::kMinValue;
268 }
269 } else {
270 if (result > kMaxInt) {
271 *overflow = true;
272 return kMaxInt;
273 }
274 if (result < kMinInt) {
275 *overflow = true;
276 return kMinInt;
277 }
265 } 278 }
266 return static_cast<int32_t>(result); 279 return static_cast<int32_t>(result);
267 } 280 }
268 281
269 282
270 static int32_t AddWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 283 static int32_t AddWithoutOverflow(Representation r,
284 int32_t a,
285 int32_t b,
286 bool* overflow) {
271 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b); 287 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b);
272 return ConvertAndSetOverflow(result, overflow); 288 return ConvertAndSetOverflow(r, result, overflow);
273 } 289 }
274 290
275 291
276 static int32_t SubWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 292 static int32_t SubWithoutOverflow(Representation r,
293 int32_t a,
294 int32_t b,
295 bool* overflow) {
277 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b); 296 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b);
278 return ConvertAndSetOverflow(result, overflow); 297 return ConvertAndSetOverflow(r, result, overflow);
279 } 298 }
280 299
281 300
282 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 301 static int32_t MulWithoutOverflow(Representation r,
302 int32_t a,
303 int32_t b,
304 bool* overflow) {
283 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); 305 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b);
284 return ConvertAndSetOverflow(result, overflow); 306 return ConvertAndSetOverflow(r, result, overflow);
285 } 307 }
286 308
287 309
288 int32_t Range::Mask() const { 310 int32_t Range::Mask() const {
289 if (lower_ == upper_) return lower_; 311 if (lower_ == upper_) return lower_;
290 if (lower_ >= 0) { 312 if (lower_ >= 0) {
291 int32_t res = 1; 313 int32_t res = 1;
292 while (res < upper_) { 314 while (res < upper_) {
293 res = (res << 1) | 1; 315 res = (res << 1) | 1;
294 } 316 }
295 return res; 317 return res;
296 } 318 }
297 return 0xffffffff; 319 return 0xffffffff;
298 } 320 }
299 321
300 322
301 void Range::AddConstant(int32_t value) { 323 void Range::AddConstant(int32_t value) {
302 if (value == 0) return; 324 if (value == 0) return;
303 bool may_overflow = false; // Overflow is ignored here. 325 bool may_overflow = false; // Overflow is ignored here.
304 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); 326 Representation r = Representation::Integer32();
305 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); 327 lower_ = AddWithoutOverflow(r, lower_, value, &may_overflow);
328 upper_ = AddWithoutOverflow(r, upper_, value, &may_overflow);
306 #ifdef DEBUG 329 #ifdef DEBUG
307 Verify(); 330 Verify();
308 #endif 331 #endif
309 } 332 }
310 333
311 334
312 void Range::Intersect(Range* other) { 335 void Range::Intersect(Range* other) {
313 upper_ = Min(upper_, other->upper_); 336 upper_ = Min(upper_, other->upper_);
314 lower_ = Max(lower_, other->lower_); 337 lower_ = Max(lower_, other->lower_);
315 bool b = CanBeMinusZero() && other->CanBeMinusZero(); 338 bool b = CanBeMinusZero() && other->CanBeMinusZero();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 lower_ = lower_ << bits; 377 lower_ = lower_ << bits;
355 upper_ = upper_ << bits; 378 upper_ = upper_ << bits;
356 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) { 379 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
357 upper_ = kMaxInt; 380 upper_ = kMaxInt;
358 lower_ = kMinInt; 381 lower_ = kMinInt;
359 } 382 }
360 set_can_be_minus_zero(false); 383 set_can_be_minus_zero(false);
361 } 384 }
362 385
363 386
364 bool Range::AddAndCheckOverflow(Range* other) { 387 bool Range::AddAndCheckOverflow(const Representation& r, Range* other) {
365 bool may_overflow = false; 388 bool may_overflow = false;
366 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); 389 lower_ = AddWithoutOverflow(r, lower_, other->lower(), &may_overflow);
367 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); 390 upper_ = AddWithoutOverflow(r, upper_, other->upper(), &may_overflow);
368 KeepOrder(); 391 KeepOrder();
369 #ifdef DEBUG 392 #ifdef DEBUG
370 Verify(); 393 Verify();
371 #endif 394 #endif
372 return may_overflow; 395 return may_overflow;
373 } 396 }
374 397
375 398
376 bool Range::SubAndCheckOverflow(Range* other) { 399 bool Range::SubAndCheckOverflow(const Representation& r, Range* other) {
377 bool may_overflow = false; 400 bool may_overflow = false;
378 lower_ = SubWithoutOverflow(lower_, other->upper(), &may_overflow); 401 lower_ = SubWithoutOverflow(r, lower_, other->upper(), &may_overflow);
379 upper_ = SubWithoutOverflow(upper_, other->lower(), &may_overflow); 402 upper_ = SubWithoutOverflow(r, upper_, other->lower(), &may_overflow);
380 KeepOrder(); 403 KeepOrder();
381 #ifdef DEBUG 404 #ifdef DEBUG
382 Verify(); 405 Verify();
383 #endif 406 #endif
384 return may_overflow; 407 return may_overflow;
385 } 408 }
386 409
387 410
388 void Range::KeepOrder() { 411 void Range::KeepOrder() {
389 if (lower_ > upper_) { 412 if (lower_ > upper_) {
390 int32_t tmp = lower_; 413 int32_t tmp = lower_;
391 lower_ = upper_; 414 lower_ = upper_;
392 upper_ = tmp; 415 upper_ = tmp;
393 } 416 }
394 } 417 }
395 418
396 419
397 #ifdef DEBUG 420 #ifdef DEBUG
398 void Range::Verify() const { 421 void Range::Verify() const {
399 ASSERT(lower_ <= upper_); 422 ASSERT(lower_ <= upper_);
400 } 423 }
401 #endif 424 #endif
402 425
403 426
404 bool Range::MulAndCheckOverflow(Range* other) { 427 bool Range::MulAndCheckOverflow(const Representation& r, Range* other) {
405 bool may_overflow = false; 428 bool may_overflow = false;
406 int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow); 429 int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow);
407 int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow); 430 int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow);
408 int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow); 431 int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow);
409 int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow); 432 int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow);
410 lower_ = Min(Min(v1, v2), Min(v3, v4)); 433 lower_ = Min(Min(v1, v2), Min(v3, v4));
411 upper_ = Max(Max(v1, v2), Max(v3, v4)); 434 upper_ = Max(Max(v1, v2), Max(v3, v4));
412 #ifdef DEBUG 435 #ifdef DEBUG
413 Verify(); 436 Verify();
414 #endif 437 #endif
415 return may_overflow; 438 return may_overflow;
416 } 439 }
417 440
418 441
419 const char* HType::ToString() { 442 const char* HType::ToString() {
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 1387
1365 1388
1366 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { 1389 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) {
1367 object()->PrintNameTo(stream); 1390 object()->PrintNameTo(stream);
1368 stream->Add(" "); 1391 stream->Add(" ");
1369 index()->PrintNameTo(stream); 1392 index()->PrintNameTo(stream);
1370 } 1393 }
1371 1394
1372 1395
1373 HValue* HBitwise::Canonicalize() { 1396 HValue* HBitwise::Canonicalize() {
1374 if (!representation().IsInteger32()) return this; 1397 if (!representation().IsSmiOrInteger32()) return this;
1375 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. 1398 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x.
1376 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; 1399 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
1377 if (left()->EqualsInteger32Constant(nop_constant) && 1400 if (left()->EqualsInteger32Constant(nop_constant) &&
1378 !right()->CheckFlag(kUint32)) { 1401 !right()->CheckFlag(kUint32)) {
1379 return right(); 1402 return right();
1380 } 1403 }
1381 if (right()->EqualsInteger32Constant(nop_constant) && 1404 if (right()->EqualsInteger32Constant(nop_constant) &&
1382 !left()->CheckFlag(kUint32)) { 1405 !left()->CheckFlag(kUint32)) {
1383 return left(); 1406 return left();
1384 } 1407 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic()); 1496 stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic());
1474 1497
1475 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); 1498 if (CanTruncateToInt32()) stream->Add(" truncating-int32");
1476 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); 1499 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
1477 if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan"); 1500 if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan");
1478 } 1501 }
1479 1502
1480 1503
1481 HValue* HUnaryMathOperation::Canonicalize() { 1504 HValue* HUnaryMathOperation::Canonicalize() {
1482 if (op() == kMathFloor) { 1505 if (op() == kMathFloor) {
1483 // If the input is integer32 then we replace the floor instruction 1506 // If the input is smi or integer32 then we replace the floor instruction
1484 // with its input. This happens before the representation changes are 1507 // with its input. This happens before the representation changes are
1485 // introduced. 1508 // introduced.
1486 if (value()->representation().IsInteger32()) return value(); 1509 if (value()->representation().IsSmiOrInteger32()) return value();
1487 1510
1488 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \ 1511 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \
1489 defined(V8_TARGET_ARCH_X64) 1512 defined(V8_TARGET_ARCH_X64)
1490 if (value()->IsDiv() && (value()->UseCount() == 1)) { 1513 if (value()->IsDiv() && (value()->UseCount() == 1)) {
1491 // TODO(2038): Implement this optimization for non ARM architectures. 1514 // TODO(2038): Implement this optimization for non ARM architectures.
1492 HDiv* hdiv = HDiv::cast(value()); 1515 HDiv* hdiv = HDiv::cast(value());
1493 HValue* left = hdiv->left(); 1516 HValue* left = hdiv->left();
1494 HValue* right = hdiv->right(); 1517 HValue* right = hdiv->right();
1495 // Try to simplify left and right values of the division. 1518 // Try to simplify left and right values of the division.
1496 HValue* new_left = 1519 HValue* new_left =
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 left()->PrintNameTo(stream); 1677 left()->PrintNameTo(stream);
1655 stream->Add(" "); 1678 stream->Add(" ");
1656 right()->PrintNameTo(stream); 1679 right()->PrintNameTo(stream);
1657 stream->Add(" "); 1680 stream->Add(" ");
1658 context()->PrintNameTo(stream); 1681 context()->PrintNameTo(stream);
1659 } 1682 }
1660 1683
1661 1684
1662 Range* HValue::InferRange(Zone* zone) { 1685 Range* HValue::InferRange(Zone* zone) {
1663 Range* result; 1686 Range* result;
1664 if (type().IsSmi()) { 1687 if (representation().IsSmi() || type().IsSmi()) {
1665 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); 1688 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue);
1666 result->set_can_be_minus_zero(false); 1689 result->set_can_be_minus_zero(false);
1667 } else { 1690 } else {
1668 // Untagged integer32 cannot be -0, all other representations can. 1691 // Untagged integer32 cannot be -0, all other representations can.
1669 result = new(zone) Range(); 1692 result = new(zone) Range();
1670 result->set_can_be_minus_zero(!representation().IsInteger32()); 1693 result->set_can_be_minus_zero(!representation().IsInteger32());
1671 } 1694 }
1672 return result; 1695 return result;
1673 } 1696 }
1674 1697
1675 1698
1676 Range* HChange::InferRange(Zone* zone) { 1699 Range* HChange::InferRange(Zone* zone) {
1677 Range* input_range = value()->range(); 1700 Range* input_range = value()->range();
1678 if (from().IsInteger32() && 1701 if (from().IsInteger32() &&
1679 to().IsSmiOrTagged() && 1702 to().IsSmiOrTagged() &&
1680 !value()->CheckFlag(HInstruction::kUint32) && 1703 !value()->CheckFlag(HInstruction::kUint32) &&
1681 input_range != NULL && input_range->IsInSmiRange()) { 1704 input_range != NULL && input_range->IsInSmiRange()) {
1682 set_type(HType::Smi()); 1705 set_type(HType::Smi());
1683 ClearGVNFlag(kChangesNewSpacePromotion); 1706 ClearGVNFlag(kChangesNewSpacePromotion);
1684 } 1707 }
1685 Range* result = (input_range != NULL) 1708 Range* result = (input_range != NULL)
1686 ? input_range->Copy(zone) 1709 ? input_range->Copy(zone)
1687 : HValue::InferRange(zone); 1710 : HValue::InferRange(zone);
1688 if (to().IsInteger32()) result->set_can_be_minus_zero(false); 1711 if (to().IsSmiOrInteger32()) result->set_can_be_minus_zero(false);
1689 return result; 1712 return result;
1690 } 1713 }
1691 1714
1692 1715
1693 Range* HConstant::InferRange(Zone* zone) { 1716 Range* HConstant::InferRange(Zone* zone) {
1694 if (has_int32_value_) { 1717 if (has_int32_value_) {
1695 Range* result = new(zone) Range(int32_value_, int32_value_); 1718 Range* result = new(zone) Range(int32_value_, int32_value_);
1696 result->set_can_be_minus_zero(false); 1719 result->set_can_be_minus_zero(false);
1697 return result; 1720 return result;
1698 } 1721 }
1699 return HValue::InferRange(zone); 1722 return HValue::InferRange(zone);
1700 } 1723 }
1701 1724
1702 1725
1703 Range* HPhi::InferRange(Zone* zone) { 1726 Range* HPhi::InferRange(Zone* zone) {
1704 if (representation().IsInteger32()) { 1727 Representation r = representation();
1728 if (r.IsSmiOrInteger32()) {
1705 if (block()->IsLoopHeader()) { 1729 if (block()->IsLoopHeader()) {
1706 Range* range = new(zone) Range(kMinInt, kMaxInt); 1730 Range* range = r.IsSmi()
1731 ? new(zone) Range(Smi::kMinValue, Smi::kMaxValue)
1732 : new(zone) Range(kMinInt, kMaxInt);
1707 return range; 1733 return range;
1708 } else { 1734 } else {
1709 Range* range = OperandAt(0)->range()->Copy(zone); 1735 Range* range = OperandAt(0)->range()->Copy(zone);
1710 for (int i = 1; i < OperandCount(); ++i) { 1736 for (int i = 1; i < OperandCount(); ++i) {
1711 range->Union(OperandAt(i)->range()); 1737 range->Union(OperandAt(i)->range());
1712 } 1738 }
1713 return range; 1739 return range;
1714 } 1740 }
1715 } else { 1741 } else {
1716 return HValue::InferRange(zone); 1742 return HValue::InferRange(zone);
1717 } 1743 }
1718 } 1744 }
1719 1745
1720 1746
1721 Range* HAdd::InferRange(Zone* zone) { 1747 Range* HAdd::InferRange(Zone* zone) {
1722 if (representation().IsInteger32()) { 1748 Representation r = representation();
1749 if (r.IsSmiOrInteger32()) {
1723 Range* a = left()->range(); 1750 Range* a = left()->range();
1724 Range* b = right()->range(); 1751 Range* b = right()->range();
1725 Range* res = a->Copy(zone); 1752 Range* res = a->Copy(zone);
1726 if (!res->AddAndCheckOverflow(b)) { 1753 if (!res->AddAndCheckOverflow(r, b)) {
1727 ClearFlag(kCanOverflow); 1754 ClearFlag(kCanOverflow);
1728 } 1755 }
1729 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); 1756 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero();
1730 res->set_can_be_minus_zero(m0); 1757 res->set_can_be_minus_zero(m0);
1731 return res; 1758 return res;
1732 } else { 1759 } else {
1733 return HValue::InferRange(zone); 1760 return HValue::InferRange(zone);
1734 } 1761 }
1735 } 1762 }
1736 1763
1737 1764
1738 Range* HSub::InferRange(Zone* zone) { 1765 Range* HSub::InferRange(Zone* zone) {
1739 if (representation().IsInteger32()) { 1766 Representation r = representation();
1767 if (r.IsSmiOrInteger32()) {
1740 Range* a = left()->range(); 1768 Range* a = left()->range();
1741 Range* b = right()->range(); 1769 Range* b = right()->range();
1742 Range* res = a->Copy(zone); 1770 Range* res = a->Copy(zone);
1743 if (!res->SubAndCheckOverflow(b)) { 1771 if (!res->SubAndCheckOverflow(r, b)) {
1744 ClearFlag(kCanOverflow); 1772 ClearFlag(kCanOverflow);
1745 } 1773 }
1746 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); 1774 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero());
1747 return res; 1775 return res;
1748 } else { 1776 } else {
1749 return HValue::InferRange(zone); 1777 return HValue::InferRange(zone);
1750 } 1778 }
1751 } 1779 }
1752 1780
1753 1781
1754 Range* HMul::InferRange(Zone* zone) { 1782 Range* HMul::InferRange(Zone* zone) {
1755 if (representation().IsInteger32()) { 1783 Representation r = representation();
1784 if (r.IsSmiOrInteger32()) {
1756 Range* a = left()->range(); 1785 Range* a = left()->range();
1757 Range* b = right()->range(); 1786 Range* b = right()->range();
1758 Range* res = a->Copy(zone); 1787 Range* res = a->Copy(zone);
1759 if (!res->MulAndCheckOverflow(b)) { 1788 if (!res->MulAndCheckOverflow(r, b)) {
1760 ClearFlag(kCanOverflow); 1789 ClearFlag(kCanOverflow);
1761 } 1790 }
1762 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || 1791 bool m0 = (a->CanBeZero() && b->CanBeNegative()) ||
1763 (a->CanBeNegative() && b->CanBeZero()); 1792 (a->CanBeNegative() && b->CanBeZero());
1764 res->set_can_be_minus_zero(m0); 1793 res->set_can_be_minus_zero(m0);
1765 return res; 1794 return res;
1766 } else { 1795 } else {
1767 return HValue::InferRange(zone); 1796 return HValue::InferRange(zone);
1768 } 1797 }
1769 } 1798 }
1770 1799
1771 1800
1772 Range* HDiv::InferRange(Zone* zone) { 1801 Range* HDiv::InferRange(Zone* zone) {
1773 if (representation().IsInteger32()) { 1802 Representation r = representation();
1803 if (r.IsSmiOrInteger32()) {
1774 Range* a = left()->range(); 1804 Range* a = left()->range();
1775 Range* b = right()->range(); 1805 Range* b = right()->range();
1776 Range* result = new(zone) Range(); 1806 Range* result = new(zone) Range();
1777 if (a->CanBeMinusZero()) { 1807 if (a->CanBeMinusZero()) {
1778 result->set_can_be_minus_zero(true); 1808 result->set_can_be_minus_zero(true);
1779 } 1809 }
1780 1810
1781 if (a->CanBeZero() && b->CanBeNegative()) { 1811 if (a->CanBeZero() && b->CanBeNegative()) {
1782 result->set_can_be_minus_zero(true); 1812 result->set_can_be_minus_zero(true);
1783 } 1813 }
1784 1814
1785 if (!a->Includes(kMinInt) || !b->Includes(-1)) { 1815 if (!b->Includes(-1) ||
1816 (r.IsSmi() && !a->Includes(Smi::kMinValue)) ||
1817 (r.IsInteger32() && !a->Includes(kMinInt))) {
1786 ClearFlag(HValue::kCanOverflow); 1818 ClearFlag(HValue::kCanOverflow);
1787 } 1819 }
1788 1820
1789 if (!b->CanBeZero()) { 1821 if (!b->CanBeZero()) {
1790 ClearFlag(HValue::kCanBeDivByZero); 1822 ClearFlag(HValue::kCanBeDivByZero);
1791 } 1823 }
1792 return result; 1824 return result;
1793 } else { 1825 } else {
1794 return HValue::InferRange(zone); 1826 return HValue::InferRange(zone);
1795 } 1827 }
1796 } 1828 }
1797 1829
1798 1830
1799 Range* HMod::InferRange(Zone* zone) { 1831 Range* HMod::InferRange(Zone* zone) {
1800 if (representation().IsInteger32()) { 1832 Representation r = representation();
1833 if (r.IsSmiOrInteger32()) {
1801 Range* a = left()->range(); 1834 Range* a = left()->range();
1802 Range* b = right()->range(); 1835 Range* b = right()->range();
1803 1836
1804 // The magnitude of the modulus is bounded by the right operand. Note that 1837 // The magnitude of the modulus is bounded by the right operand. Note that
1805 // apart for the cases involving kMinInt, the calculation below is the same 1838 // apart for the cases involving kMinInt, the calculation below is the same
1806 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. 1839 // as Max(Abs(b->lower()), Abs(b->upper())) - 1.
1807 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); 1840 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1);
1808 1841
1809 // The result of the modulo operation has the sign of its left operand. 1842 // The result of the modulo operation has the sign of its left operand.
1810 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); 1843 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative();
1811 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, 1844 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
1812 a->CanBePositive() ? positive_bound : 0); 1845 a->CanBePositive() ? positive_bound : 0);
1813 1846
1814 if (left_can_be_negative) { 1847 if (left_can_be_negative) {
1815 result->set_can_be_minus_zero(true); 1848 result->set_can_be_minus_zero(true);
1816 } 1849 }
1817 1850
1818 if (!a->Includes(kMinInt) || !b->Includes(-1)) { 1851 if (!b->Includes(-1) ||
1852 (r.IsSmi() && !a->Includes(Smi::kMinValue)) ||
Sven Panne 2013/06/04 09:53:56 * Re-order back to a, then b test. * Introduce 'mi
Sven Panne 2013/06/04 10:01:07 Thinking about it: We have to avoid an idiv of 0x8
Toon Verwaest 2013/06/04 15:06:40 You are right. I actually (temporarily) backed out
1853 (r.IsInteger32() && !a->Includes(kMinInt))) {
1819 ClearFlag(HValue::kCanOverflow); 1854 ClearFlag(HValue::kCanOverflow);
1820 } 1855 }
1821 1856
1822 if (!b->CanBeZero()) { 1857 if (!b->CanBeZero()) {
1823 ClearFlag(HValue::kCanBeDivByZero); 1858 ClearFlag(HValue::kCanBeDivByZero);
1824 } 1859 }
1825 return result; 1860 return result;
1826 } else { 1861 } else {
1827 return HValue::InferRange(zone); 1862 return HValue::InferRange(zone);
1828 } 1863 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1877 break; 1912 break;
1878 } 1913 }
1879 } 1914 }
1880 ClearFlag(kNumericConstraintEvaluationInProgress); 1915 ClearFlag(kNumericConstraintEvaluationInProgress);
1881 1916
1882 return result; 1917 return result;
1883 } 1918 }
1884 1919
1885 1920
1886 Range* HMathMinMax::InferRange(Zone* zone) { 1921 Range* HMathMinMax::InferRange(Zone* zone) {
1887 if (representation().IsInteger32()) { 1922 if (representation().IsSmiOrInteger32()) {
1888 Range* a = left()->range(); 1923 Range* a = left()->range();
1889 Range* b = right()->range(); 1924 Range* b = right()->range();
1890 Range* res = a->Copy(zone); 1925 Range* res = a->Copy(zone);
1891 if (operation_ == kMathMax) { 1926 if (operation_ == kMathMax) {
1892 res->CombinedMax(b); 1927 res->CombinedMax(b);
1893 } else { 1928 } else {
1894 ASSERT(operation_ == kMathMin); 1929 ASSERT(operation_ == kMathMin);
1895 res->CombinedMin(b); 1930 res->CombinedMin(b);
1896 } 1931 }
1897 return res; 1932 return res;
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
2167 } else if (has_int32_value_) { 2202 } else if (has_int32_value_) {
2168 r = Representation::Integer32(); 2203 r = Representation::Integer32();
2169 } else if (has_double_value_) { 2204 } else if (has_double_value_) {
2170 r = Representation::Double(); 2205 r = Representation::Double();
2171 } else { 2206 } else {
2172 r = Representation::Tagged(); 2207 r = Representation::Tagged();
2173 } 2208 }
2174 } 2209 }
2175 set_representation(r); 2210 set_representation(r);
2176 SetFlag(kUseGVN); 2211 SetFlag(kUseGVN);
2177 if (representation().IsInteger32()) { 2212 if (representation().IsSmiOrInteger32()) {
2178 ClearGVNFlag(kDependsOnOsrEntries); 2213 ClearGVNFlag(kDependsOnOsrEntries);
2179 } 2214 }
2180 } 2215 }
2181 2216
2182 2217
2183 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { 2218 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
2184 if (r.IsSmi() && !has_smi_value_) return NULL; 2219 if (r.IsSmi() && !has_smi_value_) return NULL;
2185 if (r.IsInteger32() && !has_int32_value_) return NULL; 2220 if (r.IsInteger32() && !has_int32_value_) return NULL;
2186 if (r.IsDouble() && !has_double_value_) return NULL; 2221 if (r.IsDouble() && !has_double_value_) return NULL;
2187 if (has_int32_value_) { 2222 if (has_int32_value_) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2262 !this->IsDiv() && 2297 !this->IsDiv() &&
2263 CheckUsesForFlag(kTruncatingToInt32); 2298 CheckUsesForFlag(kTruncatingToInt32);
2264 } 2299 }
2265 2300
2266 2301
2267 Representation HBinaryOperation::RepresentationFromInputs() { 2302 Representation HBinaryOperation::RepresentationFromInputs() {
2268 // Determine the worst case of observed input representations and 2303 // Determine the worst case of observed input representations and
2269 // the currently assumed output representation. 2304 // the currently assumed output representation.
2270 Representation rep = representation(); 2305 Representation rep = representation();
2271 for (int i = 1; i <= 2; ++i) { 2306 for (int i = 1; i <= 2; ++i) {
2272 Representation input_rep = observed_input_representation(i); 2307 rep = rep.generalize(observed_input_representation(i));
2273 if (input_rep.is_more_general_than(rep)) rep = input_rep;
2274 } 2308 }
2275 // If any of the actual input representation is more general than what we 2309 // If any of the actual input representation is more general than what we
2276 // have so far but not Tagged, use that representation instead. 2310 // have so far but not Tagged, use that representation instead.
2277 Representation left_rep = left()->representation(); 2311 Representation left_rep = left()->representation();
2278 Representation right_rep = right()->representation(); 2312 Representation right_rep = right()->representation();
2279 2313
2280 if (left_rep.is_more_general_than(rep) && !left_rep.IsTagged()) { 2314 if (left_rep.is_more_general_than(rep) && !left_rep.IsTagged()) {
2281 rep = left_rep; 2315 rep = left_rep;
2282 } 2316 }
2283 if (right_rep.is_more_general_than(rep) && !right_rep.IsTagged()) { 2317 if (right_rep.is_more_general_than(rep) && !right_rep.IsTagged()) {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
2449 stream->Add("B%d", SuccessorAt(0)->block_id()); 2483 stream->Add("B%d", SuccessorAt(0)->block_id());
2450 } 2484 }
2451 2485
2452 2486
2453 void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) { 2487 void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) {
2454 Representation left_rep = left()->representation(); 2488 Representation left_rep = left()->representation();
2455 Representation right_rep = right()->representation(); 2489 Representation right_rep = right()->representation();
2456 Representation observed_left = observed_input_representation(0); 2490 Representation observed_left = observed_input_representation(0);
2457 Representation observed_right = observed_input_representation(1); 2491 Representation observed_right = observed_input_representation(1);
2458 2492
2459 Representation rep = Representation::Smi(); 2493 Representation rep = observed_left.generalize(observed_right);
2460 if (observed_left.IsInteger32() && observed_right.IsInteger32()) { 2494 if (rep.IsNone() || rep.IsSmiOrInteger32()) {
2461 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); 2495 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
2462 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); 2496 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
2463 } else { 2497 } else {
2464 rep = Representation::Double(); 2498 rep = Representation::Double();
2465 } 2499 }
2466 2500
2467 if (rep.IsDouble()) { 2501 if (rep.IsDouble()) {
2468 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, === 2502 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, ===
2469 // and !=) have special handling of undefined, e.g. undefined == undefined 2503 // and !=) have special handling of undefined, e.g. undefined == undefined
2470 // is 'true'. Relational comparisons have a different semantic, first 2504 // is 'true'. Relational comparisons have a different semantic, first
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
3046 3080
3047 3081
3048 HType HFunctionLiteral::CalculateInferredType() { 3082 HType HFunctionLiteral::CalculateInferredType() {
3049 return HType::JSObject(); 3083 return HType::JSObject();
3050 } 3084 }
3051 3085
3052 3086
3053 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( 3087 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero(
3054 BitVector* visited) { 3088 BitVector* visited) {
3055 visited->Add(id()); 3089 visited->Add(id());
3056 if (representation().IsInteger32() && 3090 if (representation().IsSmiOrInteger32() &&
3057 !value()->representation().IsInteger32()) { 3091 !value()->representation().Equals(representation())) {
3058 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { 3092 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) {
3059 SetFlag(kBailoutOnMinusZero); 3093 SetFlag(kBailoutOnMinusZero);
3060 } 3094 }
3061 } 3095 }
3062 if (RequiredInputRepresentation(0).IsInteger32() && 3096 if (RequiredInputRepresentation(0).IsSmiOrInteger32() &&
3063 representation().IsInteger32()) { 3097 representation().Equals(RequiredInputRepresentation(0))) {
3064 return value(); 3098 return value();
3065 } 3099 }
3066 return NULL; 3100 return NULL;
3067 } 3101 }
3068 3102
3069 3103
3070 3104
3071 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { 3105 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) {
3072 visited->Add(id()); 3106 visited->Add(id());
3073 if (from().IsInteger32()) return NULL; 3107 if (from().IsSmiOrInteger32()) return NULL;
3074 if (CanTruncateToInt32()) return NULL; 3108 if (CanTruncateToInt32()) return NULL;
3075 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { 3109 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) {
3076 SetFlag(kBailoutOnMinusZero); 3110 SetFlag(kBailoutOnMinusZero);
3077 } 3111 }
3078 ASSERT(!from().IsInteger32() || !to().IsInteger32()); 3112 ASSERT(!from().IsSmiOrInteger32() || !to().IsSmiOrInteger32());
3079 return NULL; 3113 return NULL;
3080 } 3114 }
3081 3115
3082 3116
3083 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero( 3117 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero(
3084 BitVector* visited) { 3118 BitVector* visited) {
3085 visited->Add(id()); 3119 visited->Add(id());
3086 return value(); 3120 return value();
3087 } 3121 }
3088 3122
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3155 if (value()->IsConstant()) { 3189 if (value()->IsConstant()) {
3156 return false; 3190 return false;
3157 } 3191 }
3158 3192
3159 if (value()->IsLoadKeyed()) { 3193 if (value()->IsLoadKeyed()) {
3160 return IsExternalFloatOrDoubleElementsKind( 3194 return IsExternalFloatOrDoubleElementsKind(
3161 HLoadKeyed::cast(value())->elements_kind()); 3195 HLoadKeyed::cast(value())->elements_kind());
3162 } 3196 }
3163 3197
3164 if (value()->IsChange()) { 3198 if (value()->IsChange()) {
3165 if (HChange::cast(value())->from().IsInteger32()) { 3199 if (HChange::cast(value())->from().IsSmiOrInteger32()) {
3166 return false; 3200 return false;
3167 } 3201 }
3168 if (HChange::cast(value())->value()->type().IsSmi()) { 3202 if (HChange::cast(value())->value()->type().IsSmi()) {
3169 return false; 3203 return false;
3170 } 3204 }
3171 } 3205 }
3172 return true; 3206 return true;
3173 } 3207 }
3174 3208
3175 3209
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
3531 } else { 3565 } else {
3532 // This catches |false|, |undefined|, strings and objects. 3566 // This catches |false|, |undefined|, strings and objects.
3533 SetOperandAt(i, graph->GetConstant0()); 3567 SetOperandAt(i, graph->GetConstant0());
3534 } 3568 }
3535 } 3569 }
3536 // Overwrite observed input representations because they are likely Tagged. 3570 // Overwrite observed input representations because they are likely Tagged.
3537 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 3571 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
3538 HValue* use = it.value(); 3572 HValue* use = it.value();
3539 if (use->IsBinaryOperation()) { 3573 if (use->IsBinaryOperation()) {
3540 HBinaryOperation::cast(use)->set_observed_input_representation( 3574 HBinaryOperation::cast(use)->set_observed_input_representation(
3541 it.index(), Representation::Integer32()); 3575 it.index(), Representation::Smi());
3542 } 3576 }
3543 } 3577 }
3544 } 3578 }
3545 3579
3546 3580
3547 void HPhi::InferRepresentation(HInferRepresentation* h_infer) { 3581 void HPhi::InferRepresentation(HInferRepresentation* h_infer) {
3548 ASSERT(CheckFlag(kFlexibleRepresentation)); 3582 ASSERT(CheckFlag(kFlexibleRepresentation));
3549 Representation new_rep = RepresentationFromInputs(); 3583 Representation new_rep = RepresentationFromInputs();
3550 UpdateRepresentation(new_rep, h_infer, "inputs"); 3584 UpdateRepresentation(new_rep, h_infer, "inputs");
3551 new_rep = RepresentationFromUses(); 3585 new_rep = RepresentationFromUses();
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
3759 case kBackingStore: 3793 case kBackingStore:
3760 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); 3794 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
3761 stream->Add("[backing-store]"); 3795 stream->Add("[backing-store]");
3762 break; 3796 break;
3763 } 3797 }
3764 3798
3765 stream->Add("@%d", offset()); 3799 stream->Add("@%d", offset());
3766 } 3800 }
3767 3801
3768 } } // namespace v8::internal 3802 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698