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 void HValue::AssumeRepresentation(Representation r) { | 78 void HValue::AssumeRepresentation(Representation r) { |
79 if (CheckFlag(kFlexibleRepresentation)) { | 79 if (CheckFlag(kFlexibleRepresentation)) { |
80 ChangeRepresentation(r); | 80 ChangeRepresentation(r); |
81 // The representation of the value is dictated by type feedback and | 81 // The representation of the value is dictated by type feedback and |
82 // will not be changed later. | 82 // will not be changed later. |
83 ClearFlag(kFlexibleRepresentation); | 83 ClearFlag(kFlexibleRepresentation); |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
87 | 87 |
88 void HValue::InferRepresentation(HInferRepresentation* hinfer) { | |
89 ASSERT(CheckFlag(kFlexibleRepresentation)); | |
90 Representation new_rep = RepresentationFromInputs(); | |
91 UpdateRepresentation(new_rep, hinfer, "inputs"); | |
92 new_rep = RepresentationFromUses(); | |
93 UpdateRepresentation(new_rep, hinfer, "uses"); | |
94 } | |
95 | |
96 | |
97 Representation HValue::RepresentationFromUses() { | |
98 if (HasNoUses()) return Representation::None(); | |
99 | |
100 // Array of use counts for each representation. | |
101 int use_count[Representation::kNumRepresentations] = { 0 }; | |
102 | |
103 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | |
104 HValue* use = it.value(); | |
105 Representation rep = use->observed_input_representation(it.index()); | |
106 if (rep.IsNone()) continue; | |
107 if (FLAG_trace_representation) { | |
108 PrintF("#%d %s is used by #%d %s as %s%s\n", | |
109 id(), Mnemonic(), use->id(), use->Mnemonic(), rep.Mnemonic(), | |
110 (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : "")); | |
111 } | |
112 use_count[rep.kind()] += use->LoopWeight(); | |
113 } | |
114 if (IsPhi()) HPhi::cast(this)->AddIndirectUsesTo(&use_count[0]); | |
115 int tagged_count = use_count[Representation::kTagged]; | |
116 int double_count = use_count[Representation::kDouble]; | |
117 int int32_count = use_count[Representation::kInteger32]; | |
118 | |
119 if (tagged_count > 0) return Representation::Tagged(); | |
120 if (double_count > 0) return Representation::Double(); | |
121 if (int32_count > 0) return Representation::Integer32(); | |
122 | |
123 return Representation::None(); | |
124 } | |
125 | |
126 | |
127 void HValue::UpdateRepresentation(Representation new_rep, | |
128 HInferRepresentation* hinfer, | |
129 const char* reason) { | |
130 Representation r = representation(); | |
131 if (new_rep.is_more_general_than(r)) { | |
132 if (new_rep.IsInteger32() && !IsConvertibleToInteger()) { | |
danno
2012/11/06 11:42:59
Add a comment
Jakob Kummerow
2012/11/06 12:44:05
Done.
| |
133 new_rep = Representation::Tagged(); | |
134 if (FLAG_trace_representation) { | |
135 PrintF("Changing #%d %s representation %s -> %s because it's NCTI" | |
136 " (%s want i)\n", | |
137 id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason); | |
138 } | |
139 } else { | |
140 if (FLAG_trace_representation) { | |
141 PrintF("Changing #%d %s representation %s -> %s based on %s\n", | |
142 id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason); | |
143 } | |
144 } | |
145 ChangeRepresentation(new_rep); | |
146 AddDependantsToWorklist(hinfer); | |
147 } | |
148 } | |
149 | |
150 | |
151 void HValue::AddDependantsToWorklist(HInferRepresentation* hinfer) { | |
152 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | |
153 hinfer->AddToWorklist(it.value()); | |
154 } | |
155 for (int i = 0; i < OperandCount(); ++i) { | |
156 hinfer->AddToWorklist(OperandAt(i)); | |
157 } | |
158 } | |
159 | |
160 | |
88 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { | 161 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { |
89 if (result > kMaxInt) { | 162 if (result > kMaxInt) { |
90 *overflow = true; | 163 *overflow = true; |
91 return kMaxInt; | 164 return kMaxInt; |
92 } | 165 } |
93 if (result < kMinInt) { | 166 if (result < kMinInt) { |
94 *overflow = true; | 167 *overflow = true; |
95 return kMinInt; | 168 return kMinInt; |
96 } | 169 } |
97 return static_cast<int32_t>(result); | 170 return static_cast<int32_t>(result); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 // Skip and remove dead items in the use list. | 367 // Skip and remove dead items in the use list. |
295 while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) { | 368 while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) { |
296 tail_ = tail_->tail_; | 369 tail_ = tail_->tail_; |
297 } | 370 } |
298 return tail_; | 371 return tail_; |
299 } | 372 } |
300 | 373 |
301 | 374 |
302 bool HValue::CheckUsesForFlag(Flag f) { | 375 bool HValue::CheckUsesForFlag(Flag f) { |
303 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 376 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
377 if (it.value()->IsSimulate()) continue; | |
304 if (!it.value()->CheckFlag(f)) return false; | 378 if (!it.value()->CheckFlag(f)) return false; |
305 } | 379 } |
306 return true; | 380 return true; |
307 } | 381 } |
308 | 382 |
309 | 383 |
310 HUseIterator::HUseIterator(HUseListNode* head) : next_(head) { | 384 HUseIterator::HUseIterator(HUseListNode* head) : next_(head) { |
311 Advance(); | 385 Advance(); |
312 } | 386 } |
313 | 387 |
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1342 ASSERT(block() == NULL); | 1416 ASSERT(block() == NULL); |
1343 } | 1417 } |
1344 | 1418 |
1345 | 1419 |
1346 void HPhi::InitRealUses(int phi_id) { | 1420 void HPhi::InitRealUses(int phi_id) { |
1347 // Initialize real uses. | 1421 // Initialize real uses. |
1348 phi_id_ = phi_id; | 1422 phi_id_ = phi_id; |
1349 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 1423 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
1350 HValue* value = it.value(); | 1424 HValue* value = it.value(); |
1351 if (!value->IsPhi()) { | 1425 if (!value->IsPhi()) { |
1352 Representation rep = value->ObservedInputRepresentation(it.index()); | 1426 Representation rep = value->observed_input_representation(it.index()); |
1353 non_phi_uses_[rep.kind()] += value->LoopWeight(); | 1427 non_phi_uses_[rep.kind()] += value->LoopWeight(); |
1354 if (FLAG_trace_representation) { | 1428 if (FLAG_trace_representation) { |
1355 PrintF("%d %s is used by %d %s as %s\n", | 1429 PrintF("#%d Phi is used by real #%d %s as %s\n", |
1356 this->id(), | 1430 id(), value->id(), value->Mnemonic(), rep.Mnemonic()); |
1357 this->Mnemonic(), | |
1358 value->id(), | |
1359 value->Mnemonic(), | |
1360 rep.Mnemonic()); | |
1361 } | 1431 } |
1362 } | 1432 } |
1363 } | 1433 } |
1364 } | 1434 } |
1365 | 1435 |
1366 | 1436 |
1367 void HPhi::AddNonPhiUsesFrom(HPhi* other) { | 1437 void HPhi::AddNonPhiUsesFrom(HPhi* other) { |
1368 if (FLAG_trace_representation) { | 1438 if (FLAG_trace_representation) { |
1369 PrintF("adding to %d %s uses of %d %s: i%d d%d t%d\n", | 1439 PrintF("adding to #%d Phi uses of #%d Phi: i%d d%d t%d\n", |
1370 this->id(), | 1440 id(), other->id(), |
1371 this->Mnemonic(), | |
1372 other->id(), | |
1373 other->Mnemonic(), | |
1374 other->non_phi_uses_[Representation::kInteger32], | 1441 other->non_phi_uses_[Representation::kInteger32], |
1375 other->non_phi_uses_[Representation::kDouble], | 1442 other->non_phi_uses_[Representation::kDouble], |
1376 other->non_phi_uses_[Representation::kTagged]); | 1443 other->non_phi_uses_[Representation::kTagged]); |
1377 } | 1444 } |
1378 | 1445 |
1379 for (int i = 0; i < Representation::kNumRepresentations; i++) { | 1446 for (int i = 0; i < Representation::kNumRepresentations; i++) { |
1380 indirect_uses_[i] += other->non_phi_uses_[i]; | 1447 indirect_uses_[i] += other->non_phi_uses_[i]; |
1381 } | 1448 } |
1382 } | 1449 } |
1383 | 1450 |
1384 | 1451 |
1385 void HPhi::AddIndirectUsesTo(int* dest) { | 1452 void HPhi::AddIndirectUsesTo(int* dest) { |
1386 for (int i = 0; i < Representation::kNumRepresentations; i++) { | 1453 for (int i = 0; i < Representation::kNumRepresentations; i++) { |
1387 dest[i] += indirect_uses_[i]; | 1454 dest[i] += indirect_uses_[i]; |
1388 } | 1455 } |
1389 } | 1456 } |
1390 | 1457 |
1391 | 1458 |
1392 void HPhi::ResetInteger32Uses() { | 1459 void HSimulate::MergeInto(HSimulate* other) { |
1393 non_phi_uses_[Representation::kInteger32] = 0; | 1460 for (int i = 0; i < values_.length(); ++i) { |
1394 indirect_uses_[Representation::kInteger32] = 0; | 1461 HValue* value = values_[i]; |
1462 if (HasAssignedIndexAt(i)) { | |
1463 other->AddAssignedValue(GetAssignedIndexAt(i), value); | |
1464 } else { | |
1465 if (other->pop_count_ > 0) { | |
1466 other->pop_count_--; | |
1467 } else { | |
1468 other->AddPushedValue(value); | |
1469 } | |
1470 } | |
1471 } | |
1472 other->pop_count_ += pop_count(); | |
1395 } | 1473 } |
1396 | 1474 |
1397 | 1475 |
1398 void HSimulate::PrintDataTo(StringStream* stream) { | 1476 void HSimulate::PrintDataTo(StringStream* stream) { |
1399 stream->Add("id=%d", ast_id().ToInt()); | 1477 stream->Add("id=%d", ast_id().ToInt()); |
1400 if (pop_count_ > 0) stream->Add(" pop %d", pop_count_); | 1478 if (pop_count_ > 0) stream->Add(" pop %d", pop_count_); |
1401 if (values_.length() > 0) { | 1479 if (values_.length() > 0) { |
1402 if (pop_count_ > 0) stream->Add(" /"); | 1480 if (pop_count_ > 0) stream->Add(" /"); |
1403 for (int i = 0; i < values_.length(); ++i) { | 1481 for (int i = values_.length() - 1; i >= 0; --i) { |
1404 if (i > 0) stream->Add(","); | 1482 if (i > 0) stream->Add(","); |
1405 if (HasAssignedIndexAt(i)) { | 1483 if (HasAssignedIndexAt(i)) { |
1406 stream->Add(" var[%d] = ", GetAssignedIndexAt(i)); | 1484 stream->Add(" var[%d] = ", GetAssignedIndexAt(i)); |
1407 } else { | 1485 } else { |
1408 stream->Add(" push "); | 1486 stream->Add(" push "); |
1409 } | 1487 } |
1410 values_[i]->PrintNameTo(stream); | 1488 values_[i]->PrintNameTo(stream); |
1411 } | 1489 } |
1412 } | 1490 } |
1413 } | 1491 } |
(...skipping 18 matching lines...) Expand all Loading... | |
1432 static bool IsInteger32(double value) { | 1510 static bool IsInteger32(double value) { |
1433 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); | 1511 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); |
1434 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); | 1512 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); |
1435 } | 1513 } |
1436 | 1514 |
1437 | 1515 |
1438 HConstant::HConstant(Handle<Object> handle, Representation r) | 1516 HConstant::HConstant(Handle<Object> handle, Representation r) |
1439 : handle_(handle), | 1517 : handle_(handle), |
1440 has_int32_value_(false), | 1518 has_int32_value_(false), |
1441 has_double_value_(false) { | 1519 has_double_value_(false) { |
1442 set_representation(r); | |
1443 SetFlag(kUseGVN); | 1520 SetFlag(kUseGVN); |
1444 if (handle_->IsNumber()) { | 1521 if (handle_->IsNumber()) { |
1445 double n = handle_->Number(); | 1522 double n = handle_->Number(); |
1446 has_int32_value_ = IsInteger32(n); | 1523 has_int32_value_ = IsInteger32(n); |
1447 int32_value_ = DoubleToInt32(n); | 1524 int32_value_ = DoubleToInt32(n); |
1448 double_value_ = n; | 1525 double_value_ = n; |
1449 has_double_value_ = true; | 1526 has_double_value_ = true; |
1450 } | 1527 } |
1528 if (r.IsNone()) { | |
1529 if (has_int32_value_) { | |
1530 r = Representation::Integer32(); | |
1531 } else if (has_double_value_) { | |
1532 r = Representation::Double(); | |
1533 } else { | |
1534 r = Representation::Tagged(); | |
1535 } | |
1536 } | |
1537 set_representation(r); | |
1451 } | 1538 } |
1452 | 1539 |
1453 | 1540 |
1454 HConstant::HConstant(int32_t integer_value, Representation r) | 1541 HConstant::HConstant(int32_t integer_value, Representation r) |
1455 : has_int32_value_(true), | 1542 : has_int32_value_(true), |
1456 has_double_value_(true), | 1543 has_double_value_(true), |
1457 int32_value_(integer_value), | 1544 int32_value_(integer_value), |
1458 double_value_(FastI2D(integer_value)) { | 1545 double_value_(FastI2D(integer_value)) { |
1459 set_representation(r); | 1546 set_representation(r); |
1460 SetFlag(kUseGVN); | 1547 SetFlag(kUseGVN); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1539 | 1626 |
1540 void HBinaryOperation::PrintDataTo(StringStream* stream) { | 1627 void HBinaryOperation::PrintDataTo(StringStream* stream) { |
1541 left()->PrintNameTo(stream); | 1628 left()->PrintNameTo(stream); |
1542 stream->Add(" "); | 1629 stream->Add(" "); |
1543 right()->PrintNameTo(stream); | 1630 right()->PrintNameTo(stream); |
1544 if (CheckFlag(kCanOverflow)) stream->Add(" !"); | 1631 if (CheckFlag(kCanOverflow)) stream->Add(" !"); |
1545 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 1632 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
1546 } | 1633 } |
1547 | 1634 |
1548 | 1635 |
1636 Representation HBinaryOperation::RepresentationFromInputs() { | |
1637 // Determine the worst case of observed input representations and | |
1638 // the currently assumed output representation. | |
1639 Representation rep = representation(); | |
1640 if (observed_output_representation_.is_more_general_than(rep)) { | |
1641 rep = observed_output_representation_; | |
1642 } | |
1643 for (int i = 1; i <= 2; ++i) { | |
1644 Representation input_rep = observed_input_representation(i); | |
1645 if (input_rep.is_more_general_than(rep)) rep = input_rep; | |
1646 } | |
1647 // If any of the actual input representation is more general than what we | |
1648 // have so far but not Tagged, use that representation instead. | |
1649 Representation left_rep = left()->representation(); | |
1650 Representation right_rep = right()->representation(); | |
1651 | |
1652 if (left_rep.is_more_general_than(rep) && | |
1653 left()->CheckFlag(kFlexibleRepresentation)) { | |
1654 rep = left_rep; | |
1655 } | |
1656 if (right_rep.is_more_general_than(rep) && | |
1657 right()->CheckFlag(kFlexibleRepresentation)) { | |
1658 rep = right_rep; | |
1659 } | |
1660 return rep; | |
1661 } | |
1662 | |
1663 | |
1664 void HBinaryOperation::AssumeRepresentation(Representation r) { | |
1665 set_observed_input_representation(r, r); | |
1666 HValue::AssumeRepresentation(r); | |
1667 } | |
1668 | |
1669 | |
1549 Range* HBitwise::InferRange(Zone* zone) { | 1670 Range* HBitwise::InferRange(Zone* zone) { |
1550 if (op() == Token::BIT_XOR) return HValue::InferRange(zone); | 1671 if (op() == Token::BIT_XOR) return HValue::InferRange(zone); |
1551 const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff); | 1672 const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff); |
1552 int32_t left_mask = (left()->range() != NULL) | 1673 int32_t left_mask = (left()->range() != NULL) |
1553 ? left()->range()->Mask() | 1674 ? left()->range()->Mask() |
1554 : kDefaultMask; | 1675 : kDefaultMask; |
1555 int32_t right_mask = (right()->range() != NULL) | 1676 int32_t right_mask = (right()->range() != NULL) |
1556 ? right()->range()->Mask() | 1677 ? right()->range()->Mask() |
1557 : kDefaultMask; | 1678 : kDefaultMask; |
1558 int32_t result_mask = (op() == Token::BIT_AND) | 1679 int32_t result_mask = (op() == Token::BIT_AND) |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1670 right()->PrintNameTo(stream); | 1791 right()->PrintNameTo(stream); |
1671 HControlInstruction::PrintDataTo(stream); | 1792 HControlInstruction::PrintDataTo(stream); |
1672 } | 1793 } |
1673 | 1794 |
1674 | 1795 |
1675 void HGoto::PrintDataTo(StringStream* stream) { | 1796 void HGoto::PrintDataTo(StringStream* stream) { |
1676 stream->Add("B%d", SuccessorAt(0)->block_id()); | 1797 stream->Add("B%d", SuccessorAt(0)->block_id()); |
1677 } | 1798 } |
1678 | 1799 |
1679 | 1800 |
1680 void HCompareIDAndBranch::SetInputRepresentation(Representation r) { | 1801 void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* hinfer) { |
1681 input_representation_ = r; | 1802 Representation rep = Representation::None(); |
1682 if (r.IsDouble()) { | 1803 if (observed_input_representation(0).IsInteger32() && |
1804 observed_input_representation(1).IsInteger32()) { | |
1805 rep = Representation::Integer32(); | |
1806 } else { | |
1807 rep = Representation::Double(); | |
1683 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, === | 1808 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, === |
1684 // and !=) have special handling of undefined, e.g. undefined == undefined | 1809 // and !=) have special handling of undefined, e.g. undefined == undefined |
1685 // is 'true'. Relational comparisons have a different semantic, first | 1810 // is 'true'. Relational comparisons have a different semantic, first |
1686 // calling ToPrimitive() on their arguments. The standard Crankshaft | 1811 // calling ToPrimitive() on their arguments. The standard Crankshaft |
1687 // tagged-to-double conversion to ensure the HCompareIDAndBranch's inputs | 1812 // tagged-to-double conversion to ensure the HCompareIDAndBranch's inputs |
1688 // are doubles caused 'undefined' to be converted to NaN. That's compatible | 1813 // are doubles caused 'undefined' to be converted to NaN. That's compatible |
1689 // out-of-the box with ordered relational comparisons (<, >, <=, | 1814 // out-of-the box with ordered relational comparisons (<, >, <=, |
1690 // >=). However, for equality comparisons (and for 'in' and 'instanceof'), | 1815 // >=). However, for equality comparisons (and for 'in' and 'instanceof'), |
1691 // it is not consistent with the spec. For example, it would cause undefined | 1816 // it is not consistent with the spec. For example, it would cause undefined |
1692 // == undefined (should be true) to be evaluated as NaN == NaN | 1817 // == undefined (should be true) to be evaluated as NaN == NaN |
1693 // (false). Therefore, any comparisons other than ordered relational | 1818 // (false). Therefore, any comparisons other than ordered relational |
1694 // comparisons must cause a deopt when one of their arguments is undefined. | 1819 // comparisons must cause a deopt when one of their arguments is undefined. |
1695 // See also v8:1434 | 1820 // See also v8:1434 |
1696 if (!Token::IsOrderedRelationalCompareOp(token_)) { | 1821 if (!Token::IsOrderedRelationalCompareOp(token_)) { |
1697 SetFlag(kDeoptimizeOnUndefined); | 1822 SetFlag(kDeoptimizeOnUndefined); |
1698 } | 1823 } |
1699 } else { | |
1700 ASSERT(r.IsInteger32()); | |
1701 } | 1824 } |
1825 AssumeRepresentation(rep); | |
1702 } | 1826 } |
1703 | 1827 |
1704 | 1828 |
1705 void HParameter::PrintDataTo(StringStream* stream) { | 1829 void HParameter::PrintDataTo(StringStream* stream) { |
1706 stream->Add("%u", index()); | 1830 stream->Add("%u", index()); |
1707 } | 1831 } |
1708 | 1832 |
1709 | 1833 |
1710 void HLoadNamedField::PrintDataTo(StringStream* stream) { | 1834 void HLoadNamedField::PrintDataTo(StringStream* stream) { |
1711 object()->PrintNameTo(stream); | 1835 object()->PrintNameTo(stream); |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2454 } | 2578 } |
2455 | 2579 |
2456 | 2580 |
2457 void HBitwise::PrintDataTo(StringStream* stream) { | 2581 void HBitwise::PrintDataTo(StringStream* stream) { |
2458 stream->Add(Token::Name(op_)); | 2582 stream->Add(Token::Name(op_)); |
2459 stream->Add(" "); | 2583 stream->Add(" "); |
2460 HBitwiseBinaryOperation::PrintDataTo(stream); | 2584 HBitwiseBinaryOperation::PrintDataTo(stream); |
2461 } | 2585 } |
2462 | 2586 |
2463 | 2587 |
2464 Representation HPhi::InferredRepresentation() { | 2588 void HPhi::InferRepresentation(HInferRepresentation* hinfer) { |
2589 HValue::InferRepresentation(hinfer); | |
2590 Representation new_rep = RepresentationFromUseRequirements(); | |
2591 UpdateRepresentation(new_rep, hinfer, "use requirements"); | |
2592 } | |
2593 | |
2594 | |
2595 Representation HPhi::RepresentationFromInputs() { | |
2465 bool double_occurred = false; | 2596 bool double_occurred = false; |
2466 bool int32_occurred = false; | 2597 bool int32_occurred = false; |
2467 for (int i = 0; i < OperandCount(); ++i) { | 2598 for (int i = 0; i < OperandCount(); ++i) { |
2468 HValue* value = OperandAt(i); | 2599 HValue* value = OperandAt(i); |
2469 if (value->IsUnknownOSRValue()) { | 2600 if (value->IsUnknownOSRValue()) { |
2470 HPhi* hint_value = HUnknownOSRValue::cast(value)->incoming_value(); | 2601 HPhi* hint_value = HUnknownOSRValue::cast(value)->incoming_value(); |
2471 if (hint_value != NULL) { | 2602 if (hint_value != NULL) { |
2472 Representation hint = hint_value->representation(); | 2603 Representation hint = hint_value->representation(); |
2604 if (hint.IsTagged()) return hint; | |
2473 if (hint.IsDouble()) double_occurred = true; | 2605 if (hint.IsDouble()) double_occurred = true; |
2474 if (hint.IsInteger32()) int32_occurred = true; | 2606 if (hint.IsInteger32()) int32_occurred = true; |
2475 } | 2607 } |
2476 continue; | 2608 continue; |
2477 } | 2609 } |
2478 if (value->representation().IsDouble()) double_occurred = true; | 2610 if (value->representation().IsDouble()) double_occurred = true; |
2479 if (value->representation().IsInteger32()) int32_occurred = true; | 2611 if (value->representation().IsInteger32()) int32_occurred = true; |
2480 if (value->representation().IsTagged()) { | 2612 if (value->representation().IsTagged()) { |
2481 if (value->IsConstant()) { | 2613 if (value->IsConstant()) { |
2482 HConstant* constant = HConstant::cast(value); | 2614 HConstant* constant = HConstant::cast(value); |
2483 if (constant->IsConvertibleToInteger()) { | 2615 if (constant->IsConvertibleToInteger()) { |
2484 int32_occurred = true; | 2616 int32_occurred = true; |
2485 } else if (constant->HasNumberValue()) { | 2617 } else if (constant->HasNumberValue()) { |
2486 double_occurred = true; | 2618 double_occurred = true; |
2487 } else { | 2619 } else { |
2488 return Representation::Tagged(); | 2620 return Representation::Tagged(); |
2489 } | 2621 } |
2490 } else { | 2622 } else { |
2491 return Representation::Tagged(); | 2623 if (value->IsPhi() && !IsConvertibleToInteger()) { |
2624 return Representation::Tagged(); | |
2625 } | |
2492 } | 2626 } |
2493 } | 2627 } |
2494 } | 2628 } |
2495 | 2629 |
2496 if (double_occurred) return Representation::Double(); | 2630 if (double_occurred) return Representation::Double(); |
2497 | 2631 |
2498 if (int32_occurred) return Representation::Integer32(); | 2632 if (int32_occurred) return Representation::Integer32(); |
2499 | 2633 |
2500 return Representation::None(); | 2634 return Representation::None(); |
2501 } | 2635 } |
2502 | 2636 |
danno
2012/11/06 11:42:59
nit: two lines
Jakob Kummerow
2012/11/06 12:44:05
Done.
| |
2637 Representation HPhi::RepresentationFromUseRequirements() { | |
2638 Representation all_uses_require = Representation::None(); | |
2639 bool all_uses_require_the_same = true; | |
2640 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | |
2641 // We check for observed_input_representation elsewhere. | |
2642 Representation use_rep = | |
2643 it.value()->RequiredInputRepresentation(it.index()); | |
2644 // No useful info from this use -> look at the next one. | |
2645 if (use_rep.IsNone()) { | |
2646 continue; | |
2647 } | |
2648 if (use_rep.Equals(all_uses_require)) { | |
2649 continue; | |
2650 } | |
2651 // This use's representation contradicts what we've seen so far. | |
2652 if (!all_uses_require.IsNone()) { | |
2653 ASSERT(!use_rep.Equals(all_uses_require)); | |
2654 all_uses_require_the_same = false; | |
2655 break; | |
2656 } | |
2657 // Otherwise, initialize observed representation. | |
2658 all_uses_require = use_rep; | |
2659 } | |
2660 if (all_uses_require_the_same) { | |
2661 return all_uses_require; | |
2662 } | |
2663 | |
2664 return Representation::None(); | |
2665 } | |
2666 | |
2503 | 2667 |
2504 // Node-specific verification code is only included in debug mode. | 2668 // Node-specific verification code is only included in debug mode. |
2505 #ifdef DEBUG | 2669 #ifdef DEBUG |
2506 | 2670 |
2507 void HPhi::Verify() { | 2671 void HPhi::Verify() { |
2508 ASSERT(OperandCount() == block()->predecessors()->length()); | 2672 ASSERT(OperandCount() == block()->predecessors()->length()); |
2509 for (int i = 0; i < OperandCount(); ++i) { | 2673 for (int i = 0; i < OperandCount(); ++i) { |
2510 HValue* value = OperandAt(i); | 2674 HValue* value = OperandAt(i); |
2511 HBasicBlock* defining_block = value->block(); | 2675 HBasicBlock* defining_block = value->block(); |
2512 HBasicBlock* predecessor_block = block()->predecessors()->at(i); | 2676 HBasicBlock* predecessor_block = block()->predecessors()->at(i); |
(...skipping 22 matching lines...) Expand all Loading... | |
2535 | 2699 |
2536 | 2700 |
2537 void HCheckFunction::Verify() { | 2701 void HCheckFunction::Verify() { |
2538 HInstruction::Verify(); | 2702 HInstruction::Verify(); |
2539 ASSERT(HasNoUses()); | 2703 ASSERT(HasNoUses()); |
2540 } | 2704 } |
2541 | 2705 |
2542 #endif | 2706 #endif |
2543 | 2707 |
2544 } } // namespace v8::internal | 2708 } } // namespace v8::internal |
OLD | NEW |