Chromium Code Reviews| 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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 } | 247 } |
| 248 | 248 |
| 249 | 249 |
| 250 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { | 250 HValue* RangeEvaluationContext::ConvertGuarantee(HValue* guarantee) { |
| 251 return guarantee->IsBoundsCheckBaseIndexInformation() | 251 return guarantee->IsBoundsCheckBaseIndexInformation() |
| 252 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check() | 252 ? HBoundsCheckBaseIndexInformation::cast(guarantee)->bounds_check() |
| 253 : guarantee; | 253 : guarantee; |
| 254 } | 254 } |
| 255 | 255 |
| 256 | 256 |
| 257 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { | 257 static int32_t ConvertAndSetOverflow(Representation r, |
| 258 if (result > kMaxInt) { | 258 int64_t result, |
| 259 *overflow = true; | 259 bool* overflow) { |
| 260 return kMaxInt; | 260 if (r.IsSmi()) { |
| 261 } | 261 if (result > Smi::kMaxValue) { |
| 262 if (result < kMinInt) { | 262 *overflow = true; |
| 263 *overflow = true; | 263 return Smi::kMaxValue; |
| 264 return kMinInt; | 264 } |
| 265 if (result < Smi::kMinValue) { | |
| 266 *overflow = true; | |
| 267 return Smi::kMinValue; | |
| 268 } | |
| 269 } else { | |
| 270 if (result > kMaxInt) { | |
| 271 *overflow = true; | |
| 272 return kMaxInt; | |
| 273 } | |
| 274 if (result < kMinInt) { | |
| 275 *overflow = true; | |
| 276 return kMinInt; | |
| 277 } | |
| 265 } | 278 } |
| 266 return static_cast<int32_t>(result); | 279 return static_cast<int32_t>(result); |
| 267 } | 280 } |
| 268 | 281 |
| 269 | 282 |
| 270 static int32_t AddWithoutOverflow(int32_t a, int32_t b, bool* overflow) { | 283 static int32_t AddWithoutOverflow(Representation r, |
| 284 int32_t a, | |
| 285 int32_t b, | |
| 286 bool* overflow) { | |
| 271 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b); | 287 int64_t result = static_cast<int64_t>(a) + static_cast<int64_t>(b); |
| 272 return ConvertAndSetOverflow(result, overflow); | 288 return ConvertAndSetOverflow(r, result, overflow); |
| 273 } | 289 } |
| 274 | 290 |
| 275 | 291 |
| 276 static int32_t SubWithoutOverflow(int32_t a, int32_t b, bool* overflow) { | 292 static int32_t SubWithoutOverflow(Representation r, |
| 293 int32_t a, | |
| 294 int32_t b, | |
| 295 bool* overflow) { | |
| 277 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b); | 296 int64_t result = static_cast<int64_t>(a) - static_cast<int64_t>(b); |
| 278 return ConvertAndSetOverflow(result, overflow); | 297 return ConvertAndSetOverflow(r, result, overflow); |
| 279 } | 298 } |
| 280 | 299 |
| 281 | 300 |
| 282 static int32_t MulWithoutOverflow(int32_t a, int32_t b, bool* overflow) { | 301 static int32_t MulWithoutOverflow(Representation r, |
| 302 int32_t a, | |
| 303 int32_t b, | |
| 304 bool* overflow) { | |
| 283 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); | 305 int64_t result = static_cast<int64_t>(a) * static_cast<int64_t>(b); |
| 284 return ConvertAndSetOverflow(result, overflow); | 306 return ConvertAndSetOverflow(r, result, overflow); |
| 285 } | 307 } |
| 286 | 308 |
| 287 | 309 |
| 288 int32_t Range::Mask() const { | 310 int32_t Range::Mask() const { |
| 289 if (lower_ == upper_) return lower_; | 311 if (lower_ == upper_) return lower_; |
| 290 if (lower_ >= 0) { | 312 if (lower_ >= 0) { |
| 291 int32_t res = 1; | 313 int32_t res = 1; |
| 292 while (res < upper_) { | 314 while (res < upper_) { |
| 293 res = (res << 1) | 1; | 315 res = (res << 1) | 1; |
| 294 } | 316 } |
| 295 return res; | 317 return res; |
| 296 } | 318 } |
| 297 return 0xffffffff; | 319 return 0xffffffff; |
| 298 } | 320 } |
| 299 | 321 |
| 300 | 322 |
| 301 void Range::AddConstant(int32_t value) { | 323 void Range::AddConstant(int32_t value) { |
| 302 if (value == 0) return; | 324 if (value == 0) return; |
| 303 bool may_overflow = false; // Overflow is ignored here. | 325 bool may_overflow = false; // Overflow is ignored here. |
| 304 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); | 326 Representation r = Representation::Integer32(); |
| 305 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); | 327 lower_ = AddWithoutOverflow(r, lower_, value, &may_overflow); |
| 328 upper_ = AddWithoutOverflow(r, upper_, value, &may_overflow); | |
| 306 #ifdef DEBUG | 329 #ifdef DEBUG |
| 307 Verify(); | 330 Verify(); |
| 308 #endif | 331 #endif |
| 309 } | 332 } |
| 310 | 333 |
| 311 | 334 |
| 312 void Range::Intersect(Range* other) { | 335 void Range::Intersect(Range* other) { |
| 313 upper_ = Min(upper_, other->upper_); | 336 upper_ = Min(upper_, other->upper_); |
| 314 lower_ = Max(lower_, other->lower_); | 337 lower_ = Max(lower_, other->lower_); |
| 315 bool b = CanBeMinusZero() && other->CanBeMinusZero(); | 338 bool b = CanBeMinusZero() && other->CanBeMinusZero(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 lower_ = lower_ << bits; | 377 lower_ = lower_ << bits; |
| 355 upper_ = upper_ << bits; | 378 upper_ = upper_ << bits; |
| 356 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) { | 379 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) { |
| 357 upper_ = kMaxInt; | 380 upper_ = kMaxInt; |
| 358 lower_ = kMinInt; | 381 lower_ = kMinInt; |
| 359 } | 382 } |
| 360 set_can_be_minus_zero(false); | 383 set_can_be_minus_zero(false); |
| 361 } | 384 } |
| 362 | 385 |
| 363 | 386 |
| 364 bool Range::AddAndCheckOverflow(Range* other) { | 387 bool Range::AddAndCheckOverflow(const Representation& r, Range* other) { |
| 365 bool may_overflow = false; | 388 bool may_overflow = false; |
| 366 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); | 389 lower_ = AddWithoutOverflow(r, lower_, other->lower(), &may_overflow); |
| 367 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); | 390 upper_ = AddWithoutOverflow(r, upper_, other->upper(), &may_overflow); |
| 368 KeepOrder(); | 391 KeepOrder(); |
| 369 #ifdef DEBUG | 392 #ifdef DEBUG |
| 370 Verify(); | 393 Verify(); |
| 371 #endif | 394 #endif |
| 372 return may_overflow; | 395 return may_overflow; |
| 373 } | 396 } |
| 374 | 397 |
| 375 | 398 |
| 376 bool Range::SubAndCheckOverflow(Range* other) { | 399 bool Range::SubAndCheckOverflow(const Representation& r, Range* other) { |
| 377 bool may_overflow = false; | 400 bool may_overflow = false; |
| 378 lower_ = SubWithoutOverflow(lower_, other->upper(), &may_overflow); | 401 lower_ = SubWithoutOverflow(r, lower_, other->upper(), &may_overflow); |
| 379 upper_ = SubWithoutOverflow(upper_, other->lower(), &may_overflow); | 402 upper_ = SubWithoutOverflow(r, upper_, other->lower(), &may_overflow); |
| 380 KeepOrder(); | 403 KeepOrder(); |
| 381 #ifdef DEBUG | 404 #ifdef DEBUG |
| 382 Verify(); | 405 Verify(); |
| 383 #endif | 406 #endif |
| 384 return may_overflow; | 407 return may_overflow; |
| 385 } | 408 } |
| 386 | 409 |
| 387 | 410 |
| 388 void Range::KeepOrder() { | 411 void Range::KeepOrder() { |
| 389 if (lower_ > upper_) { | 412 if (lower_ > upper_) { |
| 390 int32_t tmp = lower_; | 413 int32_t tmp = lower_; |
| 391 lower_ = upper_; | 414 lower_ = upper_; |
| 392 upper_ = tmp; | 415 upper_ = tmp; |
| 393 } | 416 } |
| 394 } | 417 } |
| 395 | 418 |
| 396 | 419 |
| 397 #ifdef DEBUG | 420 #ifdef DEBUG |
| 398 void Range::Verify() const { | 421 void Range::Verify() const { |
| 399 ASSERT(lower_ <= upper_); | 422 ASSERT(lower_ <= upper_); |
| 400 } | 423 } |
| 401 #endif | 424 #endif |
| 402 | 425 |
| 403 | 426 |
| 404 bool Range::MulAndCheckOverflow(Range* other) { | 427 bool Range::MulAndCheckOverflow(const Representation& r, Range* other) { |
| 405 bool may_overflow = false; | 428 bool may_overflow = false; |
| 406 int v1 = MulWithoutOverflow(lower_, other->lower(), &may_overflow); | 429 int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow); |
| 407 int v2 = MulWithoutOverflow(lower_, other->upper(), &may_overflow); | 430 int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow); |
| 408 int v3 = MulWithoutOverflow(upper_, other->lower(), &may_overflow); | 431 int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow); |
| 409 int v4 = MulWithoutOverflow(upper_, other->upper(), &may_overflow); | 432 int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow); |
| 410 lower_ = Min(Min(v1, v2), Min(v3, v4)); | 433 lower_ = Min(Min(v1, v2), Min(v3, v4)); |
| 411 upper_ = Max(Max(v1, v2), Max(v3, v4)); | 434 upper_ = Max(Max(v1, v2), Max(v3, v4)); |
| 412 #ifdef DEBUG | 435 #ifdef DEBUG |
| 413 Verify(); | 436 Verify(); |
| 414 #endif | 437 #endif |
| 415 return may_overflow; | 438 return may_overflow; |
| 416 } | 439 } |
| 417 | 440 |
| 418 | 441 |
| 419 const char* HType::ToString() { | 442 const char* HType::ToString() { |
| (...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1364 | 1387 |
| 1365 | 1388 |
| 1366 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { | 1389 void HLoadFieldByIndex::PrintDataTo(StringStream* stream) { |
| 1367 object()->PrintNameTo(stream); | 1390 object()->PrintNameTo(stream); |
| 1368 stream->Add(" "); | 1391 stream->Add(" "); |
| 1369 index()->PrintNameTo(stream); | 1392 index()->PrintNameTo(stream); |
| 1370 } | 1393 } |
| 1371 | 1394 |
| 1372 | 1395 |
| 1373 HValue* HBitwise::Canonicalize() { | 1396 HValue* HBitwise::Canonicalize() { |
| 1374 if (!representation().IsInteger32()) return this; | 1397 if (!representation().IsSmiOrInteger32()) return this; |
| 1375 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. | 1398 // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x. |
| 1376 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; | 1399 int32_t nop_constant = (op() == Token::BIT_AND) ? -1 : 0; |
| 1377 if (left()->EqualsInteger32Constant(nop_constant) && | 1400 if (left()->EqualsInteger32Constant(nop_constant) && |
| 1378 !right()->CheckFlag(kUint32)) { | 1401 !right()->CheckFlag(kUint32)) { |
| 1379 return right(); | 1402 return right(); |
| 1380 } | 1403 } |
| 1381 if (right()->EqualsInteger32Constant(nop_constant) && | 1404 if (right()->EqualsInteger32Constant(nop_constant) && |
| 1382 !left()->CheckFlag(kUint32)) { | 1405 !left()->CheckFlag(kUint32)) { |
| 1383 return left(); | 1406 return left(); |
| 1384 } | 1407 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1473 stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic()); | 1496 stream->Add(" %s to %s", from().Mnemonic(), to().Mnemonic()); |
| 1474 | 1497 |
| 1475 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); | 1498 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); |
| 1476 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 1499 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
| 1477 if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan"); | 1500 if (CheckFlag(kAllowUndefinedAsNaN)) stream->Add(" allow-undefined-as-nan"); |
| 1478 } | 1501 } |
| 1479 | 1502 |
| 1480 | 1503 |
| 1481 HValue* HUnaryMathOperation::Canonicalize() { | 1504 HValue* HUnaryMathOperation::Canonicalize() { |
| 1482 if (op() == kMathFloor) { | 1505 if (op() == kMathFloor) { |
| 1483 // If the input is integer32 then we replace the floor instruction | 1506 // If the input is smi or integer32 then we replace the floor instruction |
| 1484 // with its input. This happens before the representation changes are | 1507 // with its input. This happens before the representation changes are |
| 1485 // introduced. | 1508 // introduced. |
| 1486 if (value()->representation().IsInteger32()) return value(); | 1509 if (value()->representation().IsSmiOrInteger32()) return value(); |
| 1487 | 1510 |
| 1488 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \ | 1511 #if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_IA32) || \ |
| 1489 defined(V8_TARGET_ARCH_X64) | 1512 defined(V8_TARGET_ARCH_X64) |
| 1490 if (value()->IsDiv() && (value()->UseCount() == 1)) { | 1513 if (value()->IsDiv() && (value()->UseCount() == 1)) { |
| 1491 // TODO(2038): Implement this optimization for non ARM architectures. | 1514 // TODO(2038): Implement this optimization for non ARM architectures. |
| 1492 HDiv* hdiv = HDiv::cast(value()); | 1515 HDiv* hdiv = HDiv::cast(value()); |
| 1493 HValue* left = hdiv->left(); | 1516 HValue* left = hdiv->left(); |
| 1494 HValue* right = hdiv->right(); | 1517 HValue* right = hdiv->right(); |
| 1495 // Try to simplify left and right values of the division. | 1518 // Try to simplify left and right values of the division. |
| 1496 HValue* new_left = | 1519 HValue* new_left = |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1654 left()->PrintNameTo(stream); | 1677 left()->PrintNameTo(stream); |
| 1655 stream->Add(" "); | 1678 stream->Add(" "); |
| 1656 right()->PrintNameTo(stream); | 1679 right()->PrintNameTo(stream); |
| 1657 stream->Add(" "); | 1680 stream->Add(" "); |
| 1658 context()->PrintNameTo(stream); | 1681 context()->PrintNameTo(stream); |
| 1659 } | 1682 } |
| 1660 | 1683 |
| 1661 | 1684 |
| 1662 Range* HValue::InferRange(Zone* zone) { | 1685 Range* HValue::InferRange(Zone* zone) { |
| 1663 Range* result; | 1686 Range* result; |
| 1664 if (type().IsSmi()) { | 1687 if (representation().IsSmi() || type().IsSmi()) { |
| 1665 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); | 1688 result = new(zone) Range(Smi::kMinValue, Smi::kMaxValue); |
| 1666 result->set_can_be_minus_zero(false); | 1689 result->set_can_be_minus_zero(false); |
| 1667 } else { | 1690 } else { |
| 1668 // Untagged integer32 cannot be -0, all other representations can. | 1691 // Untagged integer32 cannot be -0, all other representations can. |
| 1669 result = new(zone) Range(); | 1692 result = new(zone) Range(); |
| 1670 result->set_can_be_minus_zero(!representation().IsInteger32()); | 1693 result->set_can_be_minus_zero(!representation().IsInteger32()); |
| 1671 } | 1694 } |
| 1672 return result; | 1695 return result; |
| 1673 } | 1696 } |
| 1674 | 1697 |
| 1675 | 1698 |
| 1676 Range* HChange::InferRange(Zone* zone) { | 1699 Range* HChange::InferRange(Zone* zone) { |
| 1677 Range* input_range = value()->range(); | 1700 Range* input_range = value()->range(); |
| 1678 if (from().IsInteger32() && | 1701 if (from().IsInteger32() && |
| 1679 to().IsSmiOrTagged() && | 1702 to().IsSmiOrTagged() && |
| 1680 !value()->CheckFlag(HInstruction::kUint32) && | 1703 !value()->CheckFlag(HInstruction::kUint32) && |
| 1681 input_range != NULL && input_range->IsInSmiRange()) { | 1704 input_range != NULL && input_range->IsInSmiRange()) { |
| 1682 set_type(HType::Smi()); | 1705 set_type(HType::Smi()); |
| 1683 ClearGVNFlag(kChangesNewSpacePromotion); | 1706 ClearGVNFlag(kChangesNewSpacePromotion); |
| 1684 } | 1707 } |
| 1685 Range* result = (input_range != NULL) | 1708 Range* result = (input_range != NULL) |
| 1686 ? input_range->Copy(zone) | 1709 ? input_range->Copy(zone) |
| 1687 : HValue::InferRange(zone); | 1710 : HValue::InferRange(zone); |
| 1688 if (to().IsInteger32()) result->set_can_be_minus_zero(false); | 1711 if (to().IsSmiOrInteger32()) result->set_can_be_minus_zero(false); |
| 1689 return result; | 1712 return result; |
| 1690 } | 1713 } |
| 1691 | 1714 |
| 1692 | 1715 |
| 1693 Range* HConstant::InferRange(Zone* zone) { | 1716 Range* HConstant::InferRange(Zone* zone) { |
| 1694 if (has_int32_value_) { | 1717 if (has_int32_value_) { |
| 1695 Range* result = new(zone) Range(int32_value_, int32_value_); | 1718 Range* result = new(zone) Range(int32_value_, int32_value_); |
| 1696 result->set_can_be_minus_zero(false); | 1719 result->set_can_be_minus_zero(false); |
| 1697 return result; | 1720 return result; |
| 1698 } | 1721 } |
| 1699 return HValue::InferRange(zone); | 1722 return HValue::InferRange(zone); |
| 1700 } | 1723 } |
| 1701 | 1724 |
| 1702 | 1725 |
| 1703 Range* HPhi::InferRange(Zone* zone) { | 1726 Range* HPhi::InferRange(Zone* zone) { |
| 1704 if (representation().IsInteger32()) { | 1727 Representation r = representation(); |
| 1728 if (r.IsSmiOrInteger32()) { | |
| 1705 if (block()->IsLoopHeader()) { | 1729 if (block()->IsLoopHeader()) { |
| 1706 Range* range = new(zone) Range(kMinInt, kMaxInt); | 1730 Range* range = r.IsSmi() |
| 1731 ? new(zone) Range(Smi::kMinValue, Smi::kMaxValue) | |
| 1732 : new(zone) Range(kMinInt, kMaxInt); | |
| 1707 return range; | 1733 return range; |
| 1708 } else { | 1734 } else { |
| 1709 Range* range = OperandAt(0)->range()->Copy(zone); | 1735 Range* range = OperandAt(0)->range()->Copy(zone); |
| 1710 for (int i = 1; i < OperandCount(); ++i) { | 1736 for (int i = 1; i < OperandCount(); ++i) { |
| 1711 range->Union(OperandAt(i)->range()); | 1737 range->Union(OperandAt(i)->range()); |
| 1712 } | 1738 } |
| 1713 return range; | 1739 return range; |
| 1714 } | 1740 } |
| 1715 } else { | 1741 } else { |
| 1716 return HValue::InferRange(zone); | 1742 return HValue::InferRange(zone); |
| 1717 } | 1743 } |
| 1718 } | 1744 } |
| 1719 | 1745 |
| 1720 | 1746 |
| 1721 Range* HAdd::InferRange(Zone* zone) { | 1747 Range* HAdd::InferRange(Zone* zone) { |
| 1722 if (representation().IsInteger32()) { | 1748 Representation r = representation(); |
| 1749 if (r.IsSmiOrInteger32()) { | |
| 1723 Range* a = left()->range(); | 1750 Range* a = left()->range(); |
| 1724 Range* b = right()->range(); | 1751 Range* b = right()->range(); |
| 1725 Range* res = a->Copy(zone); | 1752 Range* res = a->Copy(zone); |
| 1726 if (!res->AddAndCheckOverflow(b)) { | 1753 if (!res->AddAndCheckOverflow(r, b)) { |
| 1727 ClearFlag(kCanOverflow); | 1754 ClearFlag(kCanOverflow); |
| 1728 } | 1755 } |
| 1729 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); | 1756 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); |
| 1730 res->set_can_be_minus_zero(m0); | 1757 res->set_can_be_minus_zero(m0); |
| 1731 return res; | 1758 return res; |
| 1732 } else { | 1759 } else { |
| 1733 return HValue::InferRange(zone); | 1760 return HValue::InferRange(zone); |
| 1734 } | 1761 } |
| 1735 } | 1762 } |
| 1736 | 1763 |
| 1737 | 1764 |
| 1738 Range* HSub::InferRange(Zone* zone) { | 1765 Range* HSub::InferRange(Zone* zone) { |
| 1739 if (representation().IsInteger32()) { | 1766 Representation r = representation(); |
| 1767 if (r.IsSmiOrInteger32()) { | |
| 1740 Range* a = left()->range(); | 1768 Range* a = left()->range(); |
| 1741 Range* b = right()->range(); | 1769 Range* b = right()->range(); |
| 1742 Range* res = a->Copy(zone); | 1770 Range* res = a->Copy(zone); |
| 1743 if (!res->SubAndCheckOverflow(b)) { | 1771 if (!res->SubAndCheckOverflow(r, b)) { |
| 1744 ClearFlag(kCanOverflow); | 1772 ClearFlag(kCanOverflow); |
| 1745 } | 1773 } |
| 1746 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); | 1774 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); |
| 1747 return res; | 1775 return res; |
| 1748 } else { | 1776 } else { |
| 1749 return HValue::InferRange(zone); | 1777 return HValue::InferRange(zone); |
| 1750 } | 1778 } |
| 1751 } | 1779 } |
| 1752 | 1780 |
| 1753 | 1781 |
| 1754 Range* HMul::InferRange(Zone* zone) { | 1782 Range* HMul::InferRange(Zone* zone) { |
| 1755 if (representation().IsInteger32()) { | 1783 Representation r = representation(); |
| 1784 if (r.IsSmiOrInteger32()) { | |
| 1756 Range* a = left()->range(); | 1785 Range* a = left()->range(); |
| 1757 Range* b = right()->range(); | 1786 Range* b = right()->range(); |
| 1758 Range* res = a->Copy(zone); | 1787 Range* res = a->Copy(zone); |
| 1759 if (!res->MulAndCheckOverflow(b)) { | 1788 if (!res->MulAndCheckOverflow(r, b)) { |
| 1760 ClearFlag(kCanOverflow); | 1789 ClearFlag(kCanOverflow); |
| 1761 } | 1790 } |
| 1762 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || | 1791 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || |
| 1763 (a->CanBeNegative() && b->CanBeZero()); | 1792 (a->CanBeNegative() && b->CanBeZero()); |
| 1764 res->set_can_be_minus_zero(m0); | 1793 res->set_can_be_minus_zero(m0); |
| 1765 return res; | 1794 return res; |
| 1766 } else { | 1795 } else { |
| 1767 return HValue::InferRange(zone); | 1796 return HValue::InferRange(zone); |
| 1768 } | 1797 } |
| 1769 } | 1798 } |
| 1770 | 1799 |
| 1771 | 1800 |
| 1772 Range* HDiv::InferRange(Zone* zone) { | 1801 Range* HDiv::InferRange(Zone* zone) { |
| 1773 if (representation().IsInteger32()) { | 1802 Representation r = representation(); |
| 1803 if (r.IsSmiOrInteger32()) { | |
| 1774 Range* a = left()->range(); | 1804 Range* a = left()->range(); |
| 1775 Range* b = right()->range(); | 1805 Range* b = right()->range(); |
| 1776 Range* result = new(zone) Range(); | 1806 Range* result = new(zone) Range(); |
| 1777 if (a->CanBeMinusZero()) { | 1807 if (a->CanBeMinusZero()) { |
| 1778 result->set_can_be_minus_zero(true); | 1808 result->set_can_be_minus_zero(true); |
| 1779 } | 1809 } |
| 1780 | 1810 |
| 1781 if (a->CanBeZero() && b->CanBeNegative()) { | 1811 if (a->CanBeZero() && b->CanBeNegative()) { |
| 1782 result->set_can_be_minus_zero(true); | 1812 result->set_can_be_minus_zero(true); |
| 1783 } | 1813 } |
| 1784 | 1814 |
| 1785 if (!a->Includes(kMinInt) || !b->Includes(-1)) { | 1815 if (!b->Includes(-1) || |
| 1816 (r.IsSmi() && !a->Includes(Smi::kMinValue)) || | |
| 1817 (r.IsInteger32() && !a->Includes(kMinInt))) { | |
| 1786 ClearFlag(HValue::kCanOverflow); | 1818 ClearFlag(HValue::kCanOverflow); |
| 1787 } | 1819 } |
| 1788 | 1820 |
| 1789 if (!b->CanBeZero()) { | 1821 if (!b->CanBeZero()) { |
| 1790 ClearFlag(HValue::kCanBeDivByZero); | 1822 ClearFlag(HValue::kCanBeDivByZero); |
| 1791 } | 1823 } |
| 1792 return result; | 1824 return result; |
| 1793 } else { | 1825 } else { |
| 1794 return HValue::InferRange(zone); | 1826 return HValue::InferRange(zone); |
| 1795 } | 1827 } |
| 1796 } | 1828 } |
| 1797 | 1829 |
| 1798 | 1830 |
| 1799 Range* HMod::InferRange(Zone* zone) { | 1831 Range* HMod::InferRange(Zone* zone) { |
| 1800 if (representation().IsInteger32()) { | 1832 Representation r = representation(); |
| 1833 if (r.IsSmiOrInteger32()) { | |
| 1801 Range* a = left()->range(); | 1834 Range* a = left()->range(); |
| 1802 Range* b = right()->range(); | 1835 Range* b = right()->range(); |
| 1803 | 1836 |
| 1804 // The magnitude of the modulus is bounded by the right operand. Note that | 1837 // The magnitude of the modulus is bounded by the right operand. Note that |
| 1805 // apart for the cases involving kMinInt, the calculation below is the same | 1838 // apart for the cases involving kMinInt, the calculation below is the same |
| 1806 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. | 1839 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. |
| 1807 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); | 1840 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); |
| 1808 | 1841 |
| 1809 // The result of the modulo operation has the sign of its left operand. | 1842 // The result of the modulo operation has the sign of its left operand. |
| 1810 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); | 1843 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); |
| 1811 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, | 1844 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, |
| 1812 a->CanBePositive() ? positive_bound : 0); | 1845 a->CanBePositive() ? positive_bound : 0); |
| 1813 | 1846 |
| 1814 if (left_can_be_negative) { | 1847 if (left_can_be_negative) { |
| 1815 result->set_can_be_minus_zero(true); | 1848 result->set_can_be_minus_zero(true); |
| 1816 } | 1849 } |
| 1817 | 1850 |
| 1818 if (!a->Includes(kMinInt) || !b->Includes(-1)) { | 1851 if (!b->Includes(-1) || |
| 1852 (r.IsSmi() && !a->Includes(Smi::kMinValue)) || | |
|
Sven Panne
2013/06/04 09:53:56
* Re-order back to a, then b test.
* Introduce 'mi
Sven Panne
2013/06/04 10:01:07
Thinking about it: We have to avoid an idiv of 0x8
Toon Verwaest
2013/06/04 15:06:40
You are right. I actually (temporarily) backed out
| |
| 1853 (r.IsInteger32() && !a->Includes(kMinInt))) { | |
| 1819 ClearFlag(HValue::kCanOverflow); | 1854 ClearFlag(HValue::kCanOverflow); |
| 1820 } | 1855 } |
| 1821 | 1856 |
| 1822 if (!b->CanBeZero()) { | 1857 if (!b->CanBeZero()) { |
| 1823 ClearFlag(HValue::kCanBeDivByZero); | 1858 ClearFlag(HValue::kCanBeDivByZero); |
| 1824 } | 1859 } |
| 1825 return result; | 1860 return result; |
| 1826 } else { | 1861 } else { |
| 1827 return HValue::InferRange(zone); | 1862 return HValue::InferRange(zone); |
| 1828 } | 1863 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1877 break; | 1912 break; |
| 1878 } | 1913 } |
| 1879 } | 1914 } |
| 1880 ClearFlag(kNumericConstraintEvaluationInProgress); | 1915 ClearFlag(kNumericConstraintEvaluationInProgress); |
| 1881 | 1916 |
| 1882 return result; | 1917 return result; |
| 1883 } | 1918 } |
| 1884 | 1919 |
| 1885 | 1920 |
| 1886 Range* HMathMinMax::InferRange(Zone* zone) { | 1921 Range* HMathMinMax::InferRange(Zone* zone) { |
| 1887 if (representation().IsInteger32()) { | 1922 if (representation().IsSmiOrInteger32()) { |
| 1888 Range* a = left()->range(); | 1923 Range* a = left()->range(); |
| 1889 Range* b = right()->range(); | 1924 Range* b = right()->range(); |
| 1890 Range* res = a->Copy(zone); | 1925 Range* res = a->Copy(zone); |
| 1891 if (operation_ == kMathMax) { | 1926 if (operation_ == kMathMax) { |
| 1892 res->CombinedMax(b); | 1927 res->CombinedMax(b); |
| 1893 } else { | 1928 } else { |
| 1894 ASSERT(operation_ == kMathMin); | 1929 ASSERT(operation_ == kMathMin); |
| 1895 res->CombinedMin(b); | 1930 res->CombinedMin(b); |
| 1896 } | 1931 } |
| 1897 return res; | 1932 return res; |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2167 } else if (has_int32_value_) { | 2202 } else if (has_int32_value_) { |
| 2168 r = Representation::Integer32(); | 2203 r = Representation::Integer32(); |
| 2169 } else if (has_double_value_) { | 2204 } else if (has_double_value_) { |
| 2170 r = Representation::Double(); | 2205 r = Representation::Double(); |
| 2171 } else { | 2206 } else { |
| 2172 r = Representation::Tagged(); | 2207 r = Representation::Tagged(); |
| 2173 } | 2208 } |
| 2174 } | 2209 } |
| 2175 set_representation(r); | 2210 set_representation(r); |
| 2176 SetFlag(kUseGVN); | 2211 SetFlag(kUseGVN); |
| 2177 if (representation().IsInteger32()) { | 2212 if (representation().IsSmiOrInteger32()) { |
| 2178 ClearGVNFlag(kDependsOnOsrEntries); | 2213 ClearGVNFlag(kDependsOnOsrEntries); |
| 2179 } | 2214 } |
| 2180 } | 2215 } |
| 2181 | 2216 |
| 2182 | 2217 |
| 2183 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { | 2218 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
| 2184 if (r.IsSmi() && !has_smi_value_) return NULL; | 2219 if (r.IsSmi() && !has_smi_value_) return NULL; |
| 2185 if (r.IsInteger32() && !has_int32_value_) return NULL; | 2220 if (r.IsInteger32() && !has_int32_value_) return NULL; |
| 2186 if (r.IsDouble() && !has_double_value_) return NULL; | 2221 if (r.IsDouble() && !has_double_value_) return NULL; |
| 2187 if (has_int32_value_) { | 2222 if (has_int32_value_) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2262 !this->IsDiv() && | 2297 !this->IsDiv() && |
| 2263 CheckUsesForFlag(kTruncatingToInt32); | 2298 CheckUsesForFlag(kTruncatingToInt32); |
| 2264 } | 2299 } |
| 2265 | 2300 |
| 2266 | 2301 |
| 2267 Representation HBinaryOperation::RepresentationFromInputs() { | 2302 Representation HBinaryOperation::RepresentationFromInputs() { |
| 2268 // Determine the worst case of observed input representations and | 2303 // Determine the worst case of observed input representations and |
| 2269 // the currently assumed output representation. | 2304 // the currently assumed output representation. |
| 2270 Representation rep = representation(); | 2305 Representation rep = representation(); |
| 2271 for (int i = 1; i <= 2; ++i) { | 2306 for (int i = 1; i <= 2; ++i) { |
| 2272 Representation input_rep = observed_input_representation(i); | 2307 rep = rep.generalize(observed_input_representation(i)); |
| 2273 if (input_rep.is_more_general_than(rep)) rep = input_rep; | |
| 2274 } | 2308 } |
| 2275 // If any of the actual input representation is more general than what we | 2309 // If any of the actual input representation is more general than what we |
| 2276 // have so far but not Tagged, use that representation instead. | 2310 // have so far but not Tagged, use that representation instead. |
| 2277 Representation left_rep = left()->representation(); | 2311 Representation left_rep = left()->representation(); |
| 2278 Representation right_rep = right()->representation(); | 2312 Representation right_rep = right()->representation(); |
| 2279 | 2313 |
| 2280 if (left_rep.is_more_general_than(rep) && !left_rep.IsTagged()) { | 2314 if (left_rep.is_more_general_than(rep) && !left_rep.IsTagged()) { |
| 2281 rep = left_rep; | 2315 rep = left_rep; |
| 2282 } | 2316 } |
| 2283 if (right_rep.is_more_general_than(rep) && !right_rep.IsTagged()) { | 2317 if (right_rep.is_more_general_than(rep) && !right_rep.IsTagged()) { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2449 stream->Add("B%d", SuccessorAt(0)->block_id()); | 2483 stream->Add("B%d", SuccessorAt(0)->block_id()); |
| 2450 } | 2484 } |
| 2451 | 2485 |
| 2452 | 2486 |
| 2453 void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) { | 2487 void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) { |
| 2454 Representation left_rep = left()->representation(); | 2488 Representation left_rep = left()->representation(); |
| 2455 Representation right_rep = right()->representation(); | 2489 Representation right_rep = right()->representation(); |
| 2456 Representation observed_left = observed_input_representation(0); | 2490 Representation observed_left = observed_input_representation(0); |
| 2457 Representation observed_right = observed_input_representation(1); | 2491 Representation observed_right = observed_input_representation(1); |
| 2458 | 2492 |
| 2459 Representation rep = Representation::Smi(); | 2493 Representation rep = observed_left.generalize(observed_right); |
| 2460 if (observed_left.IsInteger32() && observed_right.IsInteger32()) { | 2494 if (rep.IsNone() || rep.IsSmiOrInteger32()) { |
| 2461 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); | 2495 if (!left_rep.IsTagged()) rep = rep.generalize(left_rep); |
| 2462 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); | 2496 if (!right_rep.IsTagged()) rep = rep.generalize(right_rep); |
| 2463 } else { | 2497 } else { |
| 2464 rep = Representation::Double(); | 2498 rep = Representation::Double(); |
| 2465 } | 2499 } |
| 2466 | 2500 |
| 2467 if (rep.IsDouble()) { | 2501 if (rep.IsDouble()) { |
| 2468 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, === | 2502 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, === |
| 2469 // and !=) have special handling of undefined, e.g. undefined == undefined | 2503 // and !=) have special handling of undefined, e.g. undefined == undefined |
| 2470 // is 'true'. Relational comparisons have a different semantic, first | 2504 // is 'true'. Relational comparisons have a different semantic, first |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3046 | 3080 |
| 3047 | 3081 |
| 3048 HType HFunctionLiteral::CalculateInferredType() { | 3082 HType HFunctionLiteral::CalculateInferredType() { |
| 3049 return HType::JSObject(); | 3083 return HType::JSObject(); |
| 3050 } | 3084 } |
| 3051 | 3085 |
| 3052 | 3086 |
| 3053 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( | 3087 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( |
| 3054 BitVector* visited) { | 3088 BitVector* visited) { |
| 3055 visited->Add(id()); | 3089 visited->Add(id()); |
| 3056 if (representation().IsInteger32() && | 3090 if (representation().IsSmiOrInteger32() && |
| 3057 !value()->representation().IsInteger32()) { | 3091 !value()->representation().Equals(representation())) { |
| 3058 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | 3092 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
| 3059 SetFlag(kBailoutOnMinusZero); | 3093 SetFlag(kBailoutOnMinusZero); |
| 3060 } | 3094 } |
| 3061 } | 3095 } |
| 3062 if (RequiredInputRepresentation(0).IsInteger32() && | 3096 if (RequiredInputRepresentation(0).IsSmiOrInteger32() && |
| 3063 representation().IsInteger32()) { | 3097 representation().Equals(RequiredInputRepresentation(0))) { |
| 3064 return value(); | 3098 return value(); |
| 3065 } | 3099 } |
| 3066 return NULL; | 3100 return NULL; |
| 3067 } | 3101 } |
| 3068 | 3102 |
| 3069 | 3103 |
| 3070 | 3104 |
| 3071 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { | 3105 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { |
| 3072 visited->Add(id()); | 3106 visited->Add(id()); |
| 3073 if (from().IsInteger32()) return NULL; | 3107 if (from().IsSmiOrInteger32()) return NULL; |
| 3074 if (CanTruncateToInt32()) return NULL; | 3108 if (CanTruncateToInt32()) return NULL; |
| 3075 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | 3109 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
| 3076 SetFlag(kBailoutOnMinusZero); | 3110 SetFlag(kBailoutOnMinusZero); |
| 3077 } | 3111 } |
| 3078 ASSERT(!from().IsInteger32() || !to().IsInteger32()); | 3112 ASSERT(!from().IsSmiOrInteger32() || !to().IsSmiOrInteger32()); |
| 3079 return NULL; | 3113 return NULL; |
| 3080 } | 3114 } |
| 3081 | 3115 |
| 3082 | 3116 |
| 3083 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero( | 3117 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero( |
| 3084 BitVector* visited) { | 3118 BitVector* visited) { |
| 3085 visited->Add(id()); | 3119 visited->Add(id()); |
| 3086 return value(); | 3120 return value(); |
| 3087 } | 3121 } |
| 3088 | 3122 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3155 if (value()->IsConstant()) { | 3189 if (value()->IsConstant()) { |
| 3156 return false; | 3190 return false; |
| 3157 } | 3191 } |
| 3158 | 3192 |
| 3159 if (value()->IsLoadKeyed()) { | 3193 if (value()->IsLoadKeyed()) { |
| 3160 return IsExternalFloatOrDoubleElementsKind( | 3194 return IsExternalFloatOrDoubleElementsKind( |
| 3161 HLoadKeyed::cast(value())->elements_kind()); | 3195 HLoadKeyed::cast(value())->elements_kind()); |
| 3162 } | 3196 } |
| 3163 | 3197 |
| 3164 if (value()->IsChange()) { | 3198 if (value()->IsChange()) { |
| 3165 if (HChange::cast(value())->from().IsInteger32()) { | 3199 if (HChange::cast(value())->from().IsSmiOrInteger32()) { |
| 3166 return false; | 3200 return false; |
| 3167 } | 3201 } |
| 3168 if (HChange::cast(value())->value()->type().IsSmi()) { | 3202 if (HChange::cast(value())->value()->type().IsSmi()) { |
| 3169 return false; | 3203 return false; |
| 3170 } | 3204 } |
| 3171 } | 3205 } |
| 3172 return true; | 3206 return true; |
| 3173 } | 3207 } |
| 3174 | 3208 |
| 3175 | 3209 |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3531 } else { | 3565 } else { |
| 3532 // This catches |false|, |undefined|, strings and objects. | 3566 // This catches |false|, |undefined|, strings and objects. |
| 3533 SetOperandAt(i, graph->GetConstant0()); | 3567 SetOperandAt(i, graph->GetConstant0()); |
| 3534 } | 3568 } |
| 3535 } | 3569 } |
| 3536 // Overwrite observed input representations because they are likely Tagged. | 3570 // Overwrite observed input representations because they are likely Tagged. |
| 3537 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 3571 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
| 3538 HValue* use = it.value(); | 3572 HValue* use = it.value(); |
| 3539 if (use->IsBinaryOperation()) { | 3573 if (use->IsBinaryOperation()) { |
| 3540 HBinaryOperation::cast(use)->set_observed_input_representation( | 3574 HBinaryOperation::cast(use)->set_observed_input_representation( |
| 3541 it.index(), Representation::Integer32()); | 3575 it.index(), Representation::Smi()); |
| 3542 } | 3576 } |
| 3543 } | 3577 } |
| 3544 } | 3578 } |
| 3545 | 3579 |
| 3546 | 3580 |
| 3547 void HPhi::InferRepresentation(HInferRepresentation* h_infer) { | 3581 void HPhi::InferRepresentation(HInferRepresentation* h_infer) { |
| 3548 ASSERT(CheckFlag(kFlexibleRepresentation)); | 3582 ASSERT(CheckFlag(kFlexibleRepresentation)); |
| 3549 Representation new_rep = RepresentationFromInputs(); | 3583 Representation new_rep = RepresentationFromInputs(); |
| 3550 UpdateRepresentation(new_rep, h_infer, "inputs"); | 3584 UpdateRepresentation(new_rep, h_infer, "inputs"); |
| 3551 new_rep = RepresentationFromUses(); | 3585 new_rep = RepresentationFromUses(); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3759 case kBackingStore: | 3793 case kBackingStore: |
| 3760 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); | 3794 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); |
| 3761 stream->Add("[backing-store]"); | 3795 stream->Add("[backing-store]"); |
| 3762 break; | 3796 break; |
| 3763 } | 3797 } |
| 3764 | 3798 |
| 3765 stream->Add("@%d", offset()); | 3799 stream->Add("@%d", offset()); |
| 3766 } | 3800 } |
| 3767 | 3801 |
| 3768 } } // namespace v8::internal | 3802 } } // namespace v8::internal |
| OLD | NEW |