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

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, 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 | « src/hydrogen-instructions.h ('k') | src/hydrogen-minus-zero.cc » ('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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 } 78 }
79 79
80 80
81 void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) { 81 void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) {
82 ASSERT(CheckFlag(kFlexibleRepresentation)); 82 ASSERT(CheckFlag(kFlexibleRepresentation));
83 Representation new_rep = RepresentationFromInputs(); 83 Representation new_rep = RepresentationFromInputs();
84 UpdateRepresentation(new_rep, h_infer, "inputs"); 84 UpdateRepresentation(new_rep, h_infer, "inputs");
85 new_rep = RepresentationFromUses(); 85 new_rep = RepresentationFromUses();
86 UpdateRepresentation(new_rep, h_infer, "uses"); 86 UpdateRepresentation(new_rep, h_infer, "uses");
87 new_rep = RepresentationFromUseRequirements(); 87 new_rep = RepresentationFromUseRequirements();
88 if (new_rep.fits_into(Representation::Integer32())) { 88 if (new_rep.IsDouble()) new_rep = Representation::Integer32();
89 if (new_rep.IsInteger32()) {
89 UpdateRepresentation(new_rep, h_infer, "use requirements"); 90 UpdateRepresentation(new_rep, h_infer, "use requirements");
90 } 91 }
91 } 92 }
92 93
93 94
94 Representation HValue::RepresentationFromUses() { 95 Representation HValue::RepresentationFromUses() {
95 if (HasNoUses()) return Representation::None(); 96 if (HasNoUses()) return Representation::None();
96 97
97 // Array of use counts for each representation. 98 // Array of use counts for each representation.
98 int use_count[Representation::kNumRepresentations] = { 0 }; 99 int use_count[Representation::kNumRepresentations] = { 0 };
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 } 253 }
253 254
254 255
255 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { 256 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) {
256 return guarantee->IsBoundsCheckBaseIndexInformation() 257 return guarantee->IsBoundsCheckBaseIndexInformation()
257 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check() 258 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check()
258 : guarantee; 259 : guarantee;
259 } 260 }
260 261
261 262
262 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { 263 static int32_t ConvertAndSetOverflow(Representation r,
263 if (result > kMaxInt) { 264 int64_t result,
264 *overflow = true; 265 bool* overflow) {
265 return kMaxInt; 266 if (r.IsSmi()) {
266 } 267 if (result > Smi::kMaxValue) {
267 if (result < kMinInt) { 268 *overflow = true;
268 *overflow = true; 269 return Smi::kMaxValue;
269 return kMinInt; 270 }
271 if (result < Smi::kMinValue) {
272 *overflow = true;
273 return Smi::kMinValue;
274 }
275 } else {
276 if (result > kMaxInt) {
277 *overflow = true;
278 return kMaxInt;
279 }
280 if (result < kMinInt) {
281 *overflow = true;
282 return kMinInt;
283 }
270 } 284 }
271 return static_cast<int32_t>(result); 285 return static_cast<int32_t>(result);
272 } 286 }
273 287
274 288
275 static int32_t AddWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 289 static int32_t AddWithoutOverflow(Representation r,
290 int32_t a,
291 int32_t b,
292 bool* overflow) {
276 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b); 293 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b);
277 return ConvertAndSetOverflow(result, overflow); 294 return ConvertAndSetOverflow(r, result, overflow);
278 } 295 }
279 296
280 297
281 static int32_t SubWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 298 static int32_t SubWithoutOverflow(Representation r,
299 int32_t a,
300 int32_t b,
301 bool* overflow) {
282 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b); 302 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b);
283 return ConvertAndSetOverflow(result, overflow); 303 return ConvertAndSetOverflow(r, result, overflow);
284 } 304 }
285 305
286 306
287 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 307 static int32_t MulWithoutOverflow(const Representation& r,
308 int32_t a,
309 int32_t b,
310 bool* overflow) {
288 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); 311 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b);
289 return ConvertAndSetOverflow(result, overflow); 312 return ConvertAndSetOverflow(r, result, overflow);
290 } 313 }
291 314
292 315
293 int32_t Range::Mask() const { 316 int32_t Range::Mask() const {
294 if (lower_ == upper_) return lower_; 317 if (lower_ == upper_) return lower_;
295 if (lower_ >= 0) { 318 if (lower_ >= 0) {
296 int32_t res = 1; 319 int32_t res = 1;
297 while (res < upper_) { 320 while (res < upper_) {
298 res = (res << 1) | 1; 321 res = (res << 1) | 1;
299 } 322 }
300 return res; 323 return res;
301 } 324 }
302 return 0xffffffff; 325 return 0xffffffff;
303 } 326 }
304 327
305 328
306 void Range::AddConstant(int32_t value) { 329 void Range::AddConstant(int32_t value) {
307 if (value == 0) return; 330 if (value == 0) return;
308 bool may_overflow = false; // Overflow is ignored here. 331 bool may_overflow = false; // Overflow is ignored here.
309 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); 332 Representation r = Representation::Integer32();
310 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); 333 lower_ = AddWithoutOverflow(r, lower_, value, &may_overflow);
334 upper_ = AddWithoutOverflow(r, upper_, value, &may_overflow);
311 #ifdef DEBUG 335 #ifdef DEBUG
312 Verify(); 336 Verify();
313 #endif 337 #endif
314 } 338 }
315 339
316 340
317 void Range::Intersect(Range* other) { 341 void Range::Intersect(Range* other) {
318 upper_ = Min(upper_, other->upper_); 342 upper_ = Min(upper_, other->upper_);
319 lower_ = Max(lower_, other->lower_); 343 lower_ = Max(lower_, other->lower_);
320 bool b = CanBeMinusZero() && other->CanBeMinusZero(); 344 bool b = CanBeMinusZero() && other->CanBeMinusZero();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 lower_ = lower_ << bits; 383 lower_ = lower_ << bits;
360 upper_ = upper_ << bits; 384 upper_ = upper_ << bits;
361 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) { 385 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
362 upper_ = kMaxInt; 386 upper_ = kMaxInt;
363 lower_ = kMinInt; 387 lower_ = kMinInt;
364 } 388 }
365 set_can_be_minus_zero(false); 389 set_can_be_minus_zero(false);
366 } 390 }
367 391
368 392
369 bool Range::AddAndCheckOverflow(Range* other) { 393 bool Range::AddAndCheckOverflow(const Representation& r, Range* other) {
370 bool may_overflow = false; 394 bool may_overflow = false;
371 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); 395 lower_ = AddWithoutOverflow(r, lower_, other->lower(), &may_overflow);
372 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); 396 upper_ = AddWithoutOverflow(r, upper_, other->upper(), &may_overflow);
373 KeepOrder(); 397 KeepOrder();
374 #ifdef DEBUG 398 #ifdef DEBUG
375 Verify(); 399 Verify();
376 #endif 400 #endif
377 return may_overflow; 401 return may_overflow;
378 } 402 }
379 403
380 404
381 bool Range::SubAndCheckOverflow(Range* other) { 405 bool Range::SubAndCheckOverflow(const Representation& r, Range* other) {
382 bool may_overflow = false; 406 bool may_overflow = false;
383 lower_ = SubWithoutOverflow(lower_, other->upper(), &may_overflow); 407 lower_ = SubWithoutOverflow(r, lower_, other->upper(), &may_overflow);
384 upper_ = SubWithoutOverflow(upper_, other->lower(), &may_overflow); 408 upper_ = SubWithoutOverflow(r, upper_, other->lower(), &may_overflow);
385 KeepOrder(); 409 KeepOrder();
386 #ifdef DEBUG 410 #ifdef DEBUG
387 Verify(); 411 Verify();
388 #endif 412 #endif
389 return may_overflow; 413 return may_overflow;
390 } 414 }
391 415
392 416
393 void Range::KeepOrder() { 417 void Range::KeepOrder() {
394 if (lower_ > upper_) { 418 if (lower_ > upper_) {
395 int32_t tmp = lower_; 419 int32_t tmp = lower_;
396 lower_ = upper_; 420 lower_ = upper_;
397 upper_ = tmp; 421 upper_ = tmp;
398 } 422 }
399 } 423 }
400 424
401 425
402 #ifdef DEBUG 426 #ifdef DEBUG
403 void Range::Verify() const { 427 void Range::Verify() const {
404 ASSERT(lower_ <= upper_); 428 ASSERT(lower_ <= upper_);
405 } 429 }
406 #endif 430 #endif
407 431
408 432
409 bool Range::MulAndCheckOverflow(Range* other) { 433 bool Range::MulAndCheckOverflow(const Representation& r, Range* other) {
410 bool may_overflow = false; 434 bool may_overflow = false;
411 int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow); 435 int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow);
412 int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow); 436 int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow);
413 int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow); 437 int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow);
414 int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow); 438 int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow);
415 lower_ = Min(Min(v1, v2), Min(v3, v4)); 439 lower_ = Min(Min(v1, v2), Min(v3, v4));
416 upper_ = Max(Max(v1, v2), Max(v3, v4)); 440 upper_ = Max(Max(v1, v2), Max(v3, v4));
417 #ifdef DEBUG 441 #ifdef DEBUG
418 Verify(); 442 Verify();
419 #endif 443 #endif
420 return may_overflow; 444 return may_overflow;
421 } 445 }
422 446
423 447
424 const char* HType::ToString() { 448 const char* HType::ToString() {
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 1446
1423 1447
1424 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { 1448 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) {
1425 object()->PrintNameTo(stream); 1449 object()->PrintNameTo(stream);
1426 stream->Add(" "); 1450 stream->Add(" ");
1427 index()->PrintNameTo(stream); 1451 index()->PrintNameTo(stream);
1428 } 1452 }
1429 1453
1430 1454
1431 HValue* HBitwise::Canonicalize() { 1455 HValue* HBitwise::Canonicalize() {
1432 if (!representation().IsInteger32()) return this; 1456 if (!representation().IsSmiOrInteger32()) return this;
1433 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. 1457 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x.
1434 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; 1458 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
1435 if (left()->EqualsInteger32Constant(nop_constant) && 1459 if (left()->EqualsInteger32Constant(nop_constant) &&
1436 !right()->CheckFlag(kUint32)) { 1460 !right()->CheckFlag(kUint32)) {
1437 return right(); 1461 return right();
1438 } 1462 }
1439 if (right()->EqualsInteger32Constant(nop_constant) && 1463 if (right()->EqualsInteger32Constant(nop_constant) &&
1440 !left()->CheckFlag(kUint32)) { 1464 !left()->CheckFlag(kUint32)) {
1441 return left(); 1465 return left();
1442 } 1466 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 } 1566 }
1543 1567
1544 1568
1545 HValue* HUnaryMathOperation::Canonicalize() { 1569 HValue* HUnaryMathOperation::Canonicalize() {
1546 if (op() == kMathFloor) { 1570 if (op() == kMathFloor) {
1547 HValue* val = value(); 1571 HValue* val = value();
1548 if (val->IsChange()) val = HChange::cast(val)->value(); 1572 if (val->IsChange()) val = HChange::cast(val)->value();
1549 1573
1550 // If the input is integer32 then we replace the floor instruction 1574 // If the input is integer32 then we replace the floor instruction
1551 // with its input. 1575 // with its input.
1552 if (val->representation().IsInteger32()) return val; 1576 if (val->representation().IsSmiOrInteger32()) return val;
1553 1577
1554 if (val->IsDiv() && (val->UseCount() == 1)) { 1578 if (val->IsDiv() && (val->UseCount() == 1)) {
1555 HDiv* hdiv = HDiv::cast(val); 1579 HDiv* hdiv = HDiv::cast(val);
1556 HValue* left = hdiv->left(); 1580 HValue* left = hdiv->left();
1557 HValue* right = hdiv->right(); 1581 HValue* right = hdiv->right();
1558 // Try to simplify left and right values of the division. 1582 // Try to simplify left and right values of the division.
1559 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left); 1583 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left);
1560 if (new_left == NULL && 1584 if (new_left == NULL &&
1561 hdiv->observed_input_representation(1).IsSmiOrInteger32()) { 1585 hdiv->observed_input_representation(1).IsSmiOrInteger32()) {
1562 new_left = new(block()->zone()) 1586 new_left = new(block()->zone()) HChange(
1563 HChange(left, Representation::Integer32(), false, false); 1587 left, Representation::Integer32(), false, false, false);
1564 HChange::cast(new_left)->InsertBefore(this); 1588 HChange::cast(new_left)->InsertBefore(this);
1565 } 1589 }
1566 HValue* new_right = 1590 HValue* new_right =
1567 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); 1591 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right);
1568 if (new_right == NULL && 1592 if (new_right == NULL &&
1569 #if V8_TARGET_ARCH_ARM 1593 #if V8_TARGET_ARCH_ARM
1570 CpuFeatures::IsSupported(SUDIV) && 1594 CpuFeatures::IsSupported(SUDIV) &&
1571 #endif 1595 #endif
1572 hdiv->observed_input_representation(2).IsSmiOrInteger32()) { 1596 hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
1573 new_right = new(block()->zone()) 1597 new_right = new(block()->zone()) HChange(
1574 HChange(right, Representation::Integer32(), false, false); 1598 right, Representation::Integer32(), false, false, false);
1575 HChange::cast(new_right)->InsertBefore(this); 1599 HChange::cast(new_right)->InsertBefore(this);
1576 } 1600 }
1577 1601
1578 // Return if left or right are not optimizable. 1602 // Return if left or right are not optimizable.
1579 if ((new_left == NULL) || (new_right == NULL)) return this; 1603 if ((new_left == NULL) || (new_right == NULL)) return this;
1580 1604
1581 // Insert the new values in the graph. 1605 // Insert the new values in the graph.
1582 if (new_left->IsInstruction() && 1606 if (new_left->IsInstruction() &&
1583 !HInstruction::cast(new_left)->IsLinked()) { 1607 !HInstruction::cast(new_left)->IsLinked()) {
1584 HInstruction::cast(new_left)->InsertBefore(this); 1608 HInstruction::cast(new_left)->InsertBefore(this);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 left()->PrintNameTo(stream); 1758 left()->PrintNameTo(stream);
1735 stream->Add(" "); 1759 stream->Add(" ");
1736 right()->PrintNameTo(stream); 1760 right()->PrintNameTo(stream);
1737 stream->Add(" "); 1761 stream->Add(" ");
1738 context()->PrintNameTo(stream); 1762 context()->PrintNameTo(stream);
1739 } 1763 }
1740 1764
1741 1765
1742 Range* HValue::InferRange(Zone* zone) { 1766 Range* HValue::InferRange(Zone* zone) {
1743 Range* result; 1767 Range* result;
1744 if (type().IsSmi()) { 1768 if (representation().IsSmi() || type().IsSmi()) {
1745 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); 1769 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue);
1746 result->set_can_be_minus_zero(false); 1770 result->set_can_be_minus_zero(false);
1747 } else { 1771 } else {
1748 result = new(zone) Range(); 1772 result = new(zone) Range();
1749 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32)); 1773 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32));
1750 // TODO(jkummerow): The range cannot be minus zero when the upper type 1774 // TODO(jkummerow): The range cannot be minus zero when the upper type
1751 // bound is Integer32. 1775 // bound is Integer32.
1752 } 1776 }
1753 return result; 1777 return result;
1754 } 1778 }
1755 1779
1756 1780
1757 Range* HChange::InferRange(Zone* zone) { 1781 Range* HChange::InferRange(Zone* zone) {
1758 Range* input_range = value()->range(); 1782 Range* input_range = value()->range();
1759 if (from().IsInteger32() && 1783 if (from().IsInteger32() && !value()->CheckFlag(HInstruction::kUint32) &&
1760 to().IsSmiOrTagged() && 1784 (to().IsSmi() ||
1761 !value()->CheckFlag(HInstruction::kUint32) && 1785 (to().IsTagged() &&
1762 input_range != NULL && input_range->IsInSmiRange()) { 1786 input_range != NULL &&
1787 input_range->IsInSmiRange()))) {
1763 set_type(HType::Smi()); 1788 set_type(HType::Smi());
1764 ClearGVNFlag(kChangesNewSpacePromotion); 1789 ClearGVNFlag(kChangesNewSpacePromotion);
1765 } 1790 }
1766 Range* result = (input_range != NULL) 1791 Range* result = (input_range != NULL)
1767 ? input_range->Copy(zone) 1792 ? input_range->Copy(zone)
1768 : HValue::InferRange(zone); 1793 : HValue::InferRange(zone);
1769 result->set_can_be_minus_zero(!to().IsSmiOrInteger32() || 1794 result->set_can_be_minus_zero(!to().IsSmiOrInteger32() ||
1770 !CheckFlag(kAllUsesTruncatingToInt32)); 1795 !(CheckFlag(kAllUsesTruncatingToInt32) ||
1796 CheckFlag(kAllUsesTruncatingToSmi)));
1797 if (to().IsSmi()) result->ClampToSmi();
1771 return result; 1798 return result;
1772 } 1799 }
1773 1800
1774 1801
1775 Range* HConstant::InferRange(Zone* zone) { 1802 Range* HConstant::InferRange(Zone* zone) {
1776 if (has_int32_value_) { 1803 if (has_int32_value_) {
1777 Range* result = new(zone) Range(int32_value_, int32_value_); 1804 Range* result = new(zone) Range(int32_value_, int32_value_);
1778 result->set_can_be_minus_zero(false); 1805 result->set_can_be_minus_zero(false);
1779 return result; 1806 return result;
1780 } 1807 }
(...skipping 16 matching lines...) Expand all
1797 } 1824 }
1798 return range; 1825 return range;
1799 } 1826 }
1800 } else { 1827 } else {
1801 return HValue::InferRange(zone); 1828 return HValue::InferRange(zone);
1802 } 1829 }
1803 } 1830 }
1804 1831
1805 1832
1806 Range* HAdd::InferRange(Zone* zone) { 1833 Range* HAdd::InferRange(Zone* zone) {
1807 if (representation().IsInteger32()) { 1834 Representation r = representation();
1835 if (r.IsSmiOrInteger32()) {
1808 Range* a = left()->range(); 1836 Range* a = left()->range();
1809 Range* b = right()->range(); 1837 Range* b = right()->range();
1810 Range* res = a->Copy(zone); 1838 Range* res = a->Copy(zone);
1811 if (!res->AddAndCheckOverflow(b) || 1839 if (!res->AddAndCheckOverflow(r, b) ||
1812 CheckFlag(kAllUsesTruncatingToInt32)) { 1840 (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
1841 (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) {
1813 ClearFlag(kCanOverflow); 1842 ClearFlag(kCanOverflow);
1814 } 1843 }
1815 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && 1844 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
1845 !CheckFlag(kAllUsesTruncatingToInt32) &&
1816 a->CanBeMinusZero() && b->CanBeMinusZero()); 1846 a->CanBeMinusZero() && b->CanBeMinusZero());
1817 return res; 1847 return res;
1818 } else { 1848 } else {
1819 return HValue::InferRange(zone); 1849 return HValue::InferRange(zone);
1820 } 1850 }
1821 } 1851 }
1822 1852
1823 1853
1824 Range* HSub::InferRange(Zone* zone) { 1854 Range* HSub::InferRange(Zone* zone) {
1825 if (representation().IsInteger32()) { 1855 Representation r = representation();
1856 if (r.IsSmiOrInteger32()) {
1826 Range* a = left()->range(); 1857 Range* a = left()->range();
1827 Range* b = right()->range(); 1858 Range* b = right()->range();
1828 Range* res = a->Copy(zone); 1859 Range* res = a->Copy(zone);
1829 if (!res->SubAndCheckOverflow(b) || 1860 if (!res->SubAndCheckOverflow(r, b) ||
1830 CheckFlag(kAllUsesTruncatingToInt32)) { 1861 (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
1862 (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) {
1831 ClearFlag(kCanOverflow); 1863 ClearFlag(kCanOverflow);
1832 } 1864 }
1833 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && 1865 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
1866 !CheckFlag(kAllUsesTruncatingToInt32) &&
1834 a->CanBeMinusZero() && b->CanBeZero()); 1867 a->CanBeMinusZero() && b->CanBeZero());
1835 return res; 1868 return res;
1836 } else { 1869 } else {
1837 return HValue::InferRange(zone); 1870 return HValue::InferRange(zone);
1838 } 1871 }
1839 } 1872 }
1840 1873
1841 1874
1842 Range* HMul::InferRange(Zone* zone) { 1875 Range* HMul::InferRange(Zone* zone) {
1843 if (representation().IsInteger32()) { 1876 Representation r = representation();
1877 if (r.IsSmiOrInteger32()) {
1844 Range* a = left()->range(); 1878 Range* a = left()->range();
1845 Range* b = right()->range(); 1879 Range* b = right()->range();
1846 Range* res = a->Copy(zone); 1880 Range* res = a->Copy(zone);
1847 if (!res->MulAndCheckOverflow(b)) { 1881 if (!res->MulAndCheckOverflow(r, b)) {
1848 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 1882 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32
1849 // would be wrong, because truncated integer multiplication is too 1883 // would be wrong, because truncated integer multiplication is too
1850 // precise and therefore not the same as converting to Double and back. 1884 // precise and therefore not the same as converting to Double and back.
1851 ClearFlag(kCanOverflow); 1885 ClearFlag(kCanOverflow);
1852 } 1886 }
1853 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && 1887 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
1888 !CheckFlag(kAllUsesTruncatingToInt32) &&
1854 ((a->CanBeZero() && b->CanBeNegative()) || 1889 ((a->CanBeZero() && b->CanBeNegative()) ||
1855 (a->CanBeNegative() && b->CanBeZero()))); 1890 (a->CanBeNegative() && b->CanBeZero())));
1856 return res; 1891 return res;
1857 } else { 1892 } else {
1858 return HValue::InferRange(zone); 1893 return HValue::InferRange(zone);
1859 } 1894 }
1860 } 1895 }
1861 1896
1862 1897
1863 Range* HDiv::InferRange(Zone* zone) { 1898 Range* HDiv::InferRange(Zone* zone) {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 break; 1997 break;
1963 } 1998 }
1964 } 1999 }
1965 ClearFlag(kNumericConstraintEvaluationInProgress); 2000 ClearFlag(kNumericConstraintEvaluationInProgress);
1966 2001
1967 return result; 2002 return result;
1968 } 2003 }
1969 2004
1970 2005
1971 Range* HMathMinMax::InferRange(Zone* zone) { 2006 Range* HMathMinMax::InferRange(Zone* zone) {
1972 if (representation().IsInteger32()) { 2007 if (representation().IsSmiOrInteger32()) {
1973 Range* a = left()->range(); 2008 Range* a = left()->range();
1974 Range* b = right()->range(); 2009 Range* b = right()->range();
1975 Range* res = a->Copy(zone); 2010 Range* res = a->Copy(zone);
1976 if (operation_ == kMathMax) { 2011 if (operation_ == kMathMax) {
1977 res->CombinedMax(b); 2012 res->CombinedMax(b);
1978 } else { 2013 } else {
1979 ASSERT(operation_ == kMathMin); 2014 ASSERT(operation_ == kMathMin);
1980 res->CombinedMin(b); 2015 res->CombinedMin(b);
1981 } 2016 }
1982 return res; 2017 return res;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2047 ASSERT(block() == NULL); 2082 ASSERT(block() == NULL);
2048 } 2083 }
2049 2084
2050 2085
2051 void HPhi::InitRealUses(int phi_id) { 2086 void HPhi::InitRealUses(int phi_id) {
2052 // Initialize real uses. 2087 // Initialize real uses.
2053 phi_id_ = phi_id; 2088 phi_id_ = phi_id;
2054 // Compute a conservative approximation of truncating uses before inferring 2089 // Compute a conservative approximation of truncating uses before inferring
2055 // representations. The proper, exact computation will be done later, when 2090 // representations. The proper, exact computation will be done later, when
2056 // inserting representation changes. 2091 // inserting representation changes.
2092 SetFlag(kTruncatingToSmi);
2057 SetFlag(kTruncatingToInt32); 2093 SetFlag(kTruncatingToInt32);
2058 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 2094 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
2059 HValue* value = it.value(); 2095 HValue* value = it.value();
2060 if (!value->IsPhi()) { 2096 if (!value->IsPhi()) {
2061 Representation rep = value->observed_input_representation(it.index()); 2097 Representation rep = value->observed_input_representation(it.index());
2062 non_phi_uses_[rep.kind()] += value->LoopWeight(); 2098 non_phi_uses_[rep.kind()] += value->LoopWeight();
2063 if (FLAG_trace_representation) { 2099 if (FLAG_trace_representation) {
2064 PrintF("#%d Phi is used by real #%d %s as %s\n", 2100 PrintF("#%d Phi is used by real #%d %s as %s\n",
2065 id(), value->id(), value->Mnemonic(), rep.Mnemonic()); 2101 id(), value->id(), value->Mnemonic(), rep.Mnemonic());
2066 } 2102 }
2067 if (!value->IsSimulate() && !value->CheckFlag(kTruncatingToInt32)) { 2103 if (!value->IsSimulate()) {
2068 ClearFlag(kTruncatingToInt32); 2104 if (!value->CheckFlag(kTruncatingToSmi)) {
2105 ClearFlag(kTruncatingToSmi);
2106 }
2107 if (!value->CheckFlag(kTruncatingToInt32)) {
2108 ClearFlag(kTruncatingToInt32);
2109 }
2069 } 2110 }
2070 } 2111 }
2071 } 2112 }
2072 } 2113 }
2073 2114
2074 2115
2075 void HPhi::AddNonPhiUsesFrom(HPhi* other) { 2116 void HPhi::AddNonPhiUsesFrom(HPhi* other) {
2076 if (FLAG_trace_representation) { 2117 if (FLAG_trace_representation) {
2077 PrintF("adding to #%d Phi uses of #%d Phi: s%d i%d d%d t%d\n", 2118 PrintF("adding to #%d Phi uses of #%d Phi: s%d i%d d%d t%d\n",
2078 id(), other->id(), 2119 id(), other->id(),
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
2352 right()->PrintNameTo(stream); 2393 right()->PrintNameTo(stream);
2353 if (CheckFlag(kCanOverflow)) stream->Add(" !"); 2394 if (CheckFlag(kCanOverflow)) stream->Add(" !");
2354 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); 2395 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
2355 } 2396 }
2356 2397
2357 2398
2358 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { 2399 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) {
2359 ASSERT(CheckFlag(kFlexibleRepresentation)); 2400 ASSERT(CheckFlag(kFlexibleRepresentation));
2360 Representation new_rep = RepresentationFromInputs(); 2401 Representation new_rep = RepresentationFromInputs();
2361 UpdateRepresentation(new_rep, h_infer, "inputs"); 2402 UpdateRepresentation(new_rep, h_infer, "inputs");
2362 // When the operation has information about its own output type, don't look 2403 if (observed_output_representation_.IsNone()) {
2363 // at uses. 2404 new_rep = RepresentationFromUses();
2364 if (!observed_output_representation_.IsNone()) return; 2405 UpdateRepresentation(new_rep, h_infer, "uses");
2365 new_rep = RepresentationFromUses(); 2406 } else {
2366 UpdateRepresentation(new_rep, h_infer, "uses"); 2407 new_rep = RepresentationFromOutput();
2408 UpdateRepresentation(new_rep, h_infer, "output");
2409 }
2367 new_rep = RepresentationFromUseRequirements(); 2410 new_rep = RepresentationFromUseRequirements();
2368 if (new_rep.fits_into(Representation::Integer32())) { 2411 if (new_rep.IsDouble()) new_rep = Representation::Integer32();
2412 if (new_rep.IsInteger32()) {
2369 UpdateRepresentation(new_rep, h_infer, "use requirements"); 2413 UpdateRepresentation(new_rep, h_infer, "use requirements");
2370 } 2414 }
2371 } 2415 }
2372 2416
2373 2417
2374 bool HBinaryOperation::IgnoreObservedOutputRepresentation(
2375 Representation current_rep) {
2376 return observed_output_representation_.IsDouble() &&
2377 current_rep.IsInteger32() &&
2378 // Mul in Integer32 mode would be too precise.
2379 !this->IsMul() &&
2380 CheckUsesForFlag(kTruncatingToInt32);
2381 }
2382
2383
2384 Representation HBinaryOperation::RepresentationFromInputs() { 2418 Representation HBinaryOperation::RepresentationFromInputs() {
2385 // Determine the worst case of observed input representations and 2419 // Determine the worst case of observed input representations and
2386 // the currently assumed output representation. 2420 // the currently assumed output representation.
2387 Representation rep = representation(); 2421 Representation rep = representation();
2388 for (int i = 1; i <= 2; ++i) { 2422 for (int i = 1; i <= 2; ++i) {
2389 Representation input_rep = observed_input_representation(i); 2423 rep = rep.generalize(observed_input_representation(i));
2390 if (input_rep.is_more_general_than(rep)) rep = input_rep;
2391 } 2424 }
2392 // If any of the actual input representation is more general than what we 2425 // If any of the actual input representation is more general than what we
2393 // have so far but not Tagged, use that representation instead. 2426 // have so far but not Tagged, use that representation instead.
2394 Representation left_rep = left()->representation(); 2427 Representation left_rep = left()->representation();
2395 Representation right_rep = right()->representation(); 2428 Representation right_rep = right()->representation();
2429 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
2430 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
2396 2431
2397 if (left_rep.is_more_general_than(rep) && !left_rep.IsTagged()) { 2432 return rep;
2398 rep = left_rep; 2433 }
2399 } 2434
2400 if (right_rep.is_more_general_than(rep) && !right_rep.IsTagged()) { 2435
2401 rep = right_rep; 2436 bool HBinaryOperation::IgnoreObservedOutputRepresentation(
2402 } 2437 Representation current_rep) {
2438 return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) ||
2439 (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) &&
2440 // Mul in Integer32 mode would be too precise.
2441 !this->IsMul();
2442 }
2443
2444
2445 Representation HBinaryOperation::RepresentationFromOutput() {
2446 Representation rep = representation();
2403 // Consider observed output representation, but ignore it if it's Double, 2447 // Consider observed output representation, but ignore it if it's Double,
2404 // this instruction is not a division, and all its uses are truncating 2448 // this instruction is not a division, and all its uses are truncating
2405 // to Integer32. 2449 // to Integer32.
2406 if (observed_output_representation_.is_more_general_than(rep) && 2450 if (observed_output_representation_.is_more_general_than(rep) &&
2407 !IgnoreObservedOutputRepresentation(rep)) { 2451 !IgnoreObservedOutputRepresentation(rep)) {
2408 rep = observed_output_representation_; 2452 return observed_output_representation_;
2409 } 2453 }
2410 return rep; 2454 return Representation::None();
2411 } 2455 }
2412 2456
2413 2457
2414 void HBinaryOperation::AssumeRepresentation(Representation r) { 2458 void HBinaryOperation::AssumeRepresentation(Representation r) {
2415 set_observed_input_representation(1, r); 2459 set_observed_input_representation(1, r);
2416 set_observed_input_representation(2, r); 2460 set_observed_input_representation(2, r);
2417 HValue::AssumeRepresentation(r); 2461 HValue::AssumeRepresentation(r);
2418 } 2462 }
2419 2463
2420 2464
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after
3334 3378
3335 3379
3336 HType HFunctionLiteral::CalculateInferredType() { 3380 HType HFunctionLiteral::CalculateInferredType() {
3337 return HType::JSObject(); 3381 return HType::JSObject();
3338 } 3382 }
3339 3383
3340 3384
3341 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( 3385 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero(
3342 BitVector* visited) { 3386 BitVector* visited) {
3343 visited->Add(id()); 3387 visited->Add(id());
3344 if (representation().IsInteger32() && 3388 if (representation().IsSmiOrInteger32() &&
3345 !value()->representation().IsInteger32()) { 3389 !value()->representation().Equals(representation())) {
3346 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { 3390 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) {
3347 SetFlag(kBailoutOnMinusZero); 3391 SetFlag(kBailoutOnMinusZero);
3348 } 3392 }
3349 } 3393 }
3350 if (RequiredInputRepresentation(0).IsInteger32() && 3394 if (RequiredInputRepresentation(0).IsSmiOrInteger32() &&
3351 representation().IsInteger32()) { 3395 representation().Equals(RequiredInputRepresentation(0))) {
3352 return value(); 3396 return value();
3353 } 3397 }
3354 return NULL; 3398 return NULL;
3355 } 3399 }
3356 3400
3357 3401
3358
3359 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { 3402 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) {
3360 visited->Add(id()); 3403 visited->Add(id());
3361 if (from().IsInteger32()) return NULL; 3404 if (from().IsSmiOrInteger32()) return NULL;
3362 if (CanTruncateToInt32()) return NULL; 3405 if (CanTruncateToInt32()) return NULL;
3363 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { 3406 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) {
3364 SetFlag(kBailoutOnMinusZero); 3407 SetFlag(kBailoutOnMinusZero);
3365 } 3408 }
3366 ASSERT(!from().IsInteger32() || !to().IsInteger32()); 3409 ASSERT(!from().IsSmiOrInteger32() || !to().IsSmiOrInteger32());
3367 return NULL; 3410 return NULL;
3368 } 3411 }
3369 3412
3370 3413
3371 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero( 3414 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero(
3372 BitVector* visited) { 3415 BitVector* visited) {
3373 visited->Add(id()); 3416 visited->Add(id());
3374 return value(); 3417 return value();
3375 } 3418 }
3376 3419
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3443 if (value()->IsConstant()) { 3486 if (value()->IsConstant()) {
3444 return false; 3487 return false;
3445 } 3488 }
3446 3489
3447 if (value()->IsLoadKeyed()) { 3490 if (value()->IsLoadKeyed()) {
3448 return IsExternalFloatOrDoubleElementsKind( 3491 return IsExternalFloatOrDoubleElementsKind(
3449 HLoadKeyed::cast(value())->elements_kind()); 3492 HLoadKeyed::cast(value())->elements_kind());
3450 } 3493 }
3451 3494
3452 if (value()->IsChange()) { 3495 if (value()->IsChange()) {
3453 if (HChange::cast(value())->from().IsInteger32()) { 3496 if (HChange::cast(value())->from().IsSmiOrInteger32()) {
3454 return false; 3497 return false;
3455 } 3498 }
3456 if (HChange::cast(value())->value()->type().IsSmi()) { 3499 if (HChange::cast(value())->value()->type().IsSmi()) {
3457 return false; 3500 return false;
3458 } 3501 }
3459 } 3502 }
3460 return true; 3503 return true;
3461 } 3504 }
3462 3505
3463 3506
3464 #define H_CONSTANT_INT32(val) \ 3507 #define H_CONSTANT_INT32(val) \
3465 new(zone) HConstant(static_cast<int32_t>(val), Representation::Integer32()) 3508 new(zone) HConstant(static_cast<int32_t>(val))
3466 #define H_CONSTANT_DOUBLE(val) \ 3509 #define H_CONSTANT_DOUBLE(val) \
3467 new(zone) HConstant(static_cast<double>(val), Representation::Double()) 3510 new(zone) HConstant(static_cast<double>(val), Representation::Double())
3468 3511
3469 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ 3512 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
3470 HInstruction* HInstr::New( \ 3513 HInstruction* HInstr::New( \
3471 Zone* zone, HValue* context, HValue* left, HValue* right) { \ 3514 Zone* zone, HValue* context, HValue* left, HValue* right) { \
3472 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ 3515 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
3473 HConstant* c_left = HConstant::cast(left); \ 3516 HConstant* c_left = HConstant::cast(left); \
3474 HConstant* c_right = HConstant::cast(right); \ 3517 HConstant* c_right = HConstant::cast(right); \
3475 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ 3518 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
3794 for (int i = 0; i < OperandCount(); ++i) { 3837 for (int i = 0; i < OperandCount(); ++i) {
3795 if (!OperandAt(i)->IsConstant()) return; 3838 if (!OperandAt(i)->IsConstant()) return;
3796 } 3839 }
3797 HGraph* graph = block()->graph(); 3840 HGraph* graph = block()->graph();
3798 for (int i = 0; i < OperandCount(); ++i) { 3841 for (int i = 0; i < OperandCount(); ++i) {
3799 HConstant* operand = HConstant::cast(OperandAt(i)); 3842 HConstant* operand = HConstant::cast(OperandAt(i));
3800 if (operand->HasInteger32Value()) { 3843 if (operand->HasInteger32Value()) {
3801 continue; 3844 continue;
3802 } else if (operand->HasDoubleValue()) { 3845 } else if (operand->HasDoubleValue()) {
3803 HConstant* integer_input = 3846 HConstant* integer_input =
3804 new(graph->zone()) HConstant(DoubleToInt32(operand->DoubleValue()), 3847 new(graph->zone()) HConstant(DoubleToInt32(operand->DoubleValue()));
3805 Representation::Integer32());
3806 integer_input->InsertAfter(operand); 3848 integer_input->InsertAfter(operand);
3807 SetOperandAt(i, integer_input); 3849 SetOperandAt(i, integer_input);
3808 } else if (operand == graph->GetConstantTrue()) { 3850 } else if (operand == graph->GetConstantTrue()) {
3809 SetOperandAt(i, graph->GetConstant1()); 3851 SetOperandAt(i, graph->GetConstant1());
3810 } else { 3852 } else {
3811 // This catches |false|, |undefined|, strings and objects. 3853 // This catches |false|, |undefined|, strings and objects.
3812 SetOperandAt(i, graph->GetConstant0()); 3854 SetOperandAt(i, graph->GetConstant0());
3813 } 3855 }
3814 } 3856 }
3815 // Overwrite observed input representations because they are likely Tagged. 3857 // Overwrite observed input representations because they are likely Tagged.
3816 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 3858 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
3817 HValue* use = it.value(); 3859 HValue* use = it.value();
3818 if (use->IsBinaryOperation()) { 3860 if (use->IsBinaryOperation()) {
3819 HBinaryOperation::cast(use)->set_observed_input_representation( 3861 HBinaryOperation::cast(use)->set_observed_input_representation(
3820 it.index(), Representation::Integer32()); 3862 it.index(), Representation::Smi());
3821 } 3863 }
3822 } 3864 }
3823 } 3865 }
3824 3866
3825 3867
3826 void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) { 3868 void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) {
3827 ASSERT(CheckFlag(kFlexibleRepresentation)); 3869 ASSERT(CheckFlag(kFlexibleRepresentation));
3828 Representation new_rep = RepresentationFromInputs(); 3870 Representation new_rep = RepresentationFromInputs();
3829 UpdateRepresentation(new_rep, h_infer, "inputs"); 3871 UpdateRepresentation(new_rep, h_infer, "inputs");
3830 new_rep = RepresentationFromUses(); 3872 new_rep = RepresentationFromUses();
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
4037 case kBackingStore: 4079 case kBackingStore:
4038 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); 4080 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
4039 stream->Add("[backing-store]"); 4081 stream->Add("[backing-store]");
4040 break; 4082 break;
4041 } 4083 }
4042 4084
4043 stream->Add("@%d", offset()); 4085 stream->Add("@%d", offset());
4044 } 4086 }
4045 4087
4046 } } // namespace v8::internal 4088 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/hydrogen-minus-zero.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698