| 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 |