Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: src/hydrogen-instructions.cc

Issue 10837165: Lattice-based representation inference, powered by left/right specific type feedback for BinaryOps … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: HConstants, HSimulates, stub fixes Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698