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

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: review feedback 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* h_infer) {
89 ASSERT(CheckFlag(kFlexibleRepresentation));
90 Representation new_rep = RepresentationFromInputs();
91 UpdateRepresentation(new_rep, h_infer, "inputs");
92 new_rep = RepresentationFromUses();
93 UpdateRepresentation(new_rep, h_infer, "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* h_infer,
129 const char* reason) {
130 Representation r = representation();
131 if (new_rep.is_more_general_than(r)) {
132 // When an HConstant is marked "not convertible to integer", then
133 // never try to represent it as an integer.
134 if (new_rep.IsInteger32() && !IsConvertibleToInteger()) {
135 new_rep = Representation::Tagged();
136 if (FLAG_trace_representation) {
137 PrintF("Changing #%d %s representation %s -> %s because it's NCTI"
138 " (%s want i)\n",
139 id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason);
140 }
141 } else {
142 if (FLAG_trace_representation) {
143 PrintF("Changing #%d %s representation %s -> %s based on %s\n",
144 id(), Mnemonic(), r.Mnemonic(), new_rep.Mnemonic(), reason);
145 }
146 }
147 ChangeRepresentation(new_rep);
148 AddDependantsToWorklist(h_infer);
149 }
150 }
151
152
153 void HValue::AddDependantsToWorklist(HInferRepresentation* h_infer) {
154 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
155 h_infer->AddToWorklist(it.value());
156 }
157 for (int i = 0; i < OperandCount(); ++i) {
158 h_infer->AddToWorklist(OperandAt(i));
159 }
160 }
161
162
88 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { 163 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) {
89 if (result > kMaxInt) { 164 if (result > kMaxInt) {
90 *overflow = true; 165 *overflow = true;
91 return kMaxInt; 166 return kMaxInt;
92 } 167 }
93 if (result < kMinInt) { 168 if (result < kMinInt) {
94 *overflow = true; 169 *overflow = true;
95 return kMinInt; 170 return kMinInt;
96 } 171 }
97 return static_cast<int32_t>(result); 172 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. 369 // Skip and remove dead items in the use list.
295 while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) { 370 while (tail_ != NULL && tail_->value()->CheckFlag(HValue::kIsDead)) {
296 tail_ = tail_->tail_; 371 tail_ = tail_->tail_;
297 } 372 }
298 return tail_; 373 return tail_;
299 } 374 }
300 375
301 376
302 bool HValue::CheckUsesForFlag(Flag f) { 377 bool HValue::CheckUsesForFlag(Flag f) {
303 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 378 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
379 if (it.value()->IsSimulate()) continue;
304 if (!it.value()->CheckFlag(f)) return false; 380 if (!it.value()->CheckFlag(f)) return false;
305 } 381 }
306 return true; 382 return true;
307 } 383 }
308 384
309 385
310 HUseIterator::HUseIterator(HUseListNode* head) : next_(head) { 386 HUseIterator::HUseIterator(HUseListNode* head) : next_(head) {
311 Advance(); 387 Advance();
312 } 388 }
313 389
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 stream->Add(nil() == kNullValue ? "null" : "undefined"); 833 stream->Add(nil() == kNullValue ? "null" : "undefined");
758 HControlInstruction::PrintDataTo(stream); 834 HControlInstruction::PrintDataTo(stream);
759 } 835 }
760 836
761 837
762 void HReturn::PrintDataTo(StringStream* stream) { 838 void HReturn::PrintDataTo(StringStream* stream) {
763 value()->PrintNameTo(stream); 839 value()->PrintNameTo(stream);
764 } 840 }
765 841
766 842
843 Representation HBranch::observed_input_representation(int index) {
844 static const ToBooleanStub::Types tagged_types(
845 ToBooleanStub::UNDEFINED |
846 ToBooleanStub::NULL_TYPE |
847 ToBooleanStub::SPEC_OBJECT |
848 ToBooleanStub::STRING);
849 if (expected_input_types_.ContainsAnyOf(tagged_types)) {
850 return Representation::Tagged();
851 } else if (expected_input_types_.Contains(ToBooleanStub::HEAP_NUMBER)) {
852 return Representation::Double();
853 } else if (expected_input_types_.Contains(ToBooleanStub::SMI)) {
854 return Representation::Integer32();
855 } else {
856 return Representation::None();
857 }
858 }
859
860
767 void HCompareMap::PrintDataTo(StringStream* stream) { 861 void HCompareMap::PrintDataTo(StringStream* stream) {
768 value()->PrintNameTo(stream); 862 value()->PrintNameTo(stream);
769 stream->Add(" (%p)", *map()); 863 stream->Add(" (%p)", *map());
770 HControlInstruction::PrintDataTo(stream); 864 HControlInstruction::PrintDataTo(stream);
771 } 865 }
772 866
773 867
774 const char* HUnaryMathOperation::OpName() const { 868 const char* HUnaryMathOperation::OpName() const {
775 switch (op()) { 869 switch (op()) {
776 case kMathFloor: return "floor"; 870 case kMathFloor: return "floor";
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 ASSERT(block() == NULL); 1436 ASSERT(block() == NULL);
1343 } 1437 }
1344 1438
1345 1439
1346 void HPhi::InitRealUses(int phi_id) { 1440 void HPhi::InitRealUses(int phi_id) {
1347 // Initialize real uses. 1441 // Initialize real uses.
1348 phi_id_ = phi_id; 1442 phi_id_ = phi_id;
1349 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { 1443 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
1350 HValue* value = it.value(); 1444 HValue* value = it.value();
1351 if (!value->IsPhi()) { 1445 if (!value->IsPhi()) {
1352 Representation rep = value->ObservedInputRepresentation(it.index()); 1446 Representation rep = value->observed_input_representation(it.index());
1353 non_phi_uses_[rep.kind()] += value->LoopWeight(); 1447 non_phi_uses_[rep.kind()] += value->LoopWeight();
1354 if (FLAG_trace_representation) { 1448 if (FLAG_trace_representation) {
1355 PrintF("%d %s is used by %d %s as %s\n", 1449 PrintF("#%d Phi is used by real #%d %s as %s\n",
1356 this->id(), 1450 id(), value->id(), value->Mnemonic(), rep.Mnemonic());
1357 this->Mnemonic(),
1358 value->id(),
1359 value->Mnemonic(),
1360 rep.Mnemonic());
1361 } 1451 }
1362 } 1452 }
1363 } 1453 }
1364 } 1454 }
1365 1455
1366 1456
1367 void HPhi::AddNonPhiUsesFrom(HPhi* other) { 1457 void HPhi::AddNonPhiUsesFrom(HPhi* other) {
1368 if (FLAG_trace_representation) { 1458 if (FLAG_trace_representation) {
1369 PrintF("adding to %d %s uses of %d %s: i%d d%d t%d\n", 1459 PrintF("adding to #%d Phi uses of #%d Phi: i%d d%d t%d\n",
1370 this->id(), 1460 id(), other->id(),
1371 this->Mnemonic(),
1372 other->id(),
1373 other->Mnemonic(),
1374 other->non_phi_uses_[Representation::kInteger32], 1461 other->non_phi_uses_[Representation::kInteger32],
1375 other->non_phi_uses_[Representation::kDouble], 1462 other->non_phi_uses_[Representation::kDouble],
1376 other->non_phi_uses_[Representation::kTagged]); 1463 other->non_phi_uses_[Representation::kTagged]);
1377 } 1464 }
1378 1465
1379 for (int i = 0; i < Representation::kNumRepresentations; i++) { 1466 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1380 indirect_uses_[i] += other->non_phi_uses_[i]; 1467 indirect_uses_[i] += other->non_phi_uses_[i];
1381 } 1468 }
1382 } 1469 }
1383 1470
1384 1471
1385 void HPhi::AddIndirectUsesTo(int* dest) { 1472 void HPhi::AddIndirectUsesTo(int* dest) {
1386 for (int i = 0; i < Representation::kNumRepresentations; i++) { 1473 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1387 dest[i] += indirect_uses_[i]; 1474 dest[i] += indirect_uses_[i];
1388 } 1475 }
1389 } 1476 }
1390 1477
1391 1478
1392 void HPhi::ResetInteger32Uses() { 1479 void HSimulate::MergeInto(HSimulate* other) {
1393 non_phi_uses_[Representation::kInteger32] = 0; 1480 for (int i = 0; i < values_.length(); ++i) {
1394 indirect_uses_[Representation::kInteger32] = 0; 1481 HValue* value = values_[i];
1482 if (HasAssignedIndexAt(i)) {
1483 other->AddAssignedValue(GetAssignedIndexAt(i), value);
1484 } else {
1485 if (other->pop_count_ > 0) {
1486 other->pop_count_--;
1487 } else {
1488 other->AddPushedValue(value);
1489 }
1490 }
1491 }
1492 other->pop_count_ += pop_count();
1395 } 1493 }
1396 1494
1397 1495
1398 void HSimulate::PrintDataTo(StringStream* stream) { 1496 void HSimulate::PrintDataTo(StringStream* stream) {
1399 stream->Add("id=%d", ast_id().ToInt()); 1497 stream->Add("id=%d", ast_id().ToInt());
1400 if (pop_count_ > 0) stream->Add(" pop %d", pop_count_); 1498 if (pop_count_ > 0) stream->Add(" pop %d", pop_count_);
1401 if (values_.length() > 0) { 1499 if (values_.length() > 0) {
1402 if (pop_count_ > 0) stream->Add(" /"); 1500 if (pop_count_ > 0) stream->Add(" /");
1403 for (int i = 0; i < values_.length(); ++i) { 1501 for (int i = values_.length() - 1; i >= 0; --i) {
1404 if (i > 0) stream->Add(","); 1502 if (i > 0) stream->Add(",");
1405 if (HasAssignedIndexAt(i)) { 1503 if (HasAssignedIndexAt(i)) {
1406 stream->Add(" var[%d] = ", GetAssignedIndexAt(i)); 1504 stream->Add(" var[%d] = ", GetAssignedIndexAt(i));
1407 } else { 1505 } else {
1408 stream->Add(" push "); 1506 stream->Add(" push ");
1409 } 1507 }
1410 values_[i]->PrintNameTo(stream); 1508 values_[i]->PrintNameTo(stream);
1411 } 1509 }
1412 } 1510 }
1413 } 1511 }
(...skipping 18 matching lines...) Expand all
1432 static bool IsInteger32(double value) { 1530 static bool IsInteger32(double value) {
1433 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); 1531 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value));
1434 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); 1532 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value);
1435 } 1533 }
1436 1534
1437 1535
1438 HConstant::HConstant(Handle<Object> handle, Representation r) 1536 HConstant::HConstant(Handle<Object> handle, Representation r)
1439 : handle_(handle), 1537 : handle_(handle),
1440 has_int32_value_(false), 1538 has_int32_value_(false),
1441 has_double_value_(false) { 1539 has_double_value_(false) {
1442 set_representation(r);
1443 SetFlag(kUseGVN); 1540 SetFlag(kUseGVN);
1444 if (handle_->IsNumber()) { 1541 if (handle_->IsNumber()) {
1445 double n = handle_->Number(); 1542 double n = handle_->Number();
1446 has_int32_value_ = IsInteger32(n); 1543 has_int32_value_ = IsInteger32(n);
1447 int32_value_ = DoubleToInt32(n); 1544 int32_value_ = DoubleToInt32(n);
1448 double_value_ = n; 1545 double_value_ = n;
1449 has_double_value_ = true; 1546 has_double_value_ = true;
1450 } 1547 }
1548 if (r.IsNone()) {
1549 if (has_int32_value_) {
1550 r = Representation::Integer32();
1551 } else if (has_double_value_) {
1552 r = Representation::Double();
1553 } else {
1554 r = Representation::Tagged();
1555 }
1556 }
1557 set_representation(r);
1451 } 1558 }
1452 1559
1453 1560
1454 HConstant::HConstant(int32_t integer_value, Representation r) 1561 HConstant::HConstant(int32_t integer_value, Representation r)
1455 : has_int32_value_(true), 1562 : has_int32_value_(true),
1456 has_double_value_(true), 1563 has_double_value_(true),
1457 int32_value_(integer_value), 1564 int32_value_(integer_value),
1458 double_value_(FastI2D(integer_value)) { 1565 double_value_(FastI2D(integer_value)) {
1459 set_representation(r); 1566 set_representation(r);
1460 SetFlag(kUseGVN); 1567 SetFlag(kUseGVN);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 1646
1540 void HBinaryOperation::PrintDataTo(StringStream* stream) { 1647 void HBinaryOperation::PrintDataTo(StringStream* stream) {
1541 left()->PrintNameTo(stream); 1648 left()->PrintNameTo(stream);
1542 stream->Add(" "); 1649 stream->Add(" ");
1543 right()->PrintNameTo(stream); 1650 right()->PrintNameTo(stream);
1544 if (CheckFlag(kCanOverflow)) stream->Add(" !"); 1651 if (CheckFlag(kCanOverflow)) stream->Add(" !");
1545 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); 1652 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
1546 } 1653 }
1547 1654
1548 1655
1656 Representation HBinaryOperation::RepresentationFromInputs() {
1657 // Determine the worst case of observed input representations and
1658 // the currently assumed output representation.
1659 Representation rep = representation();
1660 if (observed_output_representation_.is_more_general_than(rep)) {
1661 rep = observed_output_representation_;
1662 }
1663 for (int i = 1; i <= 2; ++i) {
1664 Representation input_rep = observed_input_representation(i);
1665 if (input_rep.is_more_general_than(rep)) rep = input_rep;
1666 }
1667 // If any of the actual input representation is more general than what we
1668 // have so far but not Tagged, use that representation instead.
1669 Representation left_rep = left()->representation();
1670 Representation right_rep = right()->representation();
1671
1672 if (left_rep.is_more_general_than(rep) &&
1673 left()->CheckFlag(kFlexibleRepresentation)) {
1674 rep = left_rep;
1675 }
1676 if (right_rep.is_more_general_than(rep) &&
1677 right()->CheckFlag(kFlexibleRepresentation)) {
1678 rep = right_rep;
1679 }
1680 return rep;
1681 }
1682
1683
1684 void HBinaryOperation::AssumeRepresentation(Representation r) {
1685 set_observed_input_representation(r, r);
1686 HValue::AssumeRepresentation(r);
1687 }
1688
1689
1549 Range* HBitwise::InferRange(Zone* zone) { 1690 Range* HBitwise::InferRange(Zone* zone) {
1550 if (op() == Token::BIT_XOR) return HValue::InferRange(zone); 1691 if (op() == Token::BIT_XOR) return HValue::InferRange(zone);
1551 const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff); 1692 const int32_t kDefaultMask = static_cast<int32_t>(0xffffffff);
1552 int32_t left_mask = (left()->range() != NULL) 1693 int32_t left_mask = (left()->range() != NULL)
1553 ? left()->range()->Mask() 1694 ? left()->range()->Mask()
1554 : kDefaultMask; 1695 : kDefaultMask;
1555 int32_t right_mask = (right()->range() != NULL) 1696 int32_t right_mask = (right()->range() != NULL)
1556 ? right()->range()->Mask() 1697 ? right()->range()->Mask()
1557 : kDefaultMask; 1698 : kDefaultMask;
1558 int32_t result_mask = (op() == Token::BIT_AND) 1699 int32_t result_mask = (op() == Token::BIT_AND)
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 right()->PrintNameTo(stream); 1811 right()->PrintNameTo(stream);
1671 HControlInstruction::PrintDataTo(stream); 1812 HControlInstruction::PrintDataTo(stream);
1672 } 1813 }
1673 1814
1674 1815
1675 void HGoto::PrintDataTo(StringStream* stream) { 1816 void HGoto::PrintDataTo(StringStream* stream) {
1676 stream->Add("B%d", SuccessorAt(0)->block_id()); 1817 stream->Add("B%d", SuccessorAt(0)->block_id());
1677 } 1818 }
1678 1819
1679 1820
1680 void HCompareIDAndBranch::SetInputRepresentation(Representation r) { 1821 void HCompareIDAndBranch::InferRepresentation(HInferRepresentation* h_infer) {
1681 input_representation_ = r; 1822 Representation rep = Representation::None();
1682 if (r.IsDouble()) { 1823 if (observed_input_representation(0).IsInteger32() &&
1824 observed_input_representation(1).IsInteger32()) {
1825 rep = Representation::Integer32();
1826 } else {
1827 rep = Representation::Double();
1683 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, === 1828 // According to the ES5 spec (11.9.3, 11.8.5), Equality comparisons (==, ===
1684 // and !=) have special handling of undefined, e.g. undefined == undefined 1829 // and !=) have special handling of undefined, e.g. undefined == undefined
1685 // is 'true'. Relational comparisons have a different semantic, first 1830 // is 'true'. Relational comparisons have a different semantic, first
1686 // calling ToPrimitive() on their arguments. The standard Crankshaft 1831 // calling ToPrimitive() on their arguments. The standard Crankshaft
1687 // tagged-to-double conversion to ensure the HCompareIDAndBranch's inputs 1832 // tagged-to-double conversion to ensure the HCompareIDAndBranch's inputs
1688 // are doubles caused 'undefined' to be converted to NaN. That's compatible 1833 // are doubles caused 'undefined' to be converted to NaN. That's compatible
1689 // out-of-the box with ordered relational comparisons (<, >, <=, 1834 // out-of-the box with ordered relational comparisons (<, >, <=,
1690 // >=). However, for equality comparisons (and for 'in' and 'instanceof'), 1835 // >=). However, for equality comparisons (and for 'in' and 'instanceof'),
1691 // it is not consistent with the spec. For example, it would cause undefined 1836 // it is not consistent with the spec. For example, it would cause undefined
1692 // == undefined (should be true) to be evaluated as NaN == NaN 1837 // == undefined (should be true) to be evaluated as NaN == NaN
1693 // (false). Therefore, any comparisons other than ordered relational 1838 // (false). Therefore, any comparisons other than ordered relational
1694 // comparisons must cause a deopt when one of their arguments is undefined. 1839 // comparisons must cause a deopt when one of their arguments is undefined.
1695 // See also v8:1434 1840 // See also v8:1434
1696 if (!Token::IsOrderedRelationalCompareOp(token_)) { 1841 if (!Token::IsOrderedRelationalCompareOp(token_)) {
1697 SetFlag(kDeoptimizeOnUndefined); 1842 SetFlag(kDeoptimizeOnUndefined);
1698 } 1843 }
1699 } else {
1700 ASSERT(r.IsInteger32());
1701 } 1844 }
1845 AssumeRepresentation(rep);
1702 } 1846 }
1703 1847
1704 1848
1705 void HParameter::PrintDataTo(StringStream* stream) { 1849 void HParameter::PrintDataTo(StringStream* stream) {
1706 stream->Add("%u", index()); 1850 stream->Add("%u", index());
1707 } 1851 }
1708 1852
1709 1853
1710 void HLoadNamedField::PrintDataTo(StringStream* stream) { 1854 void HLoadNamedField::PrintDataTo(StringStream* stream) {
1711 object()->PrintNameTo(stream); 1855 object()->PrintNameTo(stream);
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after
2454 } 2598 }
2455 2599
2456 2600
2457 void HBitwise::PrintDataTo(StringStream* stream) { 2601 void HBitwise::PrintDataTo(StringStream* stream) {
2458 stream->Add(Token::Name(op_)); 2602 stream->Add(Token::Name(op_));
2459 stream->Add(" "); 2603 stream->Add(" ");
2460 HBitwiseBinaryOperation::PrintDataTo(stream); 2604 HBitwiseBinaryOperation::PrintDataTo(stream);
2461 } 2605 }
2462 2606
2463 2607
2464 Representation HPhi::InferredRepresentation() { 2608 void HPhi::InferRepresentation(HInferRepresentation* h_infer) {
2609 HValue::InferRepresentation(h_infer);
2610 Representation new_rep = RepresentationFromUseRequirements();
2611 UpdateRepresentation(new_rep, h_infer, "use requirements");
2612 }
2613
2614
2615 Representation HPhi::RepresentationFromInputs() {
2465 bool double_occurred = false; 2616 bool double_occurred = false;
2466 bool int32_occurred = false; 2617 bool int32_occurred = false;
2467 for (int i = 0; i < OperandCount(); ++i) { 2618 for (int i = 0; i < OperandCount(); ++i) {
2468 HValue* value = OperandAt(i); 2619 HValue* value = OperandAt(i);
2469 if (value->IsUnknownOSRValue()) { 2620 if (value->IsUnknownOSRValue()) {
2470 HPhi* hint_value = HUnknownOSRValue::cast(value)->incoming_value(); 2621 HPhi* hint_value = HUnknownOSRValue::cast(value)->incoming_value();
2471 if (hint_value != NULL) { 2622 if (hint_value != NULL) {
2472 Representation hint = hint_value->representation(); 2623 Representation hint = hint_value->representation();
2624 if (hint.IsTagged()) return hint;
2473 if (hint.IsDouble()) double_occurred = true; 2625 if (hint.IsDouble()) double_occurred = true;
2474 if (hint.IsInteger32()) int32_occurred = true; 2626 if (hint.IsInteger32()) int32_occurred = true;
2475 } 2627 }
2476 continue; 2628 continue;
2477 } 2629 }
2478 if (value->representation().IsDouble()) double_occurred = true; 2630 if (value->representation().IsDouble()) double_occurred = true;
2479 if (value->representation().IsInteger32()) int32_occurred = true; 2631 if (value->representation().IsInteger32()) int32_occurred = true;
2480 if (value->representation().IsTagged()) { 2632 if (value->representation().IsTagged()) {
2481 if (value->IsConstant()) { 2633 if (value->IsConstant()) {
2482 HConstant* constant = HConstant::cast(value); 2634 HConstant* constant = HConstant::cast(value);
2483 if (constant->IsConvertibleToInteger()) { 2635 if (constant->IsConvertibleToInteger()) {
2484 int32_occurred = true; 2636 int32_occurred = true;
2485 } else if (constant->HasNumberValue()) { 2637 } else if (constant->HasNumberValue()) {
2486 double_occurred = true; 2638 double_occurred = true;
2487 } else { 2639 } else {
2488 return Representation::Tagged(); 2640 return Representation::Tagged();
2489 } 2641 }
2490 } else { 2642 } else {
2491 return Representation::Tagged(); 2643 if (value->IsPhi() && !IsConvertibleToInteger()) {
2644 return Representation::Tagged();
2645 }
2492 } 2646 }
2493 } 2647 }
2494 } 2648 }
2495 2649
2496 if (double_occurred) return Representation::Double(); 2650 if (double_occurred) return Representation::Double();
2497 2651
2498 if (int32_occurred) return Representation::Integer32(); 2652 if (int32_occurred) return Representation::Integer32();
2499 2653
2500 return Representation::None(); 2654 return Representation::None();
2501 } 2655 }
2502 2656
2503 2657
2658 Representation HPhi::RepresentationFromUseRequirements() {
2659 Representation all_uses_require = Representation::None();
2660 bool all_uses_require_the_same = true;
2661 for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
2662 // We check for observed_input_representation elsewhere.
2663 Representation use_rep =
2664 it.value()->RequiredInputRepresentation(it.index());
2665 // No useful info from this use -> look at the next one.
2666 if (use_rep.IsNone()) {
2667 continue;
2668 }
2669 if (use_rep.Equals(all_uses_require)) {
2670 continue;
2671 }
2672 // This use's representation contradicts what we've seen so far.
2673 if (!all_uses_require.IsNone()) {
2674 ASSERT(!use_rep.Equals(all_uses_require));
2675 all_uses_require_the_same = false;
2676 break;
2677 }
2678 // Otherwise, initialize observed representation.
2679 all_uses_require = use_rep;
2680 }
2681 if (all_uses_require_the_same) {
2682 return all_uses_require;
2683 }
2684
2685 return Representation::None();
2686 }
2687
2688
2504 // Node-specific verification code is only included in debug mode. 2689 // Node-specific verification code is only included in debug mode.
2505 #ifdef DEBUG 2690 #ifdef DEBUG
2506 2691
2507 void HPhi::Verify() { 2692 void HPhi::Verify() {
2508 ASSERT(OperandCount() == block()->predecessors()->length()); 2693 ASSERT(OperandCount() == block()->predecessors()->length());
2509 for (int i = 0; i < OperandCount(); ++i) { 2694 for (int i = 0; i < OperandCount(); ++i) {
2510 HValue* value = OperandAt(i); 2695 HValue* value = OperandAt(i);
2511 HBasicBlock* defining_block = value->block(); 2696 HBasicBlock* defining_block = value->block();
2512 HBasicBlock* predecessor_block = block()->predecessors()->at(i); 2697 HBasicBlock* predecessor_block = block()->predecessors()->at(i);
2513 ASSERT(defining_block == predecessor_block || 2698 ASSERT(defining_block == predecessor_block ||
(...skipping 21 matching lines...) Expand all
2535 2720
2536 2721
2537 void HCheckFunction::Verify() { 2722 void HCheckFunction::Verify() {
2538 HInstruction::Verify(); 2723 HInstruction::Verify();
2539 ASSERT(HasNoUses()); 2724 ASSERT(HasNoUses());
2540 } 2725 }
2541 2726
2542 #endif 2727 #endif
2543 2728
2544 } } // namespace v8::internal 2729 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698