OLD | NEW |
---|---|
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 1718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1729 context()->PrintNameTo(stream); | 1729 context()->PrintNameTo(stream); |
1730 } | 1730 } |
1731 | 1731 |
1732 | 1732 |
1733 Range* HValue::InferRange(Zone* zone) { | 1733 Range* HValue::InferRange(Zone* zone) { |
1734 Range* result; | 1734 Range* result; |
1735 if (type().IsSmi()) { | 1735 if (type().IsSmi()) { |
1736 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); | 1736 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); |
1737 result->set_can_be_minus_zero(false); | 1737 result->set_can_be_minus_zero(false); |
1738 } else { | 1738 } else { |
1739 // Untagged integer32 cannot be -0, all other representations can. | |
1740 result = new(zone) Range(); | 1739 result = new(zone) Range(); |
1741 result->set_can_be_minus_zero(!representation().IsInteger32()); | 1740 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32)); |
1741 // TODO(jkummerow): The range cannot be minus zero when the upper type | |
1742 // bound is Integer32. | |
1742 } | 1743 } |
1743 return result; | 1744 return result; |
1744 } | 1745 } |
1745 | 1746 |
1746 | 1747 |
1747 Range* HChange::InferRange(Zone* zone) { | 1748 Range* HChange::InferRange(Zone* zone) { |
1748 Range* input_range = value()->range(); | 1749 Range* input_range = value()->range(); |
1749 if (from().IsInteger32() && | 1750 if (from().IsInteger32() && |
1750 to().IsSmiOrTagged() && | 1751 to().IsSmiOrTagged() && |
1751 !value()->CheckFlag(HInstruction::kUint32) && | 1752 !value()->CheckFlag(HInstruction::kUint32) && |
1752 input_range != NULL && input_range->IsInSmiRange()) { | 1753 input_range != NULL && input_range->IsInSmiRange()) { |
1753 set_type(HType::Smi()); | 1754 set_type(HType::Smi()); |
1754 ClearGVNFlag(kChangesNewSpacePromotion); | 1755 ClearGVNFlag(kChangesNewSpacePromotion); |
1755 } | 1756 } |
1756 Range* result = (input_range != NULL) | 1757 Range* result = (input_range != NULL) |
1757 ? input_range->Copy(zone) | 1758 ? input_range->Copy(zone) |
1758 : HValue::InferRange(zone); | 1759 : HValue::InferRange(zone); |
1759 if (to().IsInteger32()) result->set_can_be_minus_zero(false); | 1760 result->set_can_be_minus_zero(!to().IsSmiOrInteger32() || |
1761 !CheckFlag(kAllUsesTruncatingToInt32)); | |
1760 return result; | 1762 return result; |
1761 } | 1763 } |
1762 | 1764 |
1763 | 1765 |
1764 Range* HConstant::InferRange(Zone* zone) { | 1766 Range* HConstant::InferRange(Zone* zone) { |
1765 if (has_int32_value_) { | 1767 if (has_int32_value_) { |
1766 Range* result = new(zone) Range(int32_value_, int32_value_); | 1768 Range* result = new(zone) Range(int32_value_, int32_value_); |
1767 result->set_can_be_minus_zero(false); | 1769 result->set_can_be_minus_zero(false); |
1768 return result; | 1770 return result; |
1769 } | 1771 } |
(...skipping 24 matching lines...) Expand all Loading... | |
1794 | 1796 |
1795 Range* HAdd::InferRange(Zone* zone) { | 1797 Range* HAdd::InferRange(Zone* zone) { |
1796 if (representation().IsInteger32()) { | 1798 if (representation().IsInteger32()) { |
1797 Range* a = left()->range(); | 1799 Range* a = left()->range(); |
1798 Range* b = right()->range(); | 1800 Range* b = right()->range(); |
1799 Range* res = a->Copy(zone); | 1801 Range* res = a->Copy(zone); |
1800 if (!res->AddAndCheckOverflow(b) || | 1802 if (!res->AddAndCheckOverflow(b) || |
1801 CheckFlag(kAllUsesTruncatingToInt32)) { | 1803 CheckFlag(kAllUsesTruncatingToInt32)) { |
1802 ClearFlag(kCanOverflow); | 1804 ClearFlag(kCanOverflow); |
1803 } | 1805 } |
1804 if (!CheckFlag(kAllUsesTruncatingToInt32)) { | 1806 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
1805 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeMinusZero()); | 1807 a->CanBeMinusZero() && |
rossberg
2013/07/08 10:49:23
Nit: actual condition may fit on one line.
Jakob Kummerow
2013/07/08 11:12:04
Done.
| |
1806 } | 1808 b->CanBeMinusZero()); |
1807 return res; | 1809 return res; |
1808 } else { | 1810 } else { |
1809 return HValue::InferRange(zone); | 1811 return HValue::InferRange(zone); |
1810 } | 1812 } |
1811 } | 1813 } |
1812 | 1814 |
1813 | 1815 |
1814 Range* HSub::InferRange(Zone* zone) { | 1816 Range* HSub::InferRange(Zone* zone) { |
1815 if (representation().IsInteger32()) { | 1817 if (representation().IsInteger32()) { |
1816 Range* a = left()->range(); | 1818 Range* a = left()->range(); |
1817 Range* b = right()->range(); | 1819 Range* b = right()->range(); |
1818 Range* res = a->Copy(zone); | 1820 Range* res = a->Copy(zone); |
1819 if (!res->SubAndCheckOverflow(b) || | 1821 if (!res->SubAndCheckOverflow(b) || |
1820 CheckFlag(kAllUsesTruncatingToInt32)) { | 1822 CheckFlag(kAllUsesTruncatingToInt32)) { |
1821 ClearFlag(kCanOverflow); | 1823 ClearFlag(kCanOverflow); |
1822 } | 1824 } |
1823 if (!CheckFlag(kAllUsesTruncatingToInt32)) { | 1825 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
1824 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); | 1826 a->CanBeMinusZero() && |
rossberg
2013/07/08 10:49:23
Same here.
Jakob Kummerow
2013/07/08 11:12:04
Done.
| |
1825 } | 1827 b->CanBeZero()); |
1826 return res; | 1828 return res; |
1827 } else { | 1829 } else { |
1828 return HValue::InferRange(zone); | 1830 return HValue::InferRange(zone); |
1829 } | 1831 } |
1830 } | 1832 } |
1831 | 1833 |
1832 | 1834 |
1833 Range* HMul::InferRange(Zone* zone) { | 1835 Range* HMul::InferRange(Zone* zone) { |
1834 if (representation().IsInteger32()) { | 1836 if (representation().IsInteger32()) { |
1835 Range* a = left()->range(); | 1837 Range* a = left()->range(); |
1836 Range* b = right()->range(); | 1838 Range* b = right()->range(); |
1837 Range* res = a->Copy(zone); | 1839 Range* res = a->Copy(zone); |
1838 if (!res->MulAndCheckOverflow(b)) { | 1840 if (!res->MulAndCheckOverflow(b)) { |
1839 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 | 1841 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 |
1840 // would be wrong, because truncated integer multiplication is too | 1842 // would be wrong, because truncated integer multiplication is too |
1841 // precise and therefore not the same as converting to Double and back. | 1843 // precise and therefore not the same as converting to Double and back. |
1842 ClearFlag(kCanOverflow); | 1844 ClearFlag(kCanOverflow); |
1843 } | 1845 } |
1844 if (!CheckFlag(kAllUsesTruncatingToInt32)) { | 1846 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
1845 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || | 1847 ((a->CanBeZero() && b->CanBeNegative()) || |
1846 (a->CanBeNegative() && b->CanBeZero()); | 1848 (a->CanBeNegative() && b->CanBeZero()))); |
1847 res->set_can_be_minus_zero(m0); | |
1848 } | |
1849 return res; | 1849 return res; |
1850 } else { | 1850 } else { |
1851 return HValue::InferRange(zone); | 1851 return HValue::InferRange(zone); |
1852 } | 1852 } |
1853 } | 1853 } |
1854 | 1854 |
1855 | 1855 |
1856 Range* HDiv::InferRange(Zone* zone) { | 1856 Range* HDiv::InferRange(Zone* zone) { |
1857 if (representation().IsInteger32()) { | 1857 if (representation().IsInteger32()) { |
1858 Range* a = left()->range(); | 1858 Range* a = left()->range(); |
1859 Range* b = right()->range(); | 1859 Range* b = right()->range(); |
1860 Range* result = new(zone) Range(); | 1860 Range* result = new(zone) Range(); |
1861 if (!CheckFlag(kAllUsesTruncatingToInt32)) { | 1861 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
1862 if (a->CanBeMinusZero()) { | 1862 (a->CanBeMinusZero() || |
1863 result->set_can_be_minus_zero(true); | 1863 (a->CanBeZero() && b->CanBeNegative()))); |
1864 } | |
1865 | |
1866 if (a->CanBeZero() && b->CanBeNegative()) { | |
1867 result->set_can_be_minus_zero(true); | |
1868 } | |
1869 } | |
1870 | |
1871 if (!a->Includes(kMinInt) || !b->Includes(-1)) { | 1864 if (!a->Includes(kMinInt) || !b->Includes(-1)) { |
1872 ClearFlag(HValue::kCanOverflow); | 1865 ClearFlag(HValue::kCanOverflow); |
1873 } | 1866 } |
1874 | 1867 |
1875 if (!b->CanBeZero()) { | 1868 if (!b->CanBeZero()) { |
1876 ClearFlag(HValue::kCanBeDivByZero); | 1869 ClearFlag(HValue::kCanBeDivByZero); |
1877 } | 1870 } |
1878 return result; | 1871 return result; |
1879 } else { | 1872 } else { |
1880 return HValue::InferRange(zone); | 1873 return HValue::InferRange(zone); |
1881 } | 1874 } |
1882 } | 1875 } |
1883 | 1876 |
1884 | 1877 |
1885 Range* HMod::InferRange(Zone* zone) { | 1878 Range* HMod::InferRange(Zone* zone) { |
1886 if (representation().IsInteger32()) { | 1879 if (representation().IsInteger32()) { |
1887 Range* a = left()->range(); | 1880 Range* a = left()->range(); |
1888 Range* b = right()->range(); | 1881 Range* b = right()->range(); |
1889 | 1882 |
1890 // The magnitude of the modulus is bounded by the right operand. Note that | 1883 // The magnitude of the modulus is bounded by the right operand. Note that |
1891 // apart for the cases involving kMinInt, the calculation below is the same | 1884 // apart for the cases involving kMinInt, the calculation below is the same |
1892 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. | 1885 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. |
1893 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); | 1886 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); |
1894 | 1887 |
1895 // The result of the modulo operation has the sign of its left operand. | 1888 // The result of the modulo operation has the sign of its left operand. |
1896 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); | 1889 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); |
1897 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, | 1890 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, |
1898 a->CanBePositive() ? positive_bound : 0); | 1891 a->CanBePositive() ? positive_bound : 0); |
1899 | 1892 |
1900 if (left_can_be_negative && !CheckFlag(kAllUsesTruncatingToInt32)) { | 1893 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
1901 result->set_can_be_minus_zero(true); | 1894 left_can_be_negative); |
1902 } | |
1903 | 1895 |
1904 if (!a->Includes(kMinInt) || !b->Includes(-1)) { | 1896 if (!a->Includes(kMinInt) || !b->Includes(-1)) { |
1905 ClearFlag(HValue::kCanOverflow); | 1897 ClearFlag(HValue::kCanOverflow); |
1906 } | 1898 } |
1907 | 1899 |
1908 if (!b->CanBeZero()) { | 1900 if (!b->CanBeZero()) { |
1909 ClearFlag(HValue::kCanBeDivByZero); | 1901 ClearFlag(HValue::kCanBeDivByZero); |
1910 } | 1902 } |
1911 return result; | 1903 return result; |
1912 } else { | 1904 } else { |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2425 static_cast<uint32_t>( | 2417 static_cast<uint32_t>( |
2426 left_upper | left_lower | right_upper | right_lower)); | 2418 left_upper | left_lower | right_upper | right_lower)); |
2427 | 2419 |
2428 int64_t limit = 1; | 2420 int64_t limit = 1; |
2429 limit <<= high; | 2421 limit <<= high; |
2430 int32_t min = (left()->range()->CanBeNegative() || | 2422 int32_t min = (left()->range()->CanBeNegative() || |
2431 right()->range()->CanBeNegative()) | 2423 right()->range()->CanBeNegative()) |
2432 ? static_cast<int32_t>(-limit) : 0; | 2424 ? static_cast<int32_t>(-limit) : 0; |
2433 return new(zone) Range(min, static_cast<int32_t>(limit - 1)); | 2425 return new(zone) Range(min, static_cast<int32_t>(limit - 1)); |
2434 } | 2426 } |
2435 return HValue::InferRange(zone); | 2427 Range* result = HValue::InferRange(zone); |
2428 result->set_can_be_minus_zero(false); | |
2429 return result; | |
2436 } | 2430 } |
2437 const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff); | 2431 const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff); |
2438 int32_t left_mask = (left()->range() != NULL) | 2432 int32_t left_mask = (left()->range() != NULL) |
2439 ? left()->range()->Mask() | 2433 ? left()->range()->Mask() |
2440 : kDefaultMask; | 2434 : kDefaultMask; |
2441 int32_t right_mask = (right()->range() != NULL) | 2435 int32_t right_mask = (right()->range() != NULL) |
2442 ? right()->range()->Mask() | 2436 ? right()->range()->Mask() |
2443 : kDefaultMask; | 2437 : kDefaultMask; |
2444 int32_t result_mask = (op() == Token::BIT_AND) | 2438 int32_t result_mask = (op() == Token::BIT_AND) |
2445 ? left_mask & right_mask | 2439 ? left_mask & right_mask |
2446 : left_mask | right_mask; | 2440 : left_mask | right_mask; |
2447 return (result_mask >= 0) | 2441 if (result_mask >= 0) return new(zone) Range(0, result_mask); |
2448 ? new(zone) Range(0, result_mask) | 2442 |
2449 : HValue::InferRange(zone); | 2443 Range* result = HValue::InferRange(zone); |
2444 result->set_can_be_minus_zero(false); | |
2445 return result; | |
2450 } | 2446 } |
2451 | 2447 |
2452 | 2448 |
2453 Range* HSar::InferRange(Zone* zone) { | 2449 Range* HSar::InferRange(Zone* zone) { |
2454 if (right()->IsConstant()) { | 2450 if (right()->IsConstant()) { |
2455 HConstant* c = HConstant::cast(right()); | 2451 HConstant* c = HConstant::cast(right()); |
2456 if (c->HasInteger32Value()) { | 2452 if (c->HasInteger32Value()) { |
2457 Range* result = (left()->range() != NULL) | 2453 Range* result = (left()->range() != NULL) |
2458 ? left()->range()->Copy(zone) | 2454 ? left()->range()->Copy(zone) |
2459 : new(zone) Range(); | 2455 : new(zone) Range(); |
2460 result->Sar(c->Integer32Value()); | 2456 result->Sar(c->Integer32Value()); |
2461 result->set_can_be_minus_zero(false); | |
2462 return result; | 2457 return result; |
2463 } | 2458 } |
2464 } | 2459 } |
2465 return HValue::InferRange(zone); | 2460 return HValue::InferRange(zone); |
2466 } | 2461 } |
2467 | 2462 |
2468 | 2463 |
2469 Range* HShr::InferRange(Zone* zone) { | 2464 Range* HShr::InferRange(Zone* zone) { |
2470 if (right()->IsConstant()) { | 2465 if (right()->IsConstant()) { |
2471 HConstant* c = HConstant::cast(right()); | 2466 HConstant* c = HConstant::cast(right()); |
2472 if (c->HasInteger32Value()) { | 2467 if (c->HasInteger32Value()) { |
2473 int shift_count = c->Integer32Value() & 0x1f; | 2468 int shift_count = c->Integer32Value() & 0x1f; |
2474 if (left()->range()->CanBeNegative()) { | 2469 if (left()->range()->CanBeNegative()) { |
2475 // Only compute bounds if the result always fits into an int32. | 2470 // Only compute bounds if the result always fits into an int32. |
2476 return (shift_count >= 1) | 2471 return (shift_count >= 1) |
2477 ? new(zone) Range(0, | 2472 ? new(zone) Range(0, |
2478 static_cast<uint32_t>(0xffffffff) >> shift_count) | 2473 static_cast<uint32_t>(0xffffffff) >> shift_count) |
2479 : new(zone) Range(); | 2474 : new(zone) Range(); |
2480 } else { | 2475 } else { |
2481 // For positive inputs we can use the >> operator. | 2476 // For positive inputs we can use the >> operator. |
2482 Range* result = (left()->range() != NULL) | 2477 Range* result = (left()->range() != NULL) |
2483 ? left()->range()->Copy(zone) | 2478 ? left()->range()->Copy(zone) |
2484 : new(zone) Range(); | 2479 : new(zone) Range(); |
2485 result->Sar(c->Integer32Value()); | 2480 result->Sar(c->Integer32Value()); |
2486 result->set_can_be_minus_zero(false); | |
2487 return result; | 2481 return result; |
2488 } | 2482 } |
2489 } | 2483 } |
2490 } | 2484 } |
2491 return HValue::InferRange(zone); | 2485 return HValue::InferRange(zone); |
2492 } | 2486 } |
2493 | 2487 |
2494 | 2488 |
2495 Range* HShl::InferRange(Zone* zone) { | 2489 Range* HShl::InferRange(Zone* zone) { |
2496 if (right()->IsConstant()) { | 2490 if (right()->IsConstant()) { |
2497 HConstant* c = HConstant::cast(right()); | 2491 HConstant* c = HConstant::cast(right()); |
2498 if (c->HasInteger32Value()) { | 2492 if (c->HasInteger32Value()) { |
2499 Range* result = (left()->range() != NULL) | 2493 Range* result = (left()->range() != NULL) |
2500 ? left()->range()->Copy(zone) | 2494 ? left()->range()->Copy(zone) |
2501 : new(zone) Range(); | 2495 : new(zone) Range(); |
2502 result->Shl(c->Integer32Value()); | 2496 result->Shl(c->Integer32Value()); |
2503 result->set_can_be_minus_zero(false); | |
2504 return result; | 2497 return result; |
2505 } | 2498 } |
2506 } | 2499 } |
2507 return HValue::InferRange(zone); | 2500 return HValue::InferRange(zone); |
2508 } | 2501 } |
2509 | 2502 |
2510 | 2503 |
2511 Range* HLoadKeyed::InferRange(Zone* zone) { | 2504 Range* HLoadKeyed::InferRange(Zone* zone) { |
2512 switch (elements_kind()) { | 2505 switch (elements_kind()) { |
2513 case EXTERNAL_PIXEL_ELEMENTS: | 2506 case EXTERNAL_PIXEL_ELEMENTS: |
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3886 case kBackingStore: | 3879 case kBackingStore: |
3887 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); | 3880 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); |
3888 stream->Add("[backing-store]"); | 3881 stream->Add("[backing-store]"); |
3889 break; | 3882 break; |
3890 } | 3883 } |
3891 | 3884 |
3892 stream->Add("@%d", offset()); | 3885 stream->Add("@%d", offset()); |
3893 } | 3886 } |
3894 | 3887 |
3895 } } // namespace v8::internal | 3888 } } // namespace v8::internal |
OLD | NEW |