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