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

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

Issue 16741002: Skip some conditional deopts for Div/Mul when all uses are truncating (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: added regression test 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 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 521
522 bool HValue::CheckUsesForFlag(Flag f) { 522 bool HValue::CheckUsesForFlag(Flag f) {
523 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 523 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
524 if (it.value()->IsSimulate()) continue; 524 if (it.value()->IsSimulate()) continue;
525 if (!it.value()->CheckFlag(f)) return false; 525 if (!it.value()->CheckFlag(f)) return false;
526 } 526 }
527 return true; 527 return true;
528 } 528 }
529 529
530 530
531 bool HValue::HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) {
532 bool return_value = false;
533 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
534 if (it.value()->IsSimulate()) continue;
535 if (!it.value()->CheckFlag(f)) return false;
536 return_value = true;
537 }
538 return return_value;
539 }
540
541
531 HUseIterator::HUseIterator(HUseListNode* head) : next_(head) { 542 HUseIterator::HUseIterator(HUseListNode* head) : next_(head) {
532 Advance(); 543 Advance();
533 } 544 }
534 545
535 546
536 void HUseIterator::Advance() { 547 void HUseIterator::Advance() {
537 current_ = next_; 548 current_ = next_;
538 if (current_ != NULL) { 549 if (current_ != NULL) {
539 next_ = current_->tail(); 550 next_ = current_->tail();
540 value_ = current_->value(); 551 value_ = current_->value();
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 HValue* result = HBitNot::cast(value())->value(); 1433 HValue* result = HBitNot::cast(value())->value();
1423 ASSERT(result->representation().IsInteger32()); 1434 ASSERT(result->representation().IsInteger32());
1424 if (!result->CheckFlag(kUint32)) { 1435 if (!result->CheckFlag(kUint32)) {
1425 return result; 1436 return result;
1426 } 1437 }
1427 } 1438 }
1428 return this; 1439 return this;
1429 } 1440 }
1430 1441
1431 1442
1432 HValue* HArithmeticBinaryOperation::Canonicalize() {
1433 if (representation().IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) {
1434 ClearFlag(kCanOverflow);
1435 }
1436 return this;
1437 }
1438
1439
1440 static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) { 1443 static bool IsIdentityOperation(HValue* arg1, HValue* arg2, int32_t identity) {
1441 return arg1->representation().IsSpecialization() && 1444 return arg1->representation().IsSpecialization() &&
1442 arg2->EqualsInteger32Constant(identity); 1445 arg2->EqualsInteger32Constant(identity);
1443 } 1446 }
1444 1447
1445 1448
1446 HValue* HAdd::Canonicalize() { 1449 HValue* HAdd::Canonicalize() {
1447 if (IsIdentityOperation(left(), right(), 0)) return left(); 1450 if (IsIdentityOperation(left(), right(), 0)) return left();
1448 if (IsIdentityOperation(right(), left(), 0)) return right(); 1451 if (IsIdentityOperation(right(), left(), 0)) return right();
1449 return HArithmeticBinaryOperation::Canonicalize(); 1452 return this;
1450 } 1453 }
1451 1454
1452 1455
1453 HValue* HSub::Canonicalize() { 1456 HValue* HSub::Canonicalize() {
1454 if (IsIdentityOperation(left(), right(), 0)) return left(); 1457 if (IsIdentityOperation(left(), right(), 0)) return left();
1455 return HArithmeticBinaryOperation::Canonicalize(); 1458 return this;
1456 } 1459 }
1457 1460
1458 1461
1459 HValue* HMul::Canonicalize() { 1462 HValue* HMul::Canonicalize() {
1460 if (IsIdentityOperation(left(), right(), 1)) return left(); 1463 if (IsIdentityOperation(left(), right(), 1)) return left();
1461 if (IsIdentityOperation(right(), left(), 1)) return right(); 1464 if (IsIdentityOperation(right(), left(), 1)) return right();
1462 return this; 1465 return this;
1463 } 1466 }
1464 1467
1465 1468
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 return HValue::InferRange(zone); 1754 return HValue::InferRange(zone);
1752 } 1755 }
1753 } 1756 }
1754 1757
1755 1758
1756 Range* HAdd::InferRange(Zone* zone) { 1759 Range* HAdd::InferRange(Zone* zone) {
1757 if (representation().IsInteger32()) { 1760 if (representation().IsInteger32()) {
1758 Range* a = left()->range(); 1761 Range* a = left()->range();
1759 Range* b = right()->range(); 1762 Range* b = right()->range();
1760 Range* res = a->Copy(zone); 1763 Range* res = a->Copy(zone);
1761 if (!res->AddAndCheckOverflow(b)) { 1764 if (!res->AddAndCheckOverflow(b) ||
1765 CheckFlag(kAllUsesTruncatingToInt32)) {
1762 ClearFlag(kCanOverflow); 1766 ClearFlag(kCanOverflow);
1763 } 1767 }
1764 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); 1768 if (!CheckFlag(kAllUsesTruncatingToInt32)) {
1765 res->set_can_be_minus_zero(m0); 1769 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeMinusZero());
1770 }
1766 return res; 1771 return res;
1767 } else { 1772 } else {
1768 return HValue::InferRange(zone); 1773 return HValue::InferRange(zone);
1769 } 1774 }
1770 } 1775 }
1771 1776
1772 1777
1773 Range* HSub::InferRange(Zone* zone) { 1778 Range* HSub::InferRange(Zone* zone) {
1774 if (representation().IsInteger32()) { 1779 if (representation().IsInteger32()) {
1775 Range* a = left()->range(); 1780 Range* a = left()->range();
1776 Range* b = right()->range(); 1781 Range* b = right()->range();
1777 Range* res = a->Copy(zone); 1782 Range* res = a->Copy(zone);
1778 if (!res->SubAndCheckOverflow(b)) { 1783 if (!res->SubAndCheckOverflow(b) ||
1784 CheckFlag(kAllUsesTruncatingToInt32)) {
1779 ClearFlag(kCanOverflow); 1785 ClearFlag(kCanOverflow);
1780 } 1786 }
1781 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); 1787 if (!CheckFlag(kAllUsesTruncatingToInt32)) {
1788 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero());
1789 }
1782 return res; 1790 return res;
1783 } else { 1791 } else {
1784 return HValue::InferRange(zone); 1792 return HValue::InferRange(zone);
1785 } 1793 }
1786 } 1794 }
1787 1795
1788 1796
1789 Range* HMul::InferRange(Zone* zone) { 1797 Range* HMul::InferRange(Zone* zone) {
1790 if (representation().IsInteger32()) { 1798 if (representation().IsInteger32()) {
1791 Range* a = left()->range(); 1799 Range* a = left()->range();
1792 Range* b = right()->range(); 1800 Range* b = right()->range();
1793 Range* res = a->Copy(zone); 1801 Range* res = a->Copy(zone);
1794 if (!res->MulAndCheckOverflow(b)) { 1802 if (!res->MulAndCheckOverflow(b)) {
1803 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32
1804 // would be wrong, because truncated integer multiplication is too
1805 // precise and therefore not the same as converting to Double and back.
1795 ClearFlag(kCanOverflow); 1806 ClearFlag(kCanOverflow);
1796 } 1807 }
1797 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || 1808 if (!CheckFlag(kAllUsesTruncatingToInt32)) {
1798 (a->CanBeNegative() && b->CanBeZero()); 1809 bool m0 = (a->CanBeZero() && b->CanBeNegative()) ||
1799 res->set_can_be_minus_zero(m0); 1810 (a->CanBeNegative() && b->CanBeZero());
1811 res->set_can_be_minus_zero(m0);
1812 }
1800 return res; 1813 return res;
1801 } else { 1814 } else {
1802 return HValue::InferRange(zone); 1815 return HValue::InferRange(zone);
1803 } 1816 }
1804 } 1817 }
1805 1818
1806 1819
1807 Range* HDiv::InferRange(Zone* zone) { 1820 Range* HDiv::InferRange(Zone* zone) {
1808 if (representation().IsInteger32()) { 1821 if (representation().IsInteger32()) {
1809 Range* a = left()->range(); 1822 Range* a = left()->range();
1810 Range* b = right()->range(); 1823 Range* b = right()->range();
1811 Range* result = new(zone) Range(); 1824 Range* result = new(zone) Range();
1812 if (a->CanBeMinusZero()) { 1825 if (!CheckFlag(kAllUsesTruncatingToInt32)) {
1813 result->set_can_be_minus_zero(true); 1826 if (a->CanBeMinusZero()) {
1814 } 1827 result->set_can_be_minus_zero(true);
1828 }
1815 1829
1816 if (a->CanBeZero() && b->CanBeNegative()) { 1830 if (a->CanBeZero() && b->CanBeNegative()) {
1817 result->set_can_be_minus_zero(true); 1831 result->set_can_be_minus_zero(true);
1832 }
1818 } 1833 }
1819 1834
1820 if (!a->Includes(kMinInt) || !b->Includes(-1)) { 1835 if (!a->Includes(kMinInt) || !b->Includes(-1)) {
1821 ClearFlag(HValue::kCanOverflow); 1836 ClearFlag(HValue::kCanOverflow);
1822 } 1837 }
1823 1838
1824 if (!b->CanBeZero()) { 1839 if (!b->CanBeZero()) {
1825 ClearFlag(HValue::kCanBeDivByZero); 1840 ClearFlag(HValue::kCanBeDivByZero);
1826 } 1841 }
1827 return result; 1842 return result;
(...skipping 11 matching lines...) Expand all
1839 // The magnitude of the modulus is bounded by the right operand. Note that 1854 // The magnitude of the modulus is bounded by the right operand. Note that
1840 // apart for the cases involving kMinInt, the calculation below is the same 1855 // apart for the cases involving kMinInt, the calculation below is the same
1841 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. 1856 // as Max(Abs(b->lower()), Abs(b->upper())) - 1.
1842 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); 1857 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1);
1843 1858
1844 // The result of the modulo operation has the sign of its left operand. 1859 // The result of the modulo operation has the sign of its left operand.
1845 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); 1860 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative();
1846 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, 1861 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0,
1847 a->CanBePositive() ? positive_bound : 0); 1862 a->CanBePositive() ? positive_bound : 0);
1848 1863
1849 if (left_can_be_negative) { 1864 if (left_can_be_negative && !CheckFlag(kAllUsesTruncatingToInt32)) {
1850 result->set_can_be_minus_zero(true); 1865 result->set_can_be_minus_zero(true);
1851 } 1866 }
1852 1867
1853 if (!a->Includes(kMinInt) || !b->Includes(-1)) { 1868 if (!a->Includes(kMinInt) || !b->Includes(-1)) {
1854 ClearFlag(HValue::kCanOverflow); 1869 ClearFlag(HValue::kCanOverflow);
1855 } 1870 }
1856 1871
1857 if (!b->CanBeZero()) { 1872 if (!b->CanBeZero()) {
1858 ClearFlag(HValue::kCanBeDivByZero); 1873 ClearFlag(HValue::kCanBeDivByZero);
1859 } 1874 }
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
2291 UpdateRepresentation(new_rep, h_infer, "uses"); 2306 UpdateRepresentation(new_rep, h_infer, "uses");
2292 } 2307 }
2293 2308
2294 2309
2295 bool HBinaryOperation::IgnoreObservedOutputRepresentation( 2310 bool HBinaryOperation::IgnoreObservedOutputRepresentation(
2296 Representation current_rep) { 2311 Representation current_rep) {
2297 return observed_output_representation_.IsDouble() && 2312 return observed_output_representation_.IsDouble() &&
2298 current_rep.IsInteger32() && 2313 current_rep.IsInteger32() &&
2299 // Mul in Integer32 mode would be too precise. 2314 // Mul in Integer32 mode would be too precise.
2300 !this->IsMul() && 2315 !this->IsMul() &&
2301 // TODO(jkummerow): Remove blacklisting of Div when the Div
2302 // instruction has learned not to deopt when the remainder is
2303 // non-zero but all uses are truncating.
2304 !this->IsDiv() &&
2305 CheckUsesForFlag(kTruncatingToInt32); 2316 CheckUsesForFlag(kTruncatingToInt32);
2306 } 2317 }
2307 2318
2308 2319
2309 Representation HBinaryOperation::RepresentationFromInputs() { 2320 Representation HBinaryOperation::RepresentationFromInputs() {
2310 // Determine the worst case of observed input representations and 2321 // Determine the worst case of observed input representations and
2311 // the currently assumed output representation. 2322 // the currently assumed output representation.
2312 Representation rep = representation(); 2323 Representation rep = representation();
2313 for (int i = 1; i <= 2; ++i) { 2324 for (int i = 1; i <= 2; ++i) {
2314 Representation input_rep = observed_input_representation(i); 2325 Representation input_rep = observed_input_representation(i);
(...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after
3844 case kBackingStore: 3855 case kBackingStore:
3845 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); 3856 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
3846 stream->Add("[backing-store]"); 3857 stream->Add("[backing-store]");
3847 break; 3858 break;
3848 } 3859 }
3849 3860
3850 stream->Add("@%d", offset()); 3861 stream->Add("@%d", offset());
3851 } 3862 }
3852 3863
3853 } } // namespace v8::internal 3864 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698