OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/linkage.h" | 5 #include "src/compiler/linkage.h" |
6 #include "src/compiler/register-allocator.h" | 6 #include "src/compiler/register-allocator.h" |
7 #include "src/string-stream.h" | 7 #include "src/string-stream.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 assigned_register_(kInvalidAssignment), | 104 assigned_register_(kInvalidAssignment), |
105 last_interval_(NULL), | 105 last_interval_(NULL), |
106 first_interval_(NULL), | 106 first_interval_(NULL), |
107 first_pos_(NULL), | 107 first_pos_(NULL), |
108 parent_(NULL), | 108 parent_(NULL), |
109 next_(NULL), | 109 next_(NULL), |
110 current_interval_(NULL), | 110 current_interval_(NULL), |
111 last_processed_use_(NULL), | 111 last_processed_use_(NULL), |
112 current_hint_operand_(NULL), | 112 current_hint_operand_(NULL), |
113 spill_operand_(new (zone) InstructionOperand()), | 113 spill_operand_(new (zone) InstructionOperand()), |
114 spill_start_index_(kMaxInt) {} | 114 spill_start_index_(kMaxInt), |
| 115 spill_range_(NULL) {} |
115 | 116 |
116 | 117 |
117 void LiveRange::set_assigned_register(int reg, Zone* zone) { | 118 void LiveRange::set_assigned_register(int reg, Zone* zone) { |
118 DCHECK(!HasRegisterAssigned() && !IsSpilled()); | 119 DCHECK(!HasRegisterAssigned() && !IsSpilled()); |
119 assigned_register_ = reg; | 120 assigned_register_ = reg; |
120 ConvertOperands(zone); | 121 if (spill_range_ == nullptr) { |
| 122 ConvertOperands(zone); |
| 123 } |
121 } | 124 } |
122 | 125 |
123 | 126 |
124 void LiveRange::MakeSpilled(Zone* zone) { | 127 void LiveRange::MakeSpilled(Zone* zone) { |
125 DCHECK(!IsSpilled()); | 128 DCHECK(!IsSpilled()); |
126 DCHECK(TopLevel()->HasAllocatedSpillOperand()); | 129 DCHECK(TopLevel()->HasAllocatedSpillOperand()); |
127 spilled_ = true; | 130 spilled_ = true; |
128 assigned_register_ = kInvalidAssignment; | 131 assigned_register_ = kInvalidAssignment; |
129 ConvertOperands(zone); | 132 ConvertOperands(zone); |
130 } | 133 } |
131 | 134 |
132 | 135 |
133 bool LiveRange::HasAllocatedSpillOperand() const { | 136 bool LiveRange::HasAllocatedSpillOperand() const { |
134 DCHECK(spill_operand_ != NULL); | 137 DCHECK(spill_operand_ != NULL); |
135 return !spill_operand_->IsIgnored(); | 138 return !spill_operand_->IsIgnored() || spill_range_ != NULL; |
136 } | 139 } |
137 | 140 |
138 | 141 |
139 void LiveRange::SetSpillOperand(InstructionOperand* operand) { | 142 void LiveRange::SetSpillOperand(InstructionOperand* operand) { |
140 DCHECK(!operand->IsUnallocated()); | 143 DCHECK(!operand->IsUnallocated()); |
141 DCHECK(spill_operand_ != NULL); | 144 DCHECK(spill_operand_ != NULL); |
142 DCHECK(spill_operand_->IsIgnored()); | 145 DCHECK(spill_operand_->IsIgnored()); |
143 spill_operand_->ConvertTo(operand->kind(), operand->index()); | 146 spill_operand_->ConvertTo(operand->kind(), operand->index()); |
144 } | 147 } |
145 | 148 |
146 | 149 |
| 150 void LiveRange::CommitSpillOperand(InstructionOperand* operand) { |
| 151 DCHECK(spill_range_ != NULL); |
| 152 DCHECK(!IsChild()); |
| 153 spill_range_ = NULL; |
| 154 SetSpillOperand(operand); |
| 155 for (LiveRange* range = this; range != NULL; range = range->next()) { |
| 156 if (range->IsSpilled()) { |
| 157 range->ConvertUsesToOperand(operand); |
| 158 } |
| 159 } |
| 160 } |
| 161 |
| 162 |
147 UsePosition* LiveRange::NextUsePosition(LifetimePosition start) { | 163 UsePosition* LiveRange::NextUsePosition(LifetimePosition start) { |
148 UsePosition* use_pos = last_processed_use_; | 164 UsePosition* use_pos = last_processed_use_; |
149 if (use_pos == NULL) use_pos = first_pos(); | 165 if (use_pos == NULL) use_pos = first_pos(); |
150 while (use_pos != NULL && use_pos->pos().Value() < start.Value()) { | 166 while (use_pos != NULL && use_pos->pos().Value() < start.Value()) { |
151 use_pos = use_pos->next(); | 167 use_pos = use_pos->next(); |
152 } | 168 } |
153 last_processed_use_ = use_pos; | 169 last_processed_use_ = use_pos; |
154 return use_pos; | 170 return use_pos; |
155 } | 171 } |
156 | 172 |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 use_pos->next_ = prev->next_; | 449 use_pos->next_ = prev->next_; |
434 prev->next_ = use_pos; | 450 prev->next_ = use_pos; |
435 } | 451 } |
436 | 452 |
437 if (prev_hint == NULL && use_pos->HasHint()) { | 453 if (prev_hint == NULL && use_pos->HasHint()) { |
438 current_hint_operand_ = hint; | 454 current_hint_operand_ = hint; |
439 } | 455 } |
440 } | 456 } |
441 | 457 |
442 | 458 |
443 void LiveRange::ConvertOperands(Zone* zone) { | 459 void LiveRange::ConvertUsesToOperand(InstructionOperand* op) { |
444 InstructionOperand* op = CreateAssignedOperand(zone); | |
445 UsePosition* use_pos = first_pos(); | 460 UsePosition* use_pos = first_pos(); |
446 while (use_pos != NULL) { | 461 while (use_pos != NULL) { |
447 DCHECK(Start().Value() <= use_pos->pos().Value() && | 462 DCHECK(Start().Value() <= use_pos->pos().Value() && |
448 use_pos->pos().Value() <= End().Value()); | 463 use_pos->pos().Value() <= End().Value()); |
449 | 464 |
450 if (use_pos->HasOperand()) { | 465 if (use_pos->HasOperand()) { |
451 DCHECK(op->IsRegister() || op->IsDoubleRegister() || | 466 DCHECK(op->IsRegister() || op->IsDoubleRegister() || |
452 !use_pos->RequiresRegister()); | 467 !use_pos->RequiresRegister()); |
453 use_pos->operand()->ConvertTo(op->kind(), op->index()); | 468 use_pos->operand()->ConvertTo(op->kind(), op->index()); |
454 } | 469 } |
455 use_pos = use_pos->next(); | 470 use_pos = use_pos->next(); |
456 } | 471 } |
457 } | 472 } |
458 | 473 |
459 | 474 |
| 475 void LiveRange::ConvertOperands(Zone* zone) { |
| 476 ConvertUsesToOperand(CreateAssignedOperand(zone)); |
| 477 } |
| 478 |
| 479 |
460 bool LiveRange::CanCover(LifetimePosition position) const { | 480 bool LiveRange::CanCover(LifetimePosition position) const { |
461 if (IsEmpty()) return false; | 481 if (IsEmpty()) return false; |
462 return Start().Value() <= position.Value() && | 482 return Start().Value() <= position.Value() && |
463 position.Value() < End().Value(); | 483 position.Value() < End().Value(); |
464 } | 484 } |
465 | 485 |
466 | 486 |
467 bool LiveRange::Covers(LifetimePosition position) { | 487 bool LiveRange::Covers(LifetimePosition position) { |
468 if (!CanCover(position)) return false; | 488 if (!CanCover(position)) return false; |
469 UseInterval* start_search = FirstSearchIntervalForPosition(position); | 489 UseInterval* start_search = FirstSearchIntervalForPosition(position); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 live_in_sets_(code->InstructionBlockCount(), local_zone()), | 535 live_in_sets_(code->InstructionBlockCount(), local_zone()), |
516 live_ranges_(code->VirtualRegisterCount() * 2, local_zone()), | 536 live_ranges_(code->VirtualRegisterCount() * 2, local_zone()), |
517 fixed_live_ranges_(this->config()->num_general_registers(), NULL, | 537 fixed_live_ranges_(this->config()->num_general_registers(), NULL, |
518 local_zone()), | 538 local_zone()), |
519 fixed_double_live_ranges_(this->config()->num_double_registers(), NULL, | 539 fixed_double_live_ranges_(this->config()->num_double_registers(), NULL, |
520 local_zone()), | 540 local_zone()), |
521 unhandled_live_ranges_(code->VirtualRegisterCount() * 2, local_zone()), | 541 unhandled_live_ranges_(code->VirtualRegisterCount() * 2, local_zone()), |
522 active_live_ranges_(8, local_zone()), | 542 active_live_ranges_(8, local_zone()), |
523 inactive_live_ranges_(8, local_zone()), | 543 inactive_live_ranges_(8, local_zone()), |
524 reusable_slots_(8, local_zone()), | 544 reusable_slots_(8, local_zone()), |
| 545 spill_ranges_(8, local_zone()), |
525 mode_(UNALLOCATED_REGISTERS), | 546 mode_(UNALLOCATED_REGISTERS), |
526 num_registers_(-1), | 547 num_registers_(-1), |
527 allocation_ok_(true) { | 548 allocation_ok_(true) { |
528 DCHECK(this->config()->num_general_registers() <= | 549 DCHECK(this->config()->num_general_registers() <= |
529 RegisterConfiguration::kMaxGeneralRegisters); | 550 RegisterConfiguration::kMaxGeneralRegisters); |
530 DCHECK(this->config()->num_double_registers() <= | 551 DCHECK(this->config()->num_double_registers() <= |
531 RegisterConfiguration::kMaxDoubleRegisters); | 552 RegisterConfiguration::kMaxDoubleRegisters); |
532 // TryAllocateFreeReg and AllocateBlockedReg assume this | 553 // TryAllocateFreeReg and AllocateBlockedReg assume this |
533 // when allocating local arrays. | 554 // when allocating local arrays. |
534 DCHECK(this->config()->num_double_registers() >= | 555 DCHECK(this->config()->num_double_registers() >= |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 move->AddMove(cur.source(), to, code_zone()); | 765 move->AddMove(cur.source(), to, code_zone()); |
745 return; | 766 return; |
746 } | 767 } |
747 } | 768 } |
748 } | 769 } |
749 } | 770 } |
750 move->AddMove(from, to, code_zone()); | 771 move->AddMove(from, to, code_zone()); |
751 } | 772 } |
752 | 773 |
753 | 774 |
| 775 static bool AreUseIntervalsIntersecting(UseInterval* interval1, |
| 776 UseInterval* interval2) { |
| 777 while (interval1 != NULL && interval2 != NULL) { |
| 778 if (interval1->start().Value() < interval2->start().Value()) { |
| 779 if (interval1->end().Value() >= interval2->start().Value()) { |
| 780 return true; |
| 781 } |
| 782 interval1 = interval1->next(); |
| 783 } else { |
| 784 if (interval2->end().Value() >= interval1->start().Value()) { |
| 785 return true; |
| 786 } |
| 787 interval2 = interval2->next(); |
| 788 } |
| 789 } |
| 790 return false; |
| 791 } |
| 792 |
| 793 |
| 794 SpillRange::SpillRange(LiveRange* range, int id, Zone* zone) |
| 795 : id_(id), live_ranges_(1, zone), end_position_(range->End()) { |
| 796 UseInterval* src = range->first_interval(); |
| 797 UseInterval* result = NULL; |
| 798 UseInterval* node = NULL; |
| 799 // Copy the nodes |
| 800 while (src != NULL) { |
| 801 UseInterval* new_node = new (zone) UseInterval(src->start(), src->end()); |
| 802 if (result == NULL) { |
| 803 result = new_node; |
| 804 } else { |
| 805 node->set_next(new_node); |
| 806 } |
| 807 node = new_node; |
| 808 src = src->next(); |
| 809 } |
| 810 use_interval_ = result; |
| 811 live_ranges_.Add(range, zone); |
| 812 DCHECK(range->GetSpillRange() == NULL); |
| 813 range->SetSpillRange(this); |
| 814 } |
| 815 |
| 816 |
| 817 bool SpillRange::IsIntersectingWith(SpillRange* other) { |
| 818 if (End().Value() <= other->use_interval_->start().Value() || |
| 819 other->End().Value() <= use_interval_->start().Value()) { |
| 820 return false; |
| 821 } |
| 822 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); |
| 823 } |
| 824 |
| 825 |
| 826 bool SpillRange::TryMerge(SpillRange* other, Zone* zone) { |
| 827 if (Kind() == other->Kind() && |
| 828 !AreUseIntervalsIntersecting(use_interval_, other->use_interval_)) { |
| 829 if (End().Value() < other->End().Value()) { |
| 830 end_position_ = other->End(); |
| 831 } |
| 832 |
| 833 MergeDisjointIntervals(other->use_interval_, zone); |
| 834 other->use_interval_ = NULL; |
| 835 |
| 836 for (int i = 0; i < other->live_ranges_.length(); i++) { |
| 837 DCHECK(other->live_ranges_.at(i)->GetSpillRange() == other); |
| 838 other->live_ranges_.at(i)->SetSpillRange(this); |
| 839 } |
| 840 |
| 841 live_ranges_.AddAll(other->live_ranges_, zone); |
| 842 other->live_ranges_.Clear(); |
| 843 |
| 844 return true; |
| 845 } |
| 846 return false; |
| 847 } |
| 848 |
| 849 |
| 850 void SpillRange::SetOperand(InstructionOperand* op) { |
| 851 for (int i = 0; i < live_ranges_.length(); i++) { |
| 852 DCHECK(live_ranges_.at(i)->GetSpillRange() == this); |
| 853 live_ranges_.at(i)->CommitSpillOperand(op); |
| 854 } |
| 855 } |
| 856 |
| 857 |
| 858 void SpillRange::MergeDisjointIntervals(UseInterval* other, Zone* zone) { |
| 859 UseInterval* tail = NULL; |
| 860 UseInterval* current = use_interval_; |
| 861 while (other != NULL) { |
| 862 // Make sure the 'current' list starts first |
| 863 if (current == NULL || current->start().Value() > other->start().Value()) { |
| 864 std::swap(current, other); |
| 865 } |
| 866 |
| 867 // Check disjointness |
| 868 DCHECK(other == NULL || current->end().Value() <= other->start().Value()); |
| 869 |
| 870 // Append the 'current' node to the result accumulator and move forward |
| 871 if (tail == NULL) { |
| 872 use_interval_ = current; |
| 873 } else { |
| 874 tail->set_next(current); |
| 875 } |
| 876 tail = current; |
| 877 current = current->next(); |
| 878 } |
| 879 // Other list is empty => we are done |
| 880 } |
| 881 |
| 882 |
| 883 void RegisterAllocator::ReuseSpillSlots() { |
| 884 // Merge disjoint spill ranges |
| 885 for (int i = 0; i < spill_ranges_.length(); i++) { |
| 886 SpillRange* range = spill_ranges_.at(i); |
| 887 if (!range->IsEmpty()) { |
| 888 for (int j = i + 1; j < spill_ranges_.length(); j++) { |
| 889 SpillRange* other = spill_ranges_.at(j); |
| 890 if (!other->IsEmpty()) { |
| 891 range->TryMerge(spill_ranges_.at(j), local_zone()); |
| 892 } |
| 893 } |
| 894 } |
| 895 } |
| 896 |
| 897 // Allocate slots for the merged spill ranges. |
| 898 for (int i = 0; i < spill_ranges_.length(); i++) { |
| 899 SpillRange* range = spill_ranges_.at(i); |
| 900 if (!range->IsEmpty()) { |
| 901 // Allocate a new operand referring to the spill slot. |
| 902 RegisterKind kind = range->Kind(); |
| 903 int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS); |
| 904 InstructionOperand* op = nullptr; |
| 905 if (kind == DOUBLE_REGISTERS) { |
| 906 op = DoubleStackSlotOperand::Create(index, local_zone()); |
| 907 } else { |
| 908 DCHECK(kind == GENERAL_REGISTERS); |
| 909 op = StackSlotOperand::Create(index, local_zone()); |
| 910 } |
| 911 range->SetOperand(op); |
| 912 } |
| 913 } |
| 914 } |
| 915 |
| 916 |
| 917 SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { |
| 918 int spill_id = spill_ranges_.length(); |
| 919 SpillRange* spill_range = |
| 920 new (local_zone()) SpillRange(range, spill_id, local_zone()); |
| 921 spill_ranges_.Add(spill_range, local_zone()); |
| 922 return spill_range; |
| 923 } |
| 924 |
| 925 |
754 void RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) { | 926 void RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) { |
755 int start = block->first_instruction_index(); | 927 int start = block->first_instruction_index(); |
756 int end = block->last_instruction_index(); | 928 int end = block->last_instruction_index(); |
757 DCHECK_NE(-1, start); | 929 DCHECK_NE(-1, start); |
758 for (int i = start; i <= end; ++i) { | 930 for (int i = start; i <= end; ++i) { |
759 if (code()->IsGapAt(i)) { | 931 if (code()->IsGapAt(i)) { |
760 Instruction* instr = NULL; | 932 Instruction* instr = NULL; |
761 Instruction* prev_instr = NULL; | 933 Instruction* prev_instr = NULL; |
762 if (i < end) instr = InstructionAt(i + 1); | 934 if (i < end) instr = InstructionAt(i + 1); |
763 if (i > start) prev_instr = InstructionAt(i - 1); | 935 if (i > start) prev_instr = InstructionAt(i - 1); |
(...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1753 int len = unhandled_live_ranges_.length(); | 1925 int len = unhandled_live_ranges_.length(); |
1754 for (int i = 1; i < len; i++) { | 1926 for (int i = 1; i < len; i++) { |
1755 LiveRange* a = unhandled_live_ranges_.at(i - 1); | 1927 LiveRange* a = unhandled_live_ranges_.at(i - 1); |
1756 LiveRange* b = unhandled_live_ranges_.at(i); | 1928 LiveRange* b = unhandled_live_ranges_.at(i); |
1757 if (a->Start().Value() < b->Start().Value()) return false; | 1929 if (a->Start().Value() < b->Start().Value()) return false; |
1758 } | 1930 } |
1759 return true; | 1931 return true; |
1760 } | 1932 } |
1761 | 1933 |
1762 | 1934 |
1763 void RegisterAllocator::FreeSpillSlot(LiveRange* range) { | |
1764 // Check that we are the last range. | |
1765 if (range->next() != NULL) return; | |
1766 | |
1767 if (!range->TopLevel()->HasAllocatedSpillOperand()) return; | |
1768 | |
1769 InstructionOperand* spill_operand = range->TopLevel()->GetSpillOperand(); | |
1770 if (spill_operand->IsConstant()) return; | |
1771 if (spill_operand->index() >= 0) { | |
1772 reusable_slots_.Add(range, local_zone()); | |
1773 } | |
1774 } | |
1775 | |
1776 | |
1777 InstructionOperand* RegisterAllocator::TryReuseSpillSlot(LiveRange* range) { | |
1778 if (reusable_slots_.is_empty()) return NULL; | |
1779 if (reusable_slots_.first()->End().Value() > | |
1780 range->TopLevel()->Start().Value()) { | |
1781 return NULL; | |
1782 } | |
1783 InstructionOperand* result = | |
1784 reusable_slots_.first()->TopLevel()->GetSpillOperand(); | |
1785 reusable_slots_.Remove(0); | |
1786 return result; | |
1787 } | |
1788 | |
1789 | |
1790 void RegisterAllocator::ActiveToHandled(LiveRange* range) { | 1935 void RegisterAllocator::ActiveToHandled(LiveRange* range) { |
1791 DCHECK(active_live_ranges_.Contains(range)); | 1936 DCHECK(active_live_ranges_.Contains(range)); |
1792 active_live_ranges_.RemoveElement(range); | 1937 active_live_ranges_.RemoveElement(range); |
1793 TraceAlloc("Moving live range %d from active to handled\n", range->id()); | 1938 TraceAlloc("Moving live range %d from active to handled\n", range->id()); |
1794 FreeSpillSlot(range); | |
1795 } | 1939 } |
1796 | 1940 |
1797 | 1941 |
1798 void RegisterAllocator::ActiveToInactive(LiveRange* range) { | 1942 void RegisterAllocator::ActiveToInactive(LiveRange* range) { |
1799 DCHECK(active_live_ranges_.Contains(range)); | 1943 DCHECK(active_live_ranges_.Contains(range)); |
1800 active_live_ranges_.RemoveElement(range); | 1944 active_live_ranges_.RemoveElement(range); |
1801 inactive_live_ranges_.Add(range, local_zone()); | 1945 inactive_live_ranges_.Add(range, local_zone()); |
1802 TraceAlloc("Moving live range %d from active to inactive\n", range->id()); | 1946 TraceAlloc("Moving live range %d from active to inactive\n", range->id()); |
1803 } | 1947 } |
1804 | 1948 |
1805 | 1949 |
1806 void RegisterAllocator::InactiveToHandled(LiveRange* range) { | 1950 void RegisterAllocator::InactiveToHandled(LiveRange* range) { |
1807 DCHECK(inactive_live_ranges_.Contains(range)); | 1951 DCHECK(inactive_live_ranges_.Contains(range)); |
1808 inactive_live_ranges_.RemoveElement(range); | 1952 inactive_live_ranges_.RemoveElement(range); |
1809 TraceAlloc("Moving live range %d from inactive to handled\n", range->id()); | 1953 TraceAlloc("Moving live range %d from inactive to handled\n", range->id()); |
1810 FreeSpillSlot(range); | |
1811 } | 1954 } |
1812 | 1955 |
1813 | 1956 |
1814 void RegisterAllocator::InactiveToActive(LiveRange* range) { | 1957 void RegisterAllocator::InactiveToActive(LiveRange* range) { |
1815 DCHECK(inactive_live_ranges_.Contains(range)); | 1958 DCHECK(inactive_live_ranges_.Contains(range)); |
1816 inactive_live_ranges_.RemoveElement(range); | 1959 inactive_live_ranges_.RemoveElement(range); |
1817 active_live_ranges_.Add(range, local_zone()); | 1960 active_live_ranges_.Add(range, local_zone()); |
1818 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); | 1961 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); |
1819 } | 1962 } |
1820 | 1963 |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2185 } | 2328 } |
2186 } | 2329 } |
2187 | 2330 |
2188 | 2331 |
2189 void RegisterAllocator::Spill(LiveRange* range) { | 2332 void RegisterAllocator::Spill(LiveRange* range) { |
2190 DCHECK(!range->IsSpilled()); | 2333 DCHECK(!range->IsSpilled()); |
2191 TraceAlloc("Spilling live range %d\n", range->id()); | 2334 TraceAlloc("Spilling live range %d\n", range->id()); |
2192 LiveRange* first = range->TopLevel(); | 2335 LiveRange* first = range->TopLevel(); |
2193 | 2336 |
2194 if (!first->HasAllocatedSpillOperand()) { | 2337 if (!first->HasAllocatedSpillOperand()) { |
2195 InstructionOperand* op = TryReuseSpillSlot(range); | 2338 AssignSpillRangeToLiveRange(first); |
2196 if (op == NULL) { | |
2197 // Allocate a new operand referring to the spill slot. | |
2198 RegisterKind kind = range->Kind(); | |
2199 int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS); | |
2200 if (kind == DOUBLE_REGISTERS) { | |
2201 op = DoubleStackSlotOperand::Create(index, local_zone()); | |
2202 } else { | |
2203 DCHECK(kind == GENERAL_REGISTERS); | |
2204 op = StackSlotOperand::Create(index, local_zone()); | |
2205 } | |
2206 } | |
2207 first->SetSpillOperand(op); | |
2208 } | 2339 } |
2209 range->MakeSpilled(code_zone()); | 2340 range->MakeSpilled(code_zone()); |
2210 } | 2341 } |
2211 | 2342 |
2212 | 2343 |
2213 int RegisterAllocator::RegisterCount() const { return num_registers_; } | 2344 int RegisterAllocator::RegisterCount() const { return num_registers_; } |
2214 | 2345 |
2215 | 2346 |
2216 #ifdef DEBUG | 2347 #ifdef DEBUG |
2217 | 2348 |
(...skipping 15 matching lines...) Expand all Loading... |
2233 } else { | 2364 } else { |
2234 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2365 DCHECK(range->Kind() == GENERAL_REGISTERS); |
2235 assigned_registers_->Add(reg); | 2366 assigned_registers_->Add(reg); |
2236 } | 2367 } |
2237 range->set_assigned_register(reg, code_zone()); | 2368 range->set_assigned_register(reg, code_zone()); |
2238 } | 2369 } |
2239 | 2370 |
2240 } | 2371 } |
2241 } | 2372 } |
2242 } // namespace v8::internal::compiler | 2373 } // namespace v8::internal::compiler |
OLD | NEW |