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

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

Issue 20070005: Adding Smi support to Add, Sub, Mul, and Bitwise (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed nit Created 7 years, 4 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 } 77 }
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 if (representation().IsSmi() && HasNonSmiUse()) {
88 if (new_rep.fits_into(Representation::Integer32())) { 88 UpdateRepresentation(
89 UpdateRepresentation(new_rep, h_infer, "use requirements"); 89 Representation::Integer32(), h_infer, "use requirements");
90 } 90 }
91 } 91 }
92 92
93 93
94 Representation HValue::RepresentationFromUses() { 94 Representation HValue::RepresentationFromUses() {
95 if (HasNoUses()) return Representation::None(); 95 if (HasNoUses()) return Representation::None();
96 96
97 // Array of use counts for each representation. 97 // Array of use counts for each representation.
98 int use_count[Representation::kNumRepresentations] = { 0 }; 98 int use_count[Representation::kNumRepresentations] = { 0 };
99 99
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 } 252 }
253 253
254 254
255 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { 255 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) {
256 return guarantee->IsBoundsCheckBaseIndexInformation() 256 return guarantee->IsBoundsCheckBaseIndexInformation()
257 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check() 257 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check()
258 : guarantee; 258 : guarantee;
259 } 259 }
260 260
261 261
262 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { 262 static int32_t ConvertAndSetOverflow(Representation r,
263 if (result > kMaxInt) { 263 int64_t result,
264 *overflow = true; 264 bool* overflow) {
265 return kMaxInt; 265 if (r.IsSmi()) {
266 } 266 if (result > Smi::kMaxValue) {
267 if (result < kMinInt) { 267 *overflow = true;
268 *overflow = true; 268 return Smi::kMaxValue;
269 return kMinInt; 269 }
270 if (result < Smi::kMinValue) {
271 *overflow = true;
272 return Smi::kMinValue;
273 }
274 } else {
275 if (result > kMaxInt) {
276 *overflow = true;
277 return kMaxInt;
278 }
279 if (result < kMinInt) {
280 *overflow = true;
281 return kMinInt;
282 }
270 } 283 }
271 return static_cast<int32_t>(result); 284 return static_cast<int32_t>(result);
272 } 285 }
273 286
274 287
275 static int32_t AddWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 288 static int32_t AddWithoutOverflow(Representation r,
289 int32_t a,
290 int32_t b,
291 bool* overflow) {
276 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b); 292 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b);
277 return ConvertAndSetOverflow(result, overflow); 293 return ConvertAndSetOverflow(r, result, overflow);
278 } 294 }
279 295
280 296
281 static int32_t SubWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 297 static int32_t SubWithoutOverflow(Representation r,
298 int32_t a,
299 int32_t b,
300 bool* overflow) {
282 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b); 301 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b);
283 return ConvertAndSetOverflow(result, overflow); 302 return ConvertAndSetOverflow(r, result, overflow);
284 } 303 }
285 304
286 305
287 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { 306 static int32_t MulWithoutOverflow(const Representation& r,
307 int32_t a,
308 int32_t b,
309 bool* overflow) {
288 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); 310 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b);
289 return ConvertAndSetOverflow(result, overflow); 311 return ConvertAndSetOverflow(r, result, overflow);
290 } 312 }
291 313
292 314
293 int32_t Range::Mask() const { 315 int32_t Range::Mask() const {
294 if (lower_ == upper_) return lower_; 316 if (lower_ == upper_) return lower_;
295 if (lower_ >= 0) { 317 if (lower_ >= 0) {
296 int32_t res = 1; 318 int32_t res = 1;
297 while (res < upper_) { 319 while (res < upper_) {
298 res = (res << 1) | 1; 320 res = (res << 1) | 1;
299 } 321 }
300 return res; 322 return res;
301 } 323 }
302 return 0xffffffff; 324 return 0xffffffff;
303 } 325 }
304 326
305 327
306 void Range::AddConstant(int32_t value) { 328 void Range::AddConstant(int32_t value) {
307 if (value == 0) return; 329 if (value == 0) return;
308 bool may_overflow = false; // Overflow is ignored here. 330 bool may_overflow = false; // Overflow is ignored here.
309 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); 331 Representation r = Representation::Integer32();
310 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); 332 lower_ = AddWithoutOverflow(r, lower_, value, &may_overflow);
333 upper_ = AddWithoutOverflow(r, upper_, value, &may_overflow);
311 #ifdef DEBUG 334 #ifdef DEBUG
312 Verify(); 335 Verify();
313 #endif 336 #endif
314 } 337 }
315 338
316 339
317 void Range::Intersect(Range* other) { 340 void Range::Intersect(Range* other) {
318 upper_ = Min(upper_, other->upper_); 341 upper_ = Min(upper_, other->upper_);
319 lower_ = Max(lower_, other->lower_); 342 lower_ = Max(lower_, other->lower_);
320 bool b = CanBeMinusZero() && other->CanBeMinusZero(); 343 bool b = CanBeMinusZero() && other->CanBeMinusZero();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 lower_ = lower_ << bits; 382 lower_ = lower_ << bits;
360 upper_ = upper_ << bits; 383 upper_ = upper_ << bits;
361 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) { 384 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) {
362 upper_ = kMaxInt; 385 upper_ = kMaxInt;
363 lower_ = kMinInt; 386 lower_ = kMinInt;
364 } 387 }
365 set_can_be_minus_zero(false); 388 set_can_be_minus_zero(false);
366 } 389 }
367 390
368 391
369 bool Range::AddAndCheckOverflow(Range* other) { 392 bool Range::AddAndCheckOverflow(const Representation& r, Range* other) {
370 bool may_overflow = false; 393 bool may_overflow = false;
371 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); 394 lower_ = AddWithoutOverflow(r, lower_, other->lower(), &may_overflow);
372 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); 395 upper_ = AddWithoutOverflow(r, upper_, other->upper(), &may_overflow);
373 KeepOrder(); 396 KeepOrder();
374 #ifdef DEBUG 397 #ifdef DEBUG
375 Verify(); 398 Verify();
376 #endif 399 #endif
377 return may_overflow; 400 return may_overflow;
378 } 401 }
379 402
380 403
381 bool Range::SubAndCheckOverflow(Range* other) { 404 bool Range::SubAndCheckOverflow(const Representation& r, Range* other) {
382 bool may_overflow = false; 405 bool may_overflow = false;
383 lower_ = SubWithoutOverflow(lower_, other->upper(), &may_overflow); 406 lower_ = SubWithoutOverflow(r, lower_, other->upper(), &may_overflow);
384 upper_ = SubWithoutOverflow(upper_, other->lower(), &may_overflow); 407 upper_ = SubWithoutOverflow(r, upper_, other->lower(), &may_overflow);
385 KeepOrder(); 408 KeepOrder();
386 #ifdef DEBUG 409 #ifdef DEBUG
387 Verify(); 410 Verify();
388 #endif 411 #endif
389 return may_overflow; 412 return may_overflow;
390 } 413 }
391 414
392 415
393 void Range::KeepOrder() { 416 void Range::KeepOrder() {
394 if (lower_ > upper_) { 417 if (lower_ > upper_) {
395 int32_t tmp = lower_; 418 int32_t tmp = lower_;
396 lower_ = upper_; 419 lower_ = upper_;
397 upper_ = tmp; 420 upper_ = tmp;
398 } 421 }
399 } 422 }
400 423
401 424
402 #ifdef DEBUG 425 #ifdef DEBUG
403 void Range::Verify() const { 426 void Range::Verify() const {
404 ASSERT(lower_ <= upper_); 427 ASSERT(lower_ <= upper_);
405 } 428 }
406 #endif 429 #endif
407 430
408 431
409 bool Range::MulAndCheckOverflow(Range* other) { 432 bool Range::MulAndCheckOverflow(const Representation& r, Range* other) {
410 bool may_overflow = false; 433 bool may_overflow = false;
411 int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow); 434 int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow);
412 int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow); 435 int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow);
413 int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow); 436 int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow);
414 int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow); 437 int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow);
415 lower_ = Min(Min(v1, v2), Min(v3, v4)); 438 lower_ = Min(Min(v1, v2), Min(v3, v4));
416 upper_ = Max(Max(v1, v2), Max(v3, v4)); 439 upper_ = Max(Max(v1, v2), Max(v3, v4));
417 #ifdef DEBUG 440 #ifdef DEBUG
418 Verify(); 441 Verify();
419 #endif 442 #endif
420 return may_overflow; 443 return may_overflow;
421 } 444 }
422 445
423 446
424 const char* HType::ToString() { 447 const char* HType::ToString() {
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 1445
1423 1446
1424 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { 1447 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) {
1425 object()->PrintNameTo(stream); 1448 object()->PrintNameTo(stream);
1426 stream->Add(" "); 1449 stream->Add(" ");
1427 index()->PrintNameTo(stream); 1450 index()->PrintNameTo(stream);
1428 } 1451 }
1429 1452
1430 1453
1431 HValue* HBitwise::Canonicalize() { 1454 HValue* HBitwise::Canonicalize() {
1432 if (!representation().IsInteger32()) return this; 1455 if (!representation().IsSmiOrInteger32()) return this;
1433 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. 1456 // 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; 1457 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0;
1435 if (left()->EqualsInteger32Constant(nop_constant) && 1458 if (left()->EqualsInteger32Constant(nop_constant) &&
1436 !right()->CheckFlag(kUint32)) { 1459 !right()->CheckFlag(kUint32)) {
1437 return right(); 1460 return right();
1438 } 1461 }
1439 if (right()->EqualsInteger32Constant(nop_constant) && 1462 if (right()->EqualsInteger32Constant(nop_constant) &&
1440 !left()->CheckFlag(kUint32)) { 1463 !left()->CheckFlag(kUint32)) {
1441 return left(); 1464 return left();
1442 } 1465 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 } 1565 }
1543 1566
1544 1567
1545 HValue* HUnaryMathOperation::Canonicalize() { 1568 HValue* HUnaryMathOperation::Canonicalize() {
1546 if (op() == kMathFloor) { 1569 if (op() == kMathFloor) {
1547 HValue* val = value(); 1570 HValue* val = value();
1548 if (val->IsChange()) val = HChange::cast(val)->value(); 1571 if (val->IsChange()) val = HChange::cast(val)->value();
1549 1572
1550 // If the input is integer32 then we replace the floor instruction 1573 // If the input is integer32 then we replace the floor instruction
1551 // with its input. 1574 // with its input.
1552 if (val->representation().IsInteger32()) return val; 1575 if (val->representation().IsSmiOrInteger32()) return val;
1553 1576
1554 if (val->IsDiv() && (val->UseCount() == 1)) { 1577 if (val->IsDiv() && (val->UseCount() == 1)) {
1555 HDiv* hdiv = HDiv::cast(val); 1578 HDiv* hdiv = HDiv::cast(val);
1556 HValue* left = hdiv->left(); 1579 HValue* left = hdiv->left();
1557 HValue* right = hdiv->right(); 1580 HValue* right = hdiv->right();
1558 // Try to simplify left and right values of the division. 1581 // Try to simplify left and right values of the division.
1559 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left); 1582 HValue* new_left = SimplifiedDividendForMathFloorOfDiv(left);
1560 if (new_left == NULL && 1583 if (new_left == NULL &&
1561 hdiv->observed_input_representation(1).IsSmiOrInteger32()) { 1584 hdiv->observed_input_representation(1).IsSmiOrInteger32()) {
1562 new_left = new(block()->zone()) 1585 new_left = new(block()->zone()) HChange(
1563 HChange(left, Representation::Integer32(), false, false); 1586 left, Representation::Integer32(), false, false, false);
1564 HChange::cast(new_left)->InsertBefore(this); 1587 HChange::cast(new_left)->InsertBefore(this);
1565 } 1588 }
1566 HValue* new_right = 1589 HValue* new_right =
1567 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right); 1590 LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(right);
1568 if (new_right == NULL && 1591 if (new_right == NULL &&
1569 #if V8_TARGET_ARCH_ARM 1592 #if V8_TARGET_ARCH_ARM
1570 CpuFeatures::IsSupported(SUDIV) && 1593 CpuFeatures::IsSupported(SUDIV) &&
1571 #endif 1594 #endif
1572 hdiv->observed_input_representation(2).IsSmiOrInteger32()) { 1595 hdiv->observed_input_representation(2).IsSmiOrInteger32()) {
1573 new_right = new(block()->zone()) 1596 new_right = new(block()->zone()) HChange(
1574 HChange(right, Representation::Integer32(), false, false); 1597 right, Representation::Integer32(), false, false, false);
1575 HChange::cast(new_right)->InsertBefore(this); 1598 HChange::cast(new_right)->InsertBefore(this);
1576 } 1599 }
1577 1600
1578 // Return if left or right are not optimizable. 1601 // Return if left or right are not optimizable.
1579 if ((new_left == NULL) || (new_right == NULL)) return this; 1602 if ((new_left == NULL) || (new_right == NULL)) return this;
1580 1603
1581 // Insert the new values in the graph. 1604 // Insert the new values in the graph.
1582 if (new_left->IsInstruction() && 1605 if (new_left->IsInstruction() &&
1583 !HInstruction::cast(new_left)->IsLinked()) { 1606 !HInstruction::cast(new_left)->IsLinked()) {
1584 HInstruction::cast(new_left)->InsertBefore(this); 1607 HInstruction::cast(new_left)->InsertBefore(this);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1734 left()->PrintNameTo(stream); 1757 left()->PrintNameTo(stream);
1735 stream->Add(" "); 1758 stream->Add(" ");
1736 right()->PrintNameTo(stream); 1759 right()->PrintNameTo(stream);
1737 stream->Add(" "); 1760 stream->Add(" ");
1738 context()->PrintNameTo(stream); 1761 context()->PrintNameTo(stream);
1739 } 1762 }
1740 1763
1741 1764
1742 Range* HValue::InferRange(Zone* zone) { 1765 Range* HValue::InferRange(Zone* zone) {
1743 Range* result; 1766 Range* result;
1744 if (type().IsSmi()) { 1767 if (representation().IsSmi() || type().IsSmi()) {
1745 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); 1768 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue);
1746 result->set_can_be_minus_zero(false); 1769 result->set_can_be_minus_zero(false);
1747 } else { 1770 } else {
1748 result = new(zone) Range(); 1771 result = new(zone) Range();
1749 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32)); 1772 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32));
1750 // TODO(jkummerow): The range cannot be minus zero when the upper type 1773 // TODO(jkummerow): The range cannot be minus zero when the upper type
1751 // bound is Integer32. 1774 // bound is Integer32.
1752 } 1775 }
1753 return result; 1776 return result;
1754 } 1777 }
1755 1778
1756 1779
1757 Range* HChange::InferRange(Zone* zone) { 1780 Range* HChange::InferRange(Zone* zone) {
1758 Range* input_range = value()->range(); 1781 Range* input_range = value()->range();
1759 if (from().IsInteger32() && 1782 if (from().IsInteger32() && !value()->CheckFlag(HInstruction::kUint32) &&
1760 to().IsSmiOrTagged() && 1783 (to().IsSmi() ||
1761 !value()->CheckFlag(HInstruction::kUint32) && 1784 (to().IsTagged() &&
1762 input_range != NULL && input_range->IsInSmiRange()) { 1785 input_range != NULL &&
1786 input_range->IsInSmiRange()))) {
1763 set_type(HType::Smi()); 1787 set_type(HType::Smi());
1764 ClearGVNFlag(kChangesNewSpacePromotion); 1788 ClearGVNFlag(kChangesNewSpacePromotion);
1765 } 1789 }
1766 Range* result = (input_range != NULL) 1790 Range* result = (input_range != NULL)
1767 ? input_range->Copy(zone) 1791 ? input_range->Copy(zone)
1768 : HValue::InferRange(zone); 1792 : HValue::InferRange(zone);
1769 result->set_can_be_minus_zero(!to().IsSmiOrInteger32() || 1793 result->set_can_be_minus_zero(!to().IsSmiOrInteger32() ||
1770 !CheckFlag(kAllUsesTruncatingToInt32)); 1794 !(CheckFlag(kAllUsesTruncatingToInt32) ||
1795 CheckFlag(kAllUsesTruncatingToSmi)));
1796 if (to().IsSmi()) result->ClampToSmi();
1771 return result; 1797 return result;
1772 } 1798 }
1773 1799
1774 1800
1775 Range* HConstant::InferRange(Zone* zone) { 1801 Range* HConstant::InferRange(Zone* zone) {
1776 if (has_int32_value_) { 1802 if (has_int32_value_) {
1777 Range* result = new(zone) Range(int32_value_, int32_value_); 1803 Range* result = new(zone) Range(int32_value_, int32_value_);
1778 result->set_can_be_minus_zero(false); 1804 result->set_can_be_minus_zero(false);
1779 return result; 1805 return result;
1780 } 1806 }
(...skipping 16 matching lines...) Expand all
1797 } 1823 }
1798 return range; 1824 return range;
1799 } 1825 }
1800 } else { 1826 } else {
1801 return HValue::InferRange(zone); 1827 return HValue::InferRange(zone);
1802 } 1828 }
1803 } 1829 }
1804 1830
1805 1831
1806 Range* HAdd::InferRange(Zone* zone) { 1832 Range* HAdd::InferRange(Zone* zone) {
1807 if (representation().IsInteger32()) { 1833 Representation r = representation();
1834 if (r.IsSmiOrInteger32()) {
1808 Range* a = left()->range(); 1835 Range* a = left()->range();
1809 Range* b = right()->range(); 1836 Range* b = right()->range();
1810 Range* res = a->Copy(zone); 1837 Range* res = a->Copy(zone);
1811 if (!res->AddAndCheckOverflow(b) || 1838 if (!res->AddAndCheckOverflow(r, b) ||
1812 CheckFlag(kAllUsesTruncatingToInt32)) { 1839 (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
1840 (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) {
1813 ClearFlag(kCanOverflow); 1841 ClearFlag(kCanOverflow);
1814 } 1842 }
1815 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && 1843 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
1844 !CheckFlag(kAllUsesTruncatingToInt32) &&
1816 a->CanBeMinusZero() && b->CanBeMinusZero()); 1845 a->CanBeMinusZero() && b->CanBeMinusZero());
1817 return res; 1846 return res;
1818 } else { 1847 } else {
1819 return HValue::InferRange(zone); 1848 return HValue::InferRange(zone);
1820 } 1849 }
1821 } 1850 }
1822 1851
1823 1852
1824 Range* HSub::InferRange(Zone* zone) { 1853 Range* HSub::InferRange(Zone* zone) {
1825 if (representation().IsInteger32()) { 1854 Representation r = representation();
1855 if (r.IsSmiOrInteger32()) {
1826 Range* a = left()->range(); 1856 Range* a = left()->range();
1827 Range* b = right()->range(); 1857 Range* b = right()->range();
1828 Range* res = a->Copy(zone); 1858 Range* res = a->Copy(zone);
1829 if (!res->SubAndCheckOverflow(b) || 1859 if (!res->SubAndCheckOverflow(r, b) ||
1830 CheckFlag(kAllUsesTruncatingToInt32)) { 1860 (r.IsInteger32() && CheckFlag(kAllUsesTruncatingToInt32)) ||
1861 (r.IsSmi() && CheckFlag(kAllUsesTruncatingToSmi))) {
1831 ClearFlag(kCanOverflow); 1862 ClearFlag(kCanOverflow);
1832 } 1863 }
1833 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && 1864 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
1865 !CheckFlag(kAllUsesTruncatingToInt32) &&
1834 a->CanBeMinusZero() && b->CanBeZero()); 1866 a->CanBeMinusZero() && b->CanBeZero());
1835 return res; 1867 return res;
1836 } else { 1868 } else {
1837 return HValue::InferRange(zone); 1869 return HValue::InferRange(zone);
1838 } 1870 }
1839 } 1871 }
1840 1872
1841 1873
1842 Range* HMul::InferRange(Zone* zone) { 1874 Range* HMul::InferRange(Zone* zone) {
1843 if (representation().IsInteger32()) { 1875 Representation r = representation();
1876 if (r.IsSmiOrInteger32()) {
1844 Range* a = left()->range(); 1877 Range* a = left()->range();
1845 Range* b = right()->range(); 1878 Range* b = right()->range();
1846 Range* res = a->Copy(zone); 1879 Range* res = a->Copy(zone);
1847 if (!res->MulAndCheckOverflow(b)) { 1880 if (!res->MulAndCheckOverflow(r, b)) {
1848 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32 1881 // Clearing the kCanOverflow flag when kAllUsesAreTruncatingToInt32
1849 // would be wrong, because truncated integer multiplication is too 1882 // would be wrong, because truncated integer multiplication is too
1850 // precise and therefore not the same as converting to Double and back. 1883 // precise and therefore not the same as converting to Double and back.
1851 ClearFlag(kCanOverflow); 1884 ClearFlag(kCanOverflow);
1852 } 1885 }
1853 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && 1886 res->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToSmi) &&
1887 !CheckFlag(kAllUsesTruncatingToInt32) &&
1854 ((a->CanBeZero() && b->CanBeNegative()) || 1888 ((a->CanBeZero() && b->CanBeNegative()) ||
1855 (a->CanBeNegative() && b->CanBeZero()))); 1889 (a->CanBeNegative() && b->CanBeZero())));
1856 return res; 1890 return res;
1857 } else { 1891 } else {
1858 return HValue::InferRange(zone); 1892 return HValue::InferRange(zone);
1859 } 1893 }
1860 } 1894 }
1861 1895
1862 1896
1863 Range* HDiv::InferRange(Zone* zone) { 1897 Range* HDiv::InferRange(Zone* zone) {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 break; 1996 break;
1963 } 1997 }
1964 } 1998 }
1965 ClearFlag(kNumericConstraintEvaluationInProgress); 1999 ClearFlag(kNumericConstraintEvaluationInProgress);
1966 2000
1967 return result; 2001 return result;
1968 } 2002 }
1969 2003
1970 2004
1971 Range* HMathMinMax::InferRange(Zone* zone) { 2005 Range* HMathMinMax::InferRange(Zone* zone) {
1972 if (representation().IsInteger32()) { 2006 if (representation().IsSmiOrInteger32()) {
1973 Range* a = left()->range(); 2007 Range* a = left()->range();
1974 Range* b = right()->range(); 2008 Range* b = right()->range();
1975 Range* res = a->Copy(zone); 2009 Range* res = a->Copy(zone);
1976 if (operation_ == kMathMax) { 2010 if (operation_ == kMathMax) {
1977 res->CombinedMax(b); 2011 res->CombinedMax(b);
1978 } else { 2012 } else {
1979 ASSERT(operation_ == kMathMin); 2013 ASSERT(operation_ == kMathMin);
1980 res->CombinedMin(b); 2014 res->CombinedMin(b);
1981 } 2015 }
1982 return res; 2016 return res;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2047 ASSERT(block() == NULL); 2081 ASSERT(block() == NULL);
2048 } 2082 }
2049 2083
2050 2084
2051 void HPhi::InitRealUses(int phi_id) { 2085 void HPhi::InitRealUses(int phi_id) {
2052 // Initialize real uses. 2086 // Initialize real uses.
2053 phi_id_ = phi_id; 2087 phi_id_ = phi_id;
2054 // Compute a conservative approximation of truncating uses before inferring 2088 // Compute a conservative approximation of truncating uses before inferring
2055 // representations. The proper, exact computation will be done later, when 2089 // representations. The proper, exact computation will be done later, when
2056 // inserting representation changes. 2090 // inserting representation changes.
2091 SetFlag(kTruncatingToSmi);
2057 SetFlag(kTruncatingToInt32); 2092 SetFlag(kTruncatingToInt32);
2058 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 2093 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
2059 HValue* value = it.value(); 2094 HValue* value = it.value();
2060 if (!value->IsPhi()) { 2095 if (!value->IsPhi()) {
2061 Representation rep = value->observed_input_representation(it.index()); 2096 Representation rep = value->observed_input_representation(it.index());
2062 non_phi_uses_[rep.kind()] += value->LoopWeight(); 2097 non_phi_uses_[rep.kind()] += value->LoopWeight();
2063 if (FLAG_trace_representation) { 2098 if (FLAG_trace_representation) {
2064 PrintF("#%d Phi is used by real #%d %s as %s\n", 2099 PrintF("#%d Phi is used by real #%d %s as %s\n",
2065 id(), value->id(), value->Mnemonic(), rep.Mnemonic()); 2100 id(), value->id(), value->Mnemonic(), rep.Mnemonic());
2066 } 2101 }
2067 if (!value->IsSimulate() && !value->CheckFlag(kTruncatingToInt32)) { 2102 if (!value->IsSimulate()) {
2068 ClearFlag(kTruncatingToInt32); 2103 if (!value->CheckFlag(kTruncatingToSmi)) {
2104 ClearFlag(kTruncatingToSmi);
2105 }
2106 if (!value->CheckFlag(kTruncatingToInt32)) {
2107 ClearFlag(kTruncatingToInt32);
2108 }
2069 } 2109 }
2070 } 2110 }
2071 } 2111 }
2072 } 2112 }
2073 2113
2074 2114
2075 void HPhi::AddNonPhiUsesFrom(HPhi* other) { 2115 void HPhi::AddNonPhiUsesFrom(HPhi* other) {
2076 if (FLAG_trace_representation) { 2116 if (FLAG_trace_representation) {
2077 PrintF("adding to #%d Phi uses of #%d Phi: s%d i%d d%d t%d\n", 2117 PrintF("adding to #%d Phi uses of #%d Phi: s%d i%d d%d t%d\n",
2078 id(), other->id(), 2118 id(), other->id(),
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 boolean_value_(double_value != 0 && !std::isnan(double_value)), 2285 boolean_value_(double_value != 0 && !std::isnan(double_value)),
2246 int32_value_(DoubleToInt32(double_value)), 2286 int32_value_(DoubleToInt32(double_value)),
2247 double_value_(double_value) { 2287 double_value_(double_value) {
2248 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); 2288 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
2249 Initialize(r); 2289 Initialize(r);
2250 } 2290 }
2251 2291
2252 2292
2253 void HConstant::Initialize(Representation r) { 2293 void HConstant::Initialize(Representation r) {
2254 if (r.IsNone()) { 2294 if (r.IsNone()) {
2255 if (has_smi_value_) { 2295 if (has_smi_value_ && kSmiValueSize == 31) {
2256 r = Representation::Smi(); 2296 r = Representation::Smi();
2257 } else if (has_int32_value_) { 2297 } else if (has_int32_value_) {
2258 r = Representation::Integer32(); 2298 r = Representation::Integer32();
2259 } else if (has_double_value_) { 2299 } else if (has_double_value_) {
2260 r = Representation::Double(); 2300 r = Representation::Double();
2261 } else { 2301 } else {
2262 r = Representation::Tagged(); 2302 r = Representation::Tagged();
2263 } 2303 }
2264 } 2304 }
2265 set_representation(r); 2305 set_representation(r);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2352 right()->PrintNameTo(stream); 2392 right()->PrintNameTo(stream);
2353 if (CheckFlag(kCanOverflow)) stream->Add(" !"); 2393 if (CheckFlag(kCanOverflow)) stream->Add(" !");
2354 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); 2394 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
2355 } 2395 }
2356 2396
2357 2397
2358 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { 2398 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) {
2359 ASSERT(CheckFlag(kFlexibleRepresentation)); 2399 ASSERT(CheckFlag(kFlexibleRepresentation));
2360 Representation new_rep = RepresentationFromInputs(); 2400 Representation new_rep = RepresentationFromInputs();
2361 UpdateRepresentation(new_rep, h_infer, "inputs"); 2401 UpdateRepresentation(new_rep, h_infer, "inputs");
2362 // When the operation has information about its own output type, don't look 2402 if (observed_output_representation_.IsNone()) {
2363 // at uses. 2403 new_rep = RepresentationFromUses();
2364 if (!observed_output_representation_.IsNone()) return; 2404 UpdateRepresentation(new_rep, h_infer, "uses");
2365 new_rep = RepresentationFromUses(); 2405 } else {
2366 UpdateRepresentation(new_rep, h_infer, "uses"); 2406 new_rep = RepresentationFromOutput();
2367 new_rep = RepresentationFromUseRequirements(); 2407 UpdateRepresentation(new_rep, h_infer, "output");
2368 if (new_rep.fits_into(Representation::Integer32())) { 2408 }
2369 UpdateRepresentation(new_rep, h_infer, "use requirements"); 2409
2410 if (representation().IsSmi() && HasNonSmiUse()) {
2411 UpdateRepresentation(
2412 Representation::Integer32(), h_infer, "use requirements");
2370 } 2413 }
2371 } 2414 }
2372 2415
2373 2416
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() { 2417 Representation HBinaryOperation::RepresentationFromInputs() {
2385 // Determine the worst case of observed input representations and 2418 // Determine the worst case of observed input representations and
2386 // the currently assumed output representation. 2419 // the currently assumed output representation.
2387 Representation rep = representation(); 2420 Representation rep = representation();
2388 for (int i = 1; i <= 2; ++i) { 2421 for (int i = 1; i <= 2; ++i) {
2389 Representation input_rep = observed_input_representation(i); 2422 rep = rep.generalize(observed_input_representation(i));
2390 if (input_rep.is_more_general_than(rep)) rep = input_rep;
2391 } 2423 }
2392 // If any of the actual input representation is more general than what we 2424 // If any of the actual input representation is more general than what we
2393 // have so far but not Tagged, use that representation instead. 2425 // have so far but not Tagged, use that representation instead.
2394 Representation left_rep = left()->representation(); 2426 Representation left_rep = left()->representation();
2395 Representation right_rep = right()->representation(); 2427 Representation right_rep = right()->representation();
2428 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep);
2429 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep);
2396 2430
2397 if (left_rep.is_more_general_than(rep) && !left_rep.IsTagged()) { 2431 return rep;
2398 rep = left_rep; 2432 }
2399 } 2433
2400 if (right_rep.is_more_general_than(rep) && !right_rep.IsTagged()) { 2434
2401 rep = right_rep; 2435 bool HBinaryOperation::IgnoreObservedOutputRepresentation(
2402 } 2436 Representation current_rep) {
2437 return ((current_rep.IsInteger32() && CheckUsesForFlag(kTruncatingToInt32)) ||
2438 (current_rep.IsSmi() && CheckUsesForFlag(kTruncatingToSmi))) &&
2439 // Mul in Integer32 mode would be too precise.
2440 !this->IsMul();
2441 }
2442
2443
2444 Representation HBinaryOperation::RepresentationFromOutput() {
2445 Representation rep = representation();
2403 // Consider observed output representation, but ignore it if it's Double, 2446 // Consider observed output representation, but ignore it if it's Double,
2404 // this instruction is not a division, and all its uses are truncating 2447 // this instruction is not a division, and all its uses are truncating
2405 // to Integer32. 2448 // to Integer32.
2406 if (observed_output_representation_.is_more_general_than(rep) && 2449 if (observed_output_representation_.is_more_general_than(rep) &&
2407 !IgnoreObservedOutputRepresentation(rep)) { 2450 !IgnoreObservedOutputRepresentation(rep)) {
2408 rep = observed_output_representation_; 2451 return observed_output_representation_;
2409 } 2452 }
2410 return rep; 2453 return Representation::None();
2411 } 2454 }
2412 2455
2413 2456
2414 void HBinaryOperation::AssumeRepresentation(Representation r) { 2457 void HBinaryOperation::AssumeRepresentation(Representation r) {
2415 set_observed_input_representation(1, r); 2458 set_observed_input_representation(1, r);
2416 set_observed_input_representation(2, r); 2459 set_observed_input_representation(2, r);
2417 HValue::AssumeRepresentation(r); 2460 HValue::AssumeRepresentation(r);
2418 } 2461 }
2419 2462
2420 2463
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
3337 3380
3338 3381
3339 HType HFunctionLiteral::CalculateInferredType() { 3382 HType HFunctionLiteral::CalculateInferredType() {
3340 return HType::JSObject(); 3383 return HType::JSObject();
3341 } 3384 }
3342 3385
3343 3386
3344 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( 3387 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero(
3345 BitVector* visited) { 3388 BitVector* visited) {
3346 visited->Add(id()); 3389 visited->Add(id());
3347 if (representation().IsInteger32() && 3390 if (representation().IsSmiOrInteger32() &&
3348 !value()->representation().IsInteger32()) { 3391 !value()->representation().Equals(representation())) {
3349 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { 3392 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) {
3350 SetFlag(kBailoutOnMinusZero); 3393 SetFlag(kBailoutOnMinusZero);
3351 } 3394 }
3352 } 3395 }
3353 if (RequiredInputRepresentation(0).IsInteger32() && 3396 if (RequiredInputRepresentation(0).IsSmiOrInteger32() &&
3354 representation().IsInteger32()) { 3397 representation().Equals(RequiredInputRepresentation(0))) {
3355 return value(); 3398 return value();
3356 } 3399 }
3357 return NULL; 3400 return NULL;
3358 } 3401 }
3359 3402
3360 3403
3361
3362 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { 3404 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) {
3363 visited->Add(id()); 3405 visited->Add(id());
3364 if (from().IsInteger32()) return NULL; 3406 if (from().IsSmiOrInteger32()) return NULL;
3365 if (CanTruncateToInt32()) return NULL; 3407 if (CanTruncateToInt32()) return NULL;
3366 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { 3408 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) {
3367 SetFlag(kBailoutOnMinusZero); 3409 SetFlag(kBailoutOnMinusZero);
3368 } 3410 }
3369 ASSERT(!from().IsInteger32() || !to().IsInteger32()); 3411 ASSERT(!from().IsSmiOrInteger32() || !to().IsSmiOrInteger32());
3370 return NULL; 3412 return NULL;
3371 } 3413 }
3372 3414
3373 3415
3374 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero( 3416 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero(
3375 BitVector* visited) { 3417 BitVector* visited) {
3376 visited->Add(id()); 3418 visited->Add(id());
3377 return value(); 3419 return value();
3378 } 3420 }
3379 3421
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
3446 if (value()->IsConstant()) { 3488 if (value()->IsConstant()) {
3447 return false; 3489 return false;
3448 } 3490 }
3449 3491
3450 if (value()->IsLoadKeyed()) { 3492 if (value()->IsLoadKeyed()) {
3451 return IsExternalFloatOrDoubleElementsKind( 3493 return IsExternalFloatOrDoubleElementsKind(
3452 HLoadKeyed::cast(value())->elements_kind()); 3494 HLoadKeyed::cast(value())->elements_kind());
3453 } 3495 }
3454 3496
3455 if (value()->IsChange()) { 3497 if (value()->IsChange()) {
3456 if (HChange::cast(value())->from().IsInteger32()) { 3498 if (HChange::cast(value())->from().IsSmiOrInteger32()) {
3457 return false; 3499 return false;
3458 } 3500 }
3459 if (HChange::cast(value())->value()->type().IsSmi()) { 3501 if (HChange::cast(value())->value()->type().IsSmi()) {
3460 return false; 3502 return false;
3461 } 3503 }
3462 } 3504 }
3463 return true; 3505 return true;
3464 } 3506 }
3465 3507
3466 3508
3467 #define H_CONSTANT_INT32(val) \ 3509 #define H_CONSTANT_INT(val) \
3468 new(zone) HConstant(static_cast<int32_t>(val), Representation::Integer32()) 3510 new(zone) HConstant(static_cast<int32_t>(val))
3469 #define H_CONSTANT_DOUBLE(val) \ 3511 #define H_CONSTANT_DOUBLE(val) \
3470 new(zone) HConstant(static_cast<double>(val), Representation::Double()) 3512 new(zone) HConstant(static_cast<double>(val), Representation::Double())
3471 3513
3472 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ 3514 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
3473 HInstruction* HInstr::New( \ 3515 HInstruction* HInstr::New( \
3474 Zone* zone, HValue* context, HValue* left, HValue* right) { \ 3516 Zone* zone, HValue* context, HValue* left, HValue* right) { \
3475 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ 3517 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
3476 HConstant* c_left = HConstant::cast(left); \ 3518 HConstant* c_left = HConstant::cast(left); \
3477 HConstant* c_right = HConstant::cast(right); \ 3519 HConstant* c_right = HConstant::cast(right); \
3478 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ 3520 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
3479 double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ 3521 double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \
3480 if (TypeInfo::IsInt32Double(double_res)) { \ 3522 if (TypeInfo::IsInt32Double(double_res)) { \
3481 return H_CONSTANT_INT32(double_res); \ 3523 return H_CONSTANT_INT(double_res); \
3482 } \ 3524 } \
3483 return H_CONSTANT_DOUBLE(double_res); \ 3525 return H_CONSTANT_DOUBLE(double_res); \
3484 } \ 3526 } \
3485 } \ 3527 } \
3486 return new(zone) HInstr(context, left, right); \ 3528 return new(zone) HInstr(context, left, right); \
3487 } 3529 }
3488 3530
3489 3531
3490 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +) 3532 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +)
3491 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *) 3533 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *)
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
3670 int32_t dividend = c_left->Integer32Value(); 3712 int32_t dividend = c_left->Integer32Value();
3671 int32_t divisor = c_right->Integer32Value(); 3713 int32_t divisor = c_right->Integer32Value();
3672 if (dividend == kMinInt && divisor == -1) { 3714 if (dividend == kMinInt && divisor == -1) {
3673 return H_CONSTANT_DOUBLE(-0.0); 3715 return H_CONSTANT_DOUBLE(-0.0);
3674 } 3716 }
3675 if (divisor != 0) { 3717 if (divisor != 0) {
3676 int32_t res = dividend % divisor; 3718 int32_t res = dividend % divisor;
3677 if ((res == 0) && (dividend < 0)) { 3719 if ((res == 0) && (dividend < 0)) {
3678 return H_CONSTANT_DOUBLE(-0.0); 3720 return H_CONSTANT_DOUBLE(-0.0);
3679 } 3721 }
3680 return H_CONSTANT_INT32(res); 3722 return H_CONSTANT_INT(res);
3681 } 3723 }
3682 } 3724 }
3683 } 3725 }
3684 return new(zone) HMod(context, left, right, fixed_right_arg); 3726 return new(zone) HMod(context, left, right, fixed_right_arg);
3685 } 3727 }
3686 3728
3687 3729
3688 HInstruction* HDiv::New( 3730 HInstruction* HDiv::New(
3689 Zone* zone, HValue* context, HValue* left, HValue* right) { 3731 Zone* zone, HValue* context, HValue* left, HValue* right) {
3690 // If left and right are constant values, try to return a constant value. 3732 // If left and right are constant values, try to return a constant value.
3691 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { 3733 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
3692 HConstant* c_left = HConstant::cast(left); 3734 HConstant* c_left = HConstant::cast(left);
3693 HConstant* c_right = HConstant::cast(right); 3735 HConstant* c_right = HConstant::cast(right);
3694 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { 3736 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) {
3695 if (c_right->DoubleValue() != 0) { 3737 if (c_right->DoubleValue() != 0) {
3696 double double_res = c_left->DoubleValue() / c_right->DoubleValue(); 3738 double double_res = c_left->DoubleValue() / c_right->DoubleValue();
3697 if (TypeInfo::IsInt32Double(double_res)) { 3739 if (TypeInfo::IsInt32Double(double_res)) {
3698 return H_CONSTANT_INT32(double_res); 3740 return H_CONSTANT_INT(double_res);
3699 } 3741 }
3700 return H_CONSTANT_DOUBLE(double_res); 3742 return H_CONSTANT_DOUBLE(double_res);
3701 } else { 3743 } else {
3702 int sign = Double(c_left->DoubleValue()).Sign() * 3744 int sign = Double(c_left->DoubleValue()).Sign() *
3703 Double(c_right->DoubleValue()).Sign(); // Right could be -0. 3745 Double(c_right->DoubleValue()).Sign(); // Right could be -0.
3704 return H_CONSTANT_DOUBLE(sign * V8_INFINITY); 3746 return H_CONSTANT_DOUBLE(sign * V8_INFINITY);
3705 } 3747 }
3706 } 3748 }
3707 } 3749 }
3708 return new(zone) HDiv(context, left, right); 3750 return new(zone) HDiv(context, left, right);
(...skipping 16 matching lines...) Expand all
3725 case Token::BIT_AND: 3767 case Token::BIT_AND:
3726 result = v_left & v_right; 3768 result = v_left & v_right;
3727 break; 3769 break;
3728 case Token::BIT_OR: 3770 case Token::BIT_OR:
3729 result = v_left | v_right; 3771 result = v_left | v_right;
3730 break; 3772 break;
3731 default: 3773 default:
3732 result = 0; // Please the compiler. 3774 result = 0; // Please the compiler.
3733 UNREACHABLE(); 3775 UNREACHABLE();
3734 } 3776 }
3735 return H_CONSTANT_INT32(result); 3777 return H_CONSTANT_INT(result);
3736 } 3778 }
3737 } 3779 }
3738 return new(zone) HBitwise(op, context, left, right); 3780 return new(zone) HBitwise(op, context, left, right);
3739 } 3781 }
3740 3782
3741 3783
3742 #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \ 3784 #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \
3743 HInstruction* HInstr::New( \ 3785 HInstruction* HInstr::New( \
3744 Zone* zone, HValue* context, HValue* left, HValue* right) { \ 3786 Zone* zone, HValue* context, HValue* left, HValue* right) { \
3745 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ 3787 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
3746 HConstant* c_left = HConstant::cast(left); \ 3788 HConstant* c_left = HConstant::cast(left); \
3747 HConstant* c_right = HConstant::cast(right); \ 3789 HConstant* c_right = HConstant::cast(right); \
3748 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ 3790 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
3749 return H_CONSTANT_INT32(result); \ 3791 return H_CONSTANT_INT(result); \
3750 } \ 3792 } \
3751 } \ 3793 } \
3752 return new(zone) HInstr(context, left, right); \ 3794 return new(zone) HInstr(context, left, right); \
3753 } 3795 }
3754 3796
3755 3797
3756 DEFINE_NEW_H_BITWISE_INSTR(HSar, 3798 DEFINE_NEW_H_BITWISE_INSTR(HSar,
3757 c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f)) 3799 c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f))
3758 DEFINE_NEW_H_BITWISE_INSTR(HShl, 3800 DEFINE_NEW_H_BITWISE_INSTR(HShl,
3759 c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f)) 3801 c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f))
3760 3802
3761 #undef DEFINE_NEW_H_BITWISE_INSTR 3803 #undef DEFINE_NEW_H_BITWISE_INSTR
3762 3804
3763 3805
3764 HInstruction* HShr::New( 3806 HInstruction* HShr::New(
3765 Zone* zone, HValue* context, HValue* left, HValue* right) { 3807 Zone* zone, HValue* context, HValue* left, HValue* right) {
3766 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { 3808 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
3767 HConstant* c_left = HConstant::cast(left); 3809 HConstant* c_left = HConstant::cast(left);
3768 HConstant* c_right = HConstant::cast(right); 3810 HConstant* c_right = HConstant::cast(right);
3769 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { 3811 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) {
3770 int32_t left_val = c_left->NumberValueAsInteger32(); 3812 int32_t left_val = c_left->NumberValueAsInteger32();
3771 int32_t right_val = c_right->NumberValueAsInteger32() & 0x1f; 3813 int32_t right_val = c_right->NumberValueAsInteger32() & 0x1f;
3772 if ((right_val == 0) && (left_val < 0)) { 3814 if ((right_val == 0) && (left_val < 0)) {
3773 return H_CONSTANT_DOUBLE(static_cast<uint32_t>(left_val)); 3815 return H_CONSTANT_DOUBLE(static_cast<uint32_t>(left_val));
3774 } 3816 }
3775 return H_CONSTANT_INT32(static_cast<uint32_t>(left_val) >> right_val); 3817 return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val);
3776 } 3818 }
3777 } 3819 }
3778 return new(zone) HShr(context, left, right); 3820 return new(zone) HShr(context, left, right);
3779 } 3821 }
3780 3822
3781 3823
3782 #undef H_CONSTANT_INT32 3824 #undef H_CONSTANT_INT
3783 #undef H_CONSTANT_DOUBLE 3825 #undef H_CONSTANT_DOUBLE
3784 3826
3785 3827
3786 void HBitwise::PrintDataTo(StringStream* stream) { 3828 void HBitwise::PrintDataTo(StringStream* stream) {
3787 stream->Add(Token::Name(op_)); 3829 stream->Add(Token::Name(op_));
3788 stream->Add(" "); 3830 stream->Add(" ");
3789 HBitwiseBinaryOperation::PrintDataTo(stream); 3831 HBitwiseBinaryOperation::PrintDataTo(stream);
3790 } 3832 }
3791 3833
3792 3834
3793 void HPhi::SimplifyConstantInputs() { 3835 void HPhi::SimplifyConstantInputs() {
3794 // Convert constant inputs to integers when all uses are truncating. 3836 // Convert constant inputs to integers when all uses are truncating.
3795 // This must happen before representation inference takes place. 3837 // This must happen before representation inference takes place.
3796 if (!CheckUsesForFlag(kTruncatingToInt32)) return; 3838 if (!CheckUsesForFlag(kTruncatingToInt32)) return;
3797 for (int i = 0; i < OperandCount(); ++i) { 3839 for (int i = 0; i < OperandCount(); ++i) {
3798 if (!OperandAt(i)->IsConstant()) return; 3840 if (!OperandAt(i)->IsConstant()) return;
3799 } 3841 }
3800 HGraph* graph = block()->graph(); 3842 HGraph* graph = block()->graph();
3801 for (int i = 0; i < OperandCount(); ++i) { 3843 for (int i = 0; i < OperandCount(); ++i) {
3802 HConstant* operand = HConstant::cast(OperandAt(i)); 3844 HConstant* operand = HConstant::cast(OperandAt(i));
3803 if (operand->HasInteger32Value()) { 3845 if (operand->HasInteger32Value()) {
3804 continue; 3846 continue;
3805 } else if (operand->HasDoubleValue()) { 3847 } else if (operand->HasDoubleValue()) {
3806 HConstant* integer_input = 3848 HConstant* integer_input =
3807 new(graph->zone()) HConstant(DoubleToInt32(operand->DoubleValue()), 3849 new(graph->zone()) HConstant(DoubleToInt32(operand->DoubleValue()));
3808 Representation::Integer32());
3809 integer_input->InsertAfter(operand); 3850 integer_input->InsertAfter(operand);
3810 SetOperandAt(i, integer_input); 3851 SetOperandAt(i, integer_input);
3811 } else if (operand == graph->GetConstantTrue()) { 3852 } else if (operand == graph->GetConstantTrue()) {
3812 SetOperandAt(i, graph->GetConstant1()); 3853 SetOperandAt(i, graph->GetConstant1());
3813 } else { 3854 } else {
3814 // This catches |false|, |undefined|, strings and objects. 3855 // This catches |false|, |undefined|, strings and objects.
3815 SetOperandAt(i, graph->GetConstant0()); 3856 SetOperandAt(i, graph->GetConstant0());
3816 } 3857 }
3817 } 3858 }
3818 // Overwrite observed input representations because they are likely Tagged. 3859 // Overwrite observed input representations because they are likely Tagged.
3819 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 3860 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
3820 HValue* use = it.value(); 3861 HValue* use = it.value();
3821 if (use->IsBinaryOperation()) { 3862 if (use->IsBinaryOperation()) {
3822 HBinaryOperation::cast(use)->set_observed_input_representation( 3863 HBinaryOperation::cast(use)->set_observed_input_representation(
3823 it.index(), Representation::Integer32()); 3864 it.index(), Representation::Smi());
3824 } 3865 }
3825 } 3866 }
3826 } 3867 }
3827 3868
3828 3869
3829 void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) { 3870 void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) {
3830 ASSERT(CheckFlag(kFlexibleRepresentation)); 3871 ASSERT(CheckFlag(kFlexibleRepresentation));
3831 Representation new_rep = RepresentationFromInputs(); 3872 Representation new_rep = RepresentationFromInputs();
3832 UpdateRepresentation(new_rep, h_infer, "inputs"); 3873 UpdateRepresentation(new_rep, h_infer, "inputs");
3833 new_rep = RepresentationFromUses(); 3874 new_rep = RepresentationFromUses();
(...skipping 28 matching lines...) Expand all
3862 if (rep.generalize(use_rep).IsInteger32()) { 3903 if (rep.generalize(use_rep).IsInteger32()) {
3863 rep = Representation::Integer32(); 3904 rep = Representation::Integer32();
3864 continue; 3905 continue;
3865 } 3906 }
3866 return Representation::None(); 3907 return Representation::None();
3867 } 3908 }
3868 return rep; 3909 return rep;
3869 } 3910 }
3870 3911
3871 3912
3913 bool HValue::HasNonSmiUse() {
3914 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
3915 // We check for observed_input_representation elsewhere.
3916 Representation use_rep =
3917 it.value()->RequiredInputRepresentation(it.index());
3918 if (!use_rep.IsNone() && !use_rep.IsSmi()) return true;
3919 }
3920 return false;
3921 }
3922
3923
3872 // Node-specific verification code is only included in debug mode. 3924 // Node-specific verification code is only included in debug mode.
3873 #ifdef DEBUG 3925 #ifdef DEBUG
3874 3926
3875 void HPhi::Verify() { 3927 void HPhi::Verify() {
3876 ASSERT(OperandCount() == block()->predecessors()->length()); 3928 ASSERT(OperandCount() == block()->predecessors()->length());
3877 for (int i = 0; i < OperandCount(); ++i) { 3929 for (int i = 0; i < OperandCount(); ++i) {
3878 HValue* value = OperandAt(i); 3930 HValue* value = OperandAt(i);
3879 HBasicBlock* defining_block = value->block(); 3931 HBasicBlock* defining_block = value->block();
3880 HBasicBlock* predecessor_block = block()->predecessors()->at(i); 3932 HBasicBlock* predecessor_block = block()->predecessors()->at(i);
3881 ASSERT(defining_block == predecessor_block || 3933 ASSERT(defining_block == predecessor_block ||
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
4040 case kBackingStore: 4092 case kBackingStore:
4041 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); 4093 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
4042 stream->Add("[backing-store]"); 4094 stream->Add("[backing-store]");
4043 break; 4095 break;
4044 } 4096 }
4045 4097
4046 stream->Add("@%d", offset()); 4098 stream->Add("@%d", offset());
4047 } 4099 }
4048 4100
4049 } } // namespace v8::internal 4101 } } // 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