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 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |