OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |