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

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

Issue 18434004: Fix and cleanup can_be_minus_zero computation (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fixed nits Created 7 years, 5 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
« no previous file with comments | « no previous file | test/mjsunit/compiler/minus-zero.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 context()->PrintNameTo(stream); 1730 context()->PrintNameTo(stream);
1731 } 1731 }
1732 1732
1733 1733
1734 Range* HValue::InferRange(Zone* zone) { 1734 Range* HValue::InferRange(Zone* zone) {
1735 Range* result; 1735 Range* result;
1736 if (type().IsSmi()) { 1736 if (type().IsSmi()) {
1737 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); 1737 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue);
1738 result->set_can_be_minus_zero(false); 1738 result->set_can_be_minus_zero(false);
1739 } else { 1739 } else {
1740 // Untagged integer32 cannot be -0, all other representations can.
1741 result = new(zone) Range(); 1740 result = new(zone) Range();
1742 result->set_can_be_minus_zero(!representation().IsInteger32()); 1741 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32));
1742 // TODO(jkummerow): The range cannot be minus zero when the upper type
1743 // bound is Integer32.
1743 } 1744 }
1744 return result; 1745 return result;
1745 } 1746 }
1746 1747
1747 1748
1748 Range* HChange::InferRange(Zone* zone) { 1749 Range* HChange::InferRange(Zone* zone) {
1749 Range* input_range = value()->range(); 1750 Range* input_range = value()->range();
1750 if (from().IsInteger32() && 1751 if (from().IsInteger32() &&
1751 to().IsSmiOrTagged() && 1752 to().IsSmiOrTagged() &&
1752 !value()->CheckFlag(HInstruction::kUint32) && 1753 !value()->CheckFlag(HInstruction::kUint32) &&
1753 input_range != NULL && input_range->IsInSmiRange()) { 1754 input_range != NULL && input_range->IsInSmiRange()) {
1754 set_type(HType::Smi()); 1755 set_type(HType::Smi());
1755 ClearGVNFlag(kChangesNewSpacePromotion); 1756 ClearGVNFlag(kChangesNewSpacePromotion);
1756 } 1757 }
1757 Range* result = (input_range != NULL) 1758 Range* result = (input_range != NULL)
1758 ? input_range->Copy(zone) 1759 ? input_range->Copy(zone)
1759 : HValue::InferRange(zone); 1760 : HValue::InferRange(zone);
1760 if (to().IsInteger32()) result->set_can_be_minus_zero(false); 1761 result->set_can_be_minus_zero(!to().IsSmiOrInteger32() ||
1762 !CheckFlag(kAllUsesTruncatingToInt32));
1761 return result; 1763 return result;
1762 } 1764 }
1763 1765
1764 1766
1765 Range* HConstant::InferRange(Zone* zone) { 1767 Range* HConstant::InferRange(Zone* zone) {
1766 if (has_int32_value_) { 1768 if (has_int32_value_) {
1767 Range* result = new(zone) Range(int32_value_, int32_value_); 1769 Range* result = new(zone) Range(int32_value_, int32_value_);
1768 result->set_can_be_minus_zero(false); 1770 result->set_can_be_minus_zero(false);
1769 return result; 1771 return result;
1770 } 1772 }
(...skipping 24 matching lines...) Expand all
1795 1797
1796 Range* HAdd::InferRange(Zone* zone) { 1798 Range* HAdd::InferRange(Zone* zone) {
1797 if (representation().IsInteger32()) { 1799 if (representation().IsInteger32()) {
1798 Range* a = left()->range(); 1800 Range* a = left()->range();
1799 Range* b = right()->range(); 1801 Range* b = right()->range();
1800 Range* res = a->Copy(zone); 1802 Range* res = a->Copy(zone);
1801 if (!res->AddAndCheckOverflow(b) || 1803 if (!res->AddAndCheckOverflow(b) ||
1802 CheckFlag(kAllUsesTruncatingToInt32)) { 1804 CheckFlag(kAllUsesTruncatingToInt32)) {
1803 ClearFlag(kCanOverflow); 1805 ClearFlag(kCanOverflow);
1804 } 1806 }
1805 if (!CheckFlag(kAllUsesTruncatingToInt32)) { 1807 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
1806 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeMinusZero()); 1808 a->CanBeMinusZero() && b->CanBeMinusZero());
1807 }
1808 return res; 1809 return res;
1809 } else { 1810 } else {
1810 return HValue::InferRange(zone); 1811 return HValue::InferRange(zone);
1811 } 1812 }
1812 } 1813 }
1813 1814
1814 1815
1815 Range* HSub::InferRange(Zone* zone) { 1816 Range* HSub::InferRange(Zone* zone) {
1816 if (representation().IsInteger32()) { 1817 if (representation().IsInteger32()) {
1817 Range* a = left()->range(); 1818 Range* a = left()->range();
1818 Range* b = right()->range(); 1819 Range* b = right()->range();
1819 Range* res = a->Copy(zone); 1820 Range* res = a->Copy(zone);
1820 if (!res->SubAndCheckOverflow(b) || 1821 if (!res->SubAndCheckOverflow(b) ||
1821 CheckFlag(kAllUsesTruncatingToInt32)) { 1822 CheckFlag(kAllUsesTruncatingToInt32)) {
1822 ClearFlag(kCanOverflow); 1823 ClearFlag(kCanOverflow);
1823 } 1824 }
1824 if (!CheckFlag(kAllUsesTruncatingToInt32)) { 1825 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
1825 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); 1826 a->CanBeMinusZero() && b->CanBeZero());
1826 }
1827 return res; 1827 return res;
1828 } else { 1828 } else {
1829 return HValue::InferRange(zone); 1829 return HValue::InferRange(zone);
1830 } 1830 }
1831 } 1831 }
1832 1832
1833 1833
1834 Range* HMul::InferRange(Zone* zone) { 1834 Range* HMul::InferRange(Zone* zone) {
1835 if (representation().IsInteger32()) { 1835 if (representation().IsInteger32()) {
1836 Range* a = left()->range(); 1836 Range* a = left()->range();
1837 Range* b = right()->range(); 1837 Range* b = right()->range();
1838 Range* res = a->Copy(zone); 1838 Range* res = a->Copy(zone);
1839 if (!res->MulAndCheckOverflow(b)) { 1839 if (!res->MulAndCheckOverflow(b)) {
1840 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 1840 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32
1841 // would be wrong, because truncated integer multiplication is too 1841 // would be wrong, because truncated integer multiplication is too
1842 // precise and therefore not the same as converting to Double and back. 1842 // precise and therefore not the same as converting to Double and back.
1843 ClearFlag(kCanOverflow); 1843 ClearFlag(kCanOverflow);
1844 } 1844 }
1845 if (!CheckFlag(kAllUsesTruncatingToInt32)) { 1845 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
1846 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || 1846 ((a->CanBeZero() && b->CanBeNegative()) ||
1847 (a->CanBeNegative() && b->CanBeZero()); 1847 (a->CanBeNegative() && b->CanBeZero())));
1848 res->set_can_be_minus_zero(m0);
1849 }
1850 return res; 1848 return res;
1851 } else { 1849 } else {
1852 return HValue::InferRange(zone); 1850 return HValue::InferRange(zone);
1853 } 1851 }
1854 } 1852 }
1855 1853
1856 1854
1857 Range* HDiv::InferRange(Zone* zone) { 1855 Range* HDiv::InferRange(Zone* zone) {
1858 if (representation().IsInteger32()) { 1856 if (representation().IsInteger32()) {
1859 Range* a = left()->range(); 1857 Range* a = left()->range();
1860 Range* b = right()->range(); 1858 Range* b = right()->range();
1861 Range* result = new(zone) Range(); 1859 Range* result = new(zone) Range();
1862 if (!CheckFlag(kAllUsesTruncatingToInt32)) { 1860 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
1863 if (a->CanBeMinusZero()) { 1861 (a->CanBeMinusZero() ||
1864 result->set_can_be_minus_zero(true); 1862 (a->CanBeZero() && b->CanBeNegative())));
1865 }
1866
1867 if (a->CanBeZero() && b->CanBeNegative()) {
1868 result->set_can_be_minus_zero(true);
1869 }
1870 }
1871
1872 if (!a->Includes(kMinInt) || !b->Includes(-1)) { 1863 if (!a->Includes(kMinInt) || !b->Includes(-1)) {
1873 ClearFlag(HValue::kCanOverflow); 1864 ClearFlag(HValue::kCanOverflow);
1874 } 1865 }
1875 1866
1876 if (!b->CanBeZero()) { 1867 if (!b->CanBeZero()) {
1877 ClearFlag(HValue::kCanBeDivByZero); 1868 ClearFlag(HValue::kCanBeDivByZero);
1878 } 1869 }
1879 return result; 1870 return result;
1880 } else { 1871 } else {
1881 return HValue::InferRange(zone); 1872 return HValue::InferRange(zone);
1882 } 1873 }
1883 } 1874 }
1884 1875
1885 1876
1886 Range* HMod::InferRange(Zone* zone) { 1877 Range* HMod::InferRange(Zone* zone) {
1887 if (representation().IsInteger32()) { 1878 if (representation().IsInteger32()) {
1888 Range* a = left()->range(); 1879 Range* a = left()->range();
1889 Range* b = right()->range(); 1880 Range* b = right()->range();
1890 1881
1891 // The magnitude of the modulus is bounded by the right operand. Note that 1882 // The magnitude of the modulus is bounded by the right operand. Note that
1892 // apart for the cases involving kMinInt, the calculation below is the same 1883 // apart for the cases involving kMinInt, the calculation below is the same
1893 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. 1884 // as Max(Abs(b->lower()), Abs(b->upper())) - 1.
1894 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); 1885 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1);
1895 1886
1896 // The result of the modulo operation has the sign of its left operand. 1887 // The result of the modulo operation has the sign of its left operand.
1897 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); 1888 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative();
1898 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, 1889 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
1899 a->CanBePositive() ? positive_bound : 0); 1890 a->CanBePositive() ? positive_bound : 0);
1900 1891
1901 if (left_can_be_negative && !CheckFlag(kAllUsesTruncatingToInt32)) { 1892 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
1902 result->set_can_be_minus_zero(true); 1893 left_can_be_negative);
1903 }
1904 1894
1905 if (!a->Includes(kMinInt) || !b->Includes(-1)) { 1895 if (!a->Includes(kMinInt) || !b->Includes(-1)) {
1906 ClearFlag(HValue::kCanOverflow); 1896 ClearFlag(HValue::kCanOverflow);
1907 } 1897 }
1908 1898
1909 if (!b->CanBeZero()) { 1899 if (!b->CanBeZero()) {
1910 ClearFlag(HValue::kCanBeDivByZero); 1900 ClearFlag(HValue::kCanBeDivByZero);
1911 } 1901 }
1912 return result; 1902 return result;
1913 } else { 1903 } else {
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
2443 static_cast<uint32_t>( 2433 static_cast<uint32_t>(
2444 left_upper | left_lower | right_upper | right_lower)); 2434 left_upper | left_lower | right_upper | right_lower));
2445 2435
2446 int64_t limit = 1; 2436 int64_t limit = 1;
2447 limit <<= high; 2437 limit <<= high;
2448 int32_t min = (left()->range()->CanBeNegative() || 2438 int32_t min = (left()->range()->CanBeNegative() ||
2449 right()->range()->CanBeNegative()) 2439 right()->range()->CanBeNegative())
2450 ? static_cast<int32_t>(-limit) : 0; 2440 ? static_cast<int32_t>(-limit) : 0;
2451 return new(zone) Range(min, static_cast<int32_t>(limit - 1)); 2441 return new(zone) Range(min, static_cast<int32_t>(limit - 1));
2452 } 2442 }
2453 return HValue::InferRange(zone); 2443 Range* result = HValue::InferRange(zone);
2444 result->set_can_be_minus_zero(false);
2445 return result;
2454 } 2446 }
2455 const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff); 2447 const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff);
2456 int32_t left_mask = (left()->range() != NULL) 2448 int32_t left_mask = (left()->range() != NULL)
2457 ? left()->range()->Mask() 2449 ? left()->range()->Mask()
2458 : kDefaultMask; 2450 : kDefaultMask;
2459 int32_t right_mask = (right()->range() != NULL) 2451 int32_t right_mask = (right()->range() != NULL)
2460 ? right()->range()->Mask() 2452 ? right()->range()->Mask()
2461 : kDefaultMask; 2453 : kDefaultMask;
2462 int32_t result_mask = (op() == Token::BIT_AND) 2454 int32_t result_mask = (op() == Token::BIT_AND)
2463 ? left_mask & right_mask 2455 ? left_mask & right_mask
2464 : left_mask | right_mask; 2456 : left_mask | right_mask;
2465 return (result_mask >= 0) 2457 if (result_mask >= 0) return new(zone) Range(0, result_mask);
2466 ? new(zone) Range(0, result_mask) 2458
2467 : HValue::InferRange(zone); 2459 Range* result = HValue::InferRange(zone);
2460 result->set_can_be_minus_zero(false);
2461 return result;
2468 } 2462 }
2469 2463
2470 2464
2471 Range* HSar::InferRange(Zone* zone) { 2465 Range* HSar::InferRange(Zone* zone) {
2472 if (right()->IsConstant()) { 2466 if (right()->IsConstant()) {
2473 HConstant* c = HConstant::cast(right()); 2467 HConstant* c = HConstant::cast(right());
2474 if (c->HasInteger32Value()) { 2468 if (c->HasInteger32Value()) {
2475 Range* result = (left()->range() != NULL) 2469 Range* result = (left()->range() != NULL)
2476 ? left()->range()->Copy(zone) 2470 ? left()->range()->Copy(zone)
2477 : new(zone) Range(); 2471 : new(zone) Range();
2478 result->Sar(c->Integer32Value()); 2472 result->Sar(c->Integer32Value());
2479 result->set_can_be_minus_zero(false);
2480 return result; 2473 return result;
2481 } 2474 }
2482 } 2475 }
2483 return HValue::InferRange(zone); 2476 return HValue::InferRange(zone);
2484 } 2477 }
2485 2478
2486 2479
2487 Range* HShr::InferRange(Zone* zone) { 2480 Range* HShr::InferRange(Zone* zone) {
2488 if (right()->IsConstant()) { 2481 if (right()->IsConstant()) {
2489 HConstant* c = HConstant::cast(right()); 2482 HConstant* c = HConstant::cast(right());
2490 if (c->HasInteger32Value()) { 2483 if (c->HasInteger32Value()) {
2491 int shift_count = c->Integer32Value() & 0x1f; 2484 int shift_count = c->Integer32Value() & 0x1f;
2492 if (left()->range()->CanBeNegative()) { 2485 if (left()->range()->CanBeNegative()) {
2493 // Only compute bounds if the result always fits into an int32. 2486 // Only compute bounds if the result always fits into an int32.
2494 return (shift_count >= 1) 2487 return (shift_count >= 1)
2495 ? new(zone) Range(0, 2488 ? new(zone) Range(0,
2496 static_cast<uint32_t>(0xffffffff) >> shift_count) 2489 static_cast<uint32_t>(0xffffffff) >> shift_count)
2497 : new(zone) Range(); 2490 : new(zone) Range();
2498 } else { 2491 } else {
2499 // For positive inputs we can use the >> operator. 2492 // For positive inputs we can use the >> operator.
2500 Range* result = (left()->range() != NULL) 2493 Range* result = (left()->range() != NULL)
2501 ? left()->range()->Copy(zone) 2494 ? left()->range()->Copy(zone)
2502 : new(zone) Range(); 2495 : new(zone) Range();
2503 result->Sar(c->Integer32Value()); 2496 result->Sar(c->Integer32Value());
2504 result->set_can_be_minus_zero(false);
2505 return result; 2497 return result;
2506 } 2498 }
2507 } 2499 }
2508 } 2500 }
2509 return HValue::InferRange(zone); 2501 return HValue::InferRange(zone);
2510 } 2502 }
2511 2503
2512 2504
2513 Range* HShl::InferRange(Zone* zone) { 2505 Range* HShl::InferRange(Zone* zone) {
2514 if (right()->IsConstant()) { 2506 if (right()->IsConstant()) {
2515 HConstant* c = HConstant::cast(right()); 2507 HConstant* c = HConstant::cast(right());
2516 if (c->HasInteger32Value()) { 2508 if (c->HasInteger32Value()) {
2517 Range* result = (left()->range() != NULL) 2509 Range* result = (left()->range() != NULL)
2518 ? left()->range()->Copy(zone) 2510 ? left()->range()->Copy(zone)
2519 : new(zone) Range(); 2511 : new(zone) Range();
2520 result->Shl(c->Integer32Value()); 2512 result->Shl(c->Integer32Value());
2521 result->set_can_be_minus_zero(false);
2522 return result; 2513 return result;
2523 } 2514 }
2524 } 2515 }
2525 return HValue::InferRange(zone); 2516 return HValue::InferRange(zone);
2526 } 2517 }
2527 2518
2528 2519
2529 Range* HLoadKeyed::InferRange(Zone* zone) { 2520 Range* HLoadKeyed::InferRange(Zone* zone) {
2530 switch (elements_kind()) { 2521 switch (elements_kind()) {
2531 case EXTERNAL_PIXEL_ELEMENTS: 2522 case EXTERNAL_PIXEL_ELEMENTS:
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after
3916 case kBackingStore: 3907 case kBackingStore:
3917 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); 3908 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
3918 stream->Add("[backing-store]"); 3909 stream->Add("[backing-store]");
3919 break; 3910 break;
3920 } 3911 }
3921 3912
3922 stream->Add("@%d", offset()); 3913 stream->Add("@%d", offset());
3923 } 3914 }
3924 3915
3925 } } // namespace v8::internal 3916 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/compiler/minus-zero.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698