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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/compiler/linkage.h" | 6 #include "src/compiler/linkage.h" |
7 #include "src/compiler/register-allocator.h" | 7 #include "src/compiler/register-allocator.h" |
8 #include "src/string-stream.h" | 8 #include "src/string-stream.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 if (output->IsDoubleRegister() && | 85 if (output->IsDoubleRegister() && |
86 LocationOperand::cast(output)->GetDoubleRegister().is(reg)) { | 86 LocationOperand::cast(output)->GetDoubleRegister().is(reg)) { |
87 return true; | 87 return true; |
88 } | 88 } |
89 } | 89 } |
90 return false; | 90 return false; |
91 } | 91 } |
92 | 92 |
93 | 93 |
94 // TODO(dcarney): fix frame to allow frame accesses to half size location. | 94 // TODO(dcarney): fix frame to allow frame accesses to half size location. |
95 int GetByteWidth(MachineType machine_type) { | 95 int GetByteWidth(MachineRepresentation rep) { |
96 DCHECK_EQ(RepresentationOf(machine_type), machine_type); | 96 switch (rep) { |
97 switch (machine_type) { | 97 case MachineRepresentation::kBit: |
98 case kRepBit: | 98 case MachineRepresentation::kWord8: |
99 case kRepWord8: | 99 case MachineRepresentation::kWord16: |
100 case kRepWord16: | 100 case MachineRepresentation::kWord32: |
101 case kRepWord32: | 101 case MachineRepresentation::kTagged: |
102 case kRepTagged: | |
103 return kPointerSize; | 102 return kPointerSize; |
104 case kRepFloat32: | 103 case MachineRepresentation::kFloat32: |
105 case kRepWord64: | 104 case MachineRepresentation::kWord64: |
106 case kRepFloat64: | 105 case MachineRepresentation::kFloat64: |
107 return 8; | 106 return 8; |
108 default: | 107 default: |
109 UNREACHABLE(); | 108 UNREACHABLE(); |
110 return 0; | 109 return 0; |
111 } | 110 } |
112 } | 111 } |
113 | 112 |
114 } // namespace | 113 } // namespace |
115 | 114 |
116 | 115 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 os << 'e'; | 243 os << 'e'; |
245 } | 244 } |
246 return os; | 245 return os; |
247 } | 246 } |
248 | 247 |
249 | 248 |
250 const float LiveRange::kInvalidWeight = -1; | 249 const float LiveRange::kInvalidWeight = -1; |
251 const float LiveRange::kMaxWeight = std::numeric_limits<float>::max(); | 250 const float LiveRange::kMaxWeight = std::numeric_limits<float>::max(); |
252 | 251 |
253 | 252 |
254 LiveRange::LiveRange(int relative_id, MachineType machine_type, | 253 LiveRange::LiveRange(int relative_id, MachineRepresentation rep, |
255 TopLevelLiveRange* top_level) | 254 TopLevelLiveRange* top_level) |
256 : relative_id_(relative_id), | 255 : relative_id_(relative_id), |
257 bits_(0), | 256 bits_(0), |
258 last_interval_(nullptr), | 257 last_interval_(nullptr), |
259 first_interval_(nullptr), | 258 first_interval_(nullptr), |
260 first_pos_(nullptr), | 259 first_pos_(nullptr), |
261 top_level_(top_level), | 260 top_level_(top_level), |
262 next_(nullptr), | 261 next_(nullptr), |
263 current_interval_(nullptr), | 262 current_interval_(nullptr), |
264 last_processed_use_(nullptr), | 263 last_processed_use_(nullptr), |
265 current_hint_position_(nullptr), | 264 current_hint_position_(nullptr), |
266 splitting_pointer_(nullptr), | 265 splitting_pointer_(nullptr), |
267 size_(kInvalidSize), | 266 size_(kInvalidSize), |
268 weight_(kInvalidWeight), | 267 weight_(kInvalidWeight), |
269 group_(nullptr) { | 268 group_(nullptr) { |
270 DCHECK(AllocatedOperand::IsSupportedMachineType(machine_type)); | 269 DCHECK(AllocatedOperand::IsSupportedRepresentation(rep)); |
271 bits_ = AssignedRegisterField::encode(kUnassignedRegister) | | 270 bits_ = AssignedRegisterField::encode(kUnassignedRegister) | |
272 MachineTypeField::encode(machine_type); | 271 RepresentationField::encode(rep); |
273 } | 272 } |
274 | 273 |
275 | 274 |
276 void LiveRange::Verify() const { | 275 void LiveRange::Verify() const { |
277 // Walk the positions, verifying that each is in an interval. | 276 // Walk the positions, verifying that each is in an interval. |
278 auto interval = first_interval_; | 277 auto interval = first_interval_; |
279 for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) { | 278 for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) { |
280 CHECK(Start() <= pos->pos()); | 279 CHECK(Start() <= pos->pos()); |
281 CHECK(pos->pos() <= End()); | 280 CHECK(pos->pos() <= End()); |
282 CHECK(interval != nullptr); | 281 CHECK(interval != nullptr); |
(...skipping 19 matching lines...) Expand all Loading... |
302 | 301 |
303 void LiveRange::Spill() { | 302 void LiveRange::Spill() { |
304 DCHECK(!spilled()); | 303 DCHECK(!spilled()); |
305 DCHECK(!TopLevel()->HasNoSpillType()); | 304 DCHECK(!TopLevel()->HasNoSpillType()); |
306 set_spilled(true); | 305 set_spilled(true); |
307 bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister); | 306 bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister); |
308 } | 307 } |
309 | 308 |
310 | 309 |
311 RegisterKind LiveRange::kind() const { | 310 RegisterKind LiveRange::kind() const { |
312 switch (RepresentationOf(machine_type())) { | 311 return IsFloatingPoint(representation()) ? DOUBLE_REGISTERS |
313 case kRepFloat32: | 312 : GENERAL_REGISTERS; |
314 case kRepFloat64: | |
315 return DOUBLE_REGISTERS; | |
316 default: | |
317 break; | |
318 } | |
319 return GENERAL_REGISTERS; | |
320 } | 313 } |
321 | 314 |
322 | 315 |
323 UsePosition* LiveRange::FirstHintPosition(int* register_index) const { | 316 UsePosition* LiveRange::FirstHintPosition(int* register_index) const { |
324 for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) { | 317 for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) { |
325 if (pos->HintRegister(register_index)) return pos; | 318 if (pos->HintRegister(register_index)) return pos; |
326 } | 319 } |
327 return nullptr; | 320 return nullptr; |
328 } | 321 } |
329 | 322 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 return use_pos->pos() > pos.NextStart().End(); | 383 return use_pos->pos() > pos.NextStart().End(); |
391 } | 384 } |
392 | 385 |
393 | 386 |
394 bool LiveRange::IsTopLevel() const { return top_level_ == this; } | 387 bool LiveRange::IsTopLevel() const { return top_level_ == this; } |
395 | 388 |
396 | 389 |
397 InstructionOperand LiveRange::GetAssignedOperand() const { | 390 InstructionOperand LiveRange::GetAssignedOperand() const { |
398 if (HasRegisterAssigned()) { | 391 if (HasRegisterAssigned()) { |
399 DCHECK(!spilled()); | 392 DCHECK(!spilled()); |
400 return AllocatedOperand(LocationOperand::REGISTER, machine_type(), | 393 return AllocatedOperand(LocationOperand::REGISTER, representation(), |
401 assigned_register()); | 394 assigned_register()); |
402 } | 395 } |
403 DCHECK(spilled()); | 396 DCHECK(spilled()); |
404 DCHECK(!HasRegisterAssigned()); | 397 DCHECK(!HasRegisterAssigned()); |
405 if (TopLevel()->HasSpillOperand()) { | 398 if (TopLevel()->HasSpillOperand()) { |
406 auto op = TopLevel()->GetSpillOperand(); | 399 auto op = TopLevel()->GetSpillOperand(); |
407 DCHECK(!op->IsUnallocated()); | 400 DCHECK(!op->IsUnallocated()); |
408 return *op; | 401 return *op; |
409 } | 402 } |
410 return TopLevel()->GetSpillRangeOperand(); | 403 return TopLevel()->GetSpillRangeOperand(); |
(...skipping 18 matching lines...) Expand all Loading... |
429 auto start = current_interval_ == nullptr ? LifetimePosition::Invalid() | 422 auto start = current_interval_ == nullptr ? LifetimePosition::Invalid() |
430 : current_interval_->start(); | 423 : current_interval_->start(); |
431 if (to_start_of->start() > start) { | 424 if (to_start_of->start() > start) { |
432 current_interval_ = to_start_of; | 425 current_interval_ = to_start_of; |
433 } | 426 } |
434 } | 427 } |
435 | 428 |
436 | 429 |
437 LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) { | 430 LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) { |
438 int new_id = TopLevel()->GetNextChildId(); | 431 int new_id = TopLevel()->GetNextChildId(); |
439 LiveRange* child = new (zone) LiveRange(new_id, machine_type(), TopLevel()); | 432 LiveRange* child = new (zone) LiveRange(new_id, representation(), TopLevel()); |
440 DetachAt(position, child, zone); | 433 DetachAt(position, child, zone); |
441 | 434 |
442 child->top_level_ = TopLevel(); | 435 child->top_level_ = TopLevel(); |
443 child->next_ = next_; | 436 child->next_ = next_; |
444 next_ = child; | 437 next_ = child; |
445 if (child->next() == nullptr) { | 438 if (child->next() == nullptr) { |
446 TopLevel()->set_last_child(child); | 439 TopLevel()->set_last_child(child); |
447 } | 440 } |
448 return child; | 441 return child; |
449 } | 442 } |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 struct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject { | 667 struct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject { |
675 SpillMoveInsertionList(int gap_index, InstructionOperand* operand, | 668 SpillMoveInsertionList(int gap_index, InstructionOperand* operand, |
676 SpillMoveInsertionList* next) | 669 SpillMoveInsertionList* next) |
677 : gap_index(gap_index), operand(operand), next(next) {} | 670 : gap_index(gap_index), operand(operand), next(next) {} |
678 const int gap_index; | 671 const int gap_index; |
679 InstructionOperand* const operand; | 672 InstructionOperand* const operand; |
680 SpillMoveInsertionList* const next; | 673 SpillMoveInsertionList* const next; |
681 }; | 674 }; |
682 | 675 |
683 | 676 |
684 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineType machine_type) | 677 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineRepresentation rep) |
685 : LiveRange(0, machine_type, this), | 678 : LiveRange(0, rep, this), |
686 vreg_(vreg), | 679 vreg_(vreg), |
687 last_child_id_(0), | 680 last_child_id_(0), |
688 splintered_from_(nullptr), | 681 splintered_from_(nullptr), |
689 spill_operand_(nullptr), | 682 spill_operand_(nullptr), |
690 spill_move_insertion_locations_(nullptr), | 683 spill_move_insertion_locations_(nullptr), |
691 spilled_in_deferred_blocks_(false), | 684 spilled_in_deferred_blocks_(false), |
692 spill_start_index_(kMaxInt), | 685 spill_start_index_(kMaxInt), |
693 last_child_(this), | 686 last_child_(this), |
694 last_pos_(nullptr), | 687 last_pos_(nullptr), |
695 splinter_(nullptr), | 688 splinter_(nullptr), |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) { | 783 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) { |
791 DCHECK(!HasSpillOperand()); | 784 DCHECK(!HasSpillOperand()); |
792 DCHECK(spill_range); | 785 DCHECK(spill_range); |
793 spill_range_ = spill_range; | 786 spill_range_ = spill_range; |
794 } | 787 } |
795 | 788 |
796 | 789 |
797 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const { | 790 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const { |
798 auto spill_range = GetSpillRange(); | 791 auto spill_range = GetSpillRange(); |
799 int index = spill_range->assigned_slot(); | 792 int index = spill_range->assigned_slot(); |
800 return AllocatedOperand(LocationOperand::STACK_SLOT, machine_type(), index); | 793 return AllocatedOperand(LocationOperand::STACK_SLOT, representation(), index); |
801 } | 794 } |
802 | 795 |
803 | 796 |
804 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, | 797 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, |
805 Zone* zone) { | 798 Zone* zone) { |
806 DCHECK(start != Start() || end != End()); | 799 DCHECK(start != Start() || end != End()); |
807 DCHECK(start < end); | 800 DCHECK(start < end); |
808 | 801 |
809 TopLevelLiveRange splinter_temp(-1, machine_type()); | 802 TopLevelLiveRange splinter_temp(-1, representation()); |
810 UsePosition* last_in_splinter = nullptr; | 803 UsePosition* last_in_splinter = nullptr; |
811 // Live ranges defined in deferred blocks stay in deferred blocks, so we | 804 // Live ranges defined in deferred blocks stay in deferred blocks, so we |
812 // don't need to splinter them. That means that start should always be | 805 // don't need to splinter them. That means that start should always be |
813 // after the beginning of the range. | 806 // after the beginning of the range. |
814 DCHECK(start > Start()); | 807 DCHECK(start > Start()); |
815 | 808 |
816 if (end >= End()) { | 809 if (end >= End()) { |
817 DCHECK(start > Start()); | 810 DCHECK(start > Start()); |
818 DetachAt(start, &splinter_temp, zone); | 811 DetachAt(start, &splinter_temp, zone); |
819 next_ = nullptr; | 812 next_ = nullptr; |
820 } else { | 813 } else { |
821 DCHECK(start < End() && Start() < end); | 814 DCHECK(start < End() && Start() < end); |
822 | 815 |
823 const int kInvalidId = std::numeric_limits<int>::max(); | 816 const int kInvalidId = std::numeric_limits<int>::max(); |
824 | 817 |
825 UsePosition* last = DetachAt(start, &splinter_temp, zone); | 818 UsePosition* last = DetachAt(start, &splinter_temp, zone); |
826 | 819 |
827 LiveRange end_part(kInvalidId, this->machine_type(), nullptr); | 820 LiveRange end_part(kInvalidId, this->representation(), nullptr); |
828 last_in_splinter = splinter_temp.DetachAt(end, &end_part, zone); | 821 last_in_splinter = splinter_temp.DetachAt(end, &end_part, zone); |
829 | 822 |
830 next_ = end_part.next_; | 823 next_ = end_part.next_; |
831 last_interval_->set_next(end_part.first_interval_); | 824 last_interval_->set_next(end_part.first_interval_); |
832 // The next splinter will happen either at or after the current interval. | 825 // The next splinter will happen either at or after the current interval. |
833 // We can optimize DetachAt by setting current_interval_ accordingly, | 826 // We can optimize DetachAt by setting current_interval_ accordingly, |
834 // which will then be picked up by FirstSearchIntervalForPosition. | 827 // which will then be picked up by FirstSearchIntervalForPosition. |
835 current_interval_ = last_interval_; | 828 current_interval_ = last_interval_; |
836 last_interval_ = end_part.last_interval_; | 829 last_interval_ = end_part.last_interval_; |
837 | 830 |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 interval = interval->next(); | 1074 interval = interval->next(); |
1082 } | 1075 } |
1083 os << "}"; | 1076 os << "}"; |
1084 return os; | 1077 return os; |
1085 } | 1078 } |
1086 | 1079 |
1087 | 1080 |
1088 SpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone) | 1081 SpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone) |
1089 : live_ranges_(zone), | 1082 : live_ranges_(zone), |
1090 assigned_slot_(kUnassignedSlot), | 1083 assigned_slot_(kUnassignedSlot), |
1091 byte_width_(GetByteWidth(parent->machine_type())), | 1084 byte_width_(GetByteWidth(parent->representation())), |
1092 kind_(parent->kind()) { | 1085 kind_(parent->kind()) { |
1093 // Spill ranges are created for top level, non-splintered ranges. This is so | 1086 // Spill ranges are created for top level, non-splintered ranges. This is so |
1094 // that, when merging decisions are made, we consider the full extent of the | 1087 // that, when merging decisions are made, we consider the full extent of the |
1095 // virtual register, and avoid clobbering it. | 1088 // virtual register, and avoid clobbering it. |
1096 DCHECK(!parent->IsSplinter()); | 1089 DCHECK(!parent->IsSplinter()); |
1097 UseInterval* result = nullptr; | 1090 UseInterval* result = nullptr; |
1098 UseInterval* node = nullptr; | 1091 UseInterval* node = nullptr; |
1099 // Copy the intervals for all ranges. | 1092 // Copy the intervals for all ranges. |
1100 for (LiveRange* range = parent; range != nullptr; range = range->next()) { | 1093 for (LiveRange* range = parent; range != nullptr; range = range->next()) { |
1101 auto src = range->first_interval(); | 1094 auto src = range->first_interval(); |
1102 while (src != nullptr) { | 1095 while (src != nullptr) { |
1103 auto new_node = new (zone) UseInterval(src->start(), src->end()); | 1096 auto new_node = new (zone) UseInterval(src->start(), src->end()); |
1104 if (result == nullptr) { | 1097 if (result == nullptr) { |
1105 result = new_node; | 1098 result = new_node; |
1106 } else { | 1099 } else { |
1107 node->set_next(new_node); | 1100 node->set_next(new_node); |
1108 } | 1101 } |
1109 node = new_node; | 1102 node = new_node; |
1110 src = src->next(); | 1103 src = src->next(); |
1111 } | 1104 } |
1112 } | 1105 } |
1113 use_interval_ = result; | 1106 use_interval_ = result; |
1114 live_ranges().push_back(parent); | 1107 live_ranges().push_back(parent); |
1115 end_position_ = node->end(); | 1108 end_position_ = node->end(); |
1116 parent->SetSpillRange(this); | 1109 parent->SetSpillRange(this); |
1117 } | 1110 } |
1118 | 1111 |
1119 | 1112 |
1120 int SpillRange::ByteWidth() const { | 1113 int SpillRange::ByteWidth() const { |
1121 return GetByteWidth(live_ranges_[0]->machine_type()); | 1114 return GetByteWidth(live_ranges_[0]->representation()); |
1122 } | 1115 } |
1123 | 1116 |
1124 | 1117 |
1125 bool SpillRange::IsIntersectingWith(SpillRange* other) const { | 1118 bool SpillRange::IsIntersectingWith(SpillRange* other) const { |
1126 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || | 1119 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || |
1127 this->End() <= other->use_interval_->start() || | 1120 this->End() <= other->use_interval_->start() || |
1128 other->End() <= this->use_interval_->start()) { | 1121 other->End() <= this->use_interval_->start()) { |
1129 return false; | 1122 return false; |
1130 } | 1123 } |
1131 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); | 1124 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1250 | 1243 |
1251 MoveOperands* RegisterAllocationData::AddGapMove( | 1244 MoveOperands* RegisterAllocationData::AddGapMove( |
1252 int index, Instruction::GapPosition position, | 1245 int index, Instruction::GapPosition position, |
1253 const InstructionOperand& from, const InstructionOperand& to) { | 1246 const InstructionOperand& from, const InstructionOperand& to) { |
1254 auto instr = code()->InstructionAt(index); | 1247 auto instr = code()->InstructionAt(index); |
1255 auto moves = instr->GetOrCreateParallelMove(position, code_zone()); | 1248 auto moves = instr->GetOrCreateParallelMove(position, code_zone()); |
1256 return moves->AddMove(from, to); | 1249 return moves->AddMove(from, to); |
1257 } | 1250 } |
1258 | 1251 |
1259 | 1252 |
1260 MachineType RegisterAllocationData::MachineTypeFor(int virtual_register) { | 1253 MachineRepresentation RegisterAllocationData::RepresentationFor( |
| 1254 int virtual_register) { |
1261 DCHECK_LT(virtual_register, code()->VirtualRegisterCount()); | 1255 DCHECK_LT(virtual_register, code()->VirtualRegisterCount()); |
1262 return code()->GetRepresentation(virtual_register); | 1256 return code()->GetRepresentation(virtual_register); |
1263 } | 1257 } |
1264 | 1258 |
1265 | 1259 |
1266 TopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) { | 1260 TopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) { |
1267 if (index >= static_cast<int>(live_ranges().size())) { | 1261 if (index >= static_cast<int>(live_ranges().size())) { |
1268 live_ranges().resize(index + 1, nullptr); | 1262 live_ranges().resize(index + 1, nullptr); |
1269 } | 1263 } |
1270 auto result = live_ranges()[index]; | 1264 auto result = live_ranges()[index]; |
1271 if (result == nullptr) { | 1265 if (result == nullptr) { |
1272 result = NewLiveRange(index, MachineTypeFor(index)); | 1266 result = NewLiveRange(index, RepresentationFor(index)); |
1273 live_ranges()[index] = result; | 1267 live_ranges()[index] = result; |
1274 } | 1268 } |
1275 return result; | 1269 return result; |
1276 } | 1270 } |
1277 | 1271 |
1278 | 1272 |
1279 TopLevelLiveRange* RegisterAllocationData::NewLiveRange( | 1273 TopLevelLiveRange* RegisterAllocationData::NewLiveRange( |
1280 int index, MachineType machine_type) { | 1274 int index, MachineRepresentation rep) { |
1281 return new (allocation_zone()) TopLevelLiveRange(index, machine_type); | 1275 return new (allocation_zone()) TopLevelLiveRange(index, rep); |
1282 } | 1276 } |
1283 | 1277 |
1284 | 1278 |
1285 int RegisterAllocationData::GetNextLiveRangeId() { | 1279 int RegisterAllocationData::GetNextLiveRangeId() { |
1286 int vreg = virtual_register_count_++; | 1280 int vreg = virtual_register_count_++; |
1287 if (vreg >= static_cast<int>(live_ranges().size())) { | 1281 if (vreg >= static_cast<int>(live_ranges().size())) { |
1288 live_ranges().resize(vreg + 1, nullptr); | 1282 live_ranges().resize(vreg + 1, nullptr); |
1289 } | 1283 } |
1290 return vreg; | 1284 return vreg; |
1291 } | 1285 } |
1292 | 1286 |
1293 | 1287 |
1294 TopLevelLiveRange* RegisterAllocationData::NextLiveRange( | 1288 TopLevelLiveRange* RegisterAllocationData::NextLiveRange( |
1295 MachineType machine_type) { | 1289 MachineRepresentation rep) { |
1296 int vreg = GetNextLiveRangeId(); | 1290 int vreg = GetNextLiveRangeId(); |
1297 TopLevelLiveRange* ret = NewLiveRange(vreg, machine_type); | 1291 TopLevelLiveRange* ret = NewLiveRange(vreg, rep); |
1298 return ret; | 1292 return ret; |
1299 } | 1293 } |
1300 | 1294 |
1301 | 1295 |
1302 RegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap( | 1296 RegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap( |
1303 const InstructionBlock* block, PhiInstruction* phi) { | 1297 const InstructionBlock* block, PhiInstruction* phi) { |
1304 auto map_value = new (allocation_zone()) | 1298 auto map_value = new (allocation_zone()) |
1305 RegisterAllocationData::PhiMapValue(phi, block, allocation_zone()); | 1299 RegisterAllocationData::PhiMapValue(phi, block, allocation_zone()); |
1306 auto res = | 1300 auto res = |
1307 phi_map_.insert(std::make_pair(phi->virtual_register(), map_value)); | 1301 phi_map_.insert(std::make_pair(phi->virtual_register(), map_value)); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1494 | 1488 |
1495 ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data) | 1489 ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data) |
1496 : data_(data) {} | 1490 : data_(data) {} |
1497 | 1491 |
1498 | 1492 |
1499 InstructionOperand* ConstraintBuilder::AllocateFixed( | 1493 InstructionOperand* ConstraintBuilder::AllocateFixed( |
1500 UnallocatedOperand* operand, int pos, bool is_tagged) { | 1494 UnallocatedOperand* operand, int pos, bool is_tagged) { |
1501 TRACE("Allocating fixed reg for op %d\n", operand->virtual_register()); | 1495 TRACE("Allocating fixed reg for op %d\n", operand->virtual_register()); |
1502 DCHECK(operand->HasFixedPolicy()); | 1496 DCHECK(operand->HasFixedPolicy()); |
1503 InstructionOperand allocated; | 1497 InstructionOperand allocated; |
1504 MachineType machine_type = InstructionSequence::DefaultRepresentation(); | 1498 MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); |
1505 int virtual_register = operand->virtual_register(); | 1499 int virtual_register = operand->virtual_register(); |
1506 if (virtual_register != InstructionOperand::kInvalidVirtualRegister) { | 1500 if (virtual_register != InstructionOperand::kInvalidVirtualRegister) { |
1507 machine_type = data()->MachineTypeFor(virtual_register); | 1501 rep = data()->RepresentationFor(virtual_register); |
1508 } | 1502 } |
1509 if (operand->HasFixedSlotPolicy()) { | 1503 if (operand->HasFixedSlotPolicy()) { |
1510 allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, machine_type, | 1504 allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, rep, |
1511 operand->fixed_slot_index()); | 1505 operand->fixed_slot_index()); |
1512 } else if (operand->HasFixedRegisterPolicy()) { | 1506 } else if (operand->HasFixedRegisterPolicy()) { |
1513 DCHECK(!IsFloatingPoint(machine_type)); | 1507 DCHECK(!IsFloatingPoint(rep)); |
1514 allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, | 1508 allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep, |
1515 operand->fixed_register_index()); | 1509 operand->fixed_register_index()); |
1516 } else if (operand->HasFixedDoubleRegisterPolicy()) { | 1510 } else if (operand->HasFixedDoubleRegisterPolicy()) { |
1517 DCHECK(IsFloatingPoint(machine_type)); | 1511 DCHECK(IsFloatingPoint(rep)); |
1518 DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register); | 1512 DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register); |
1519 allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, | 1513 allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep, |
1520 operand->fixed_register_index()); | 1514 operand->fixed_register_index()); |
1521 } else { | 1515 } else { |
1522 UNREACHABLE(); | 1516 UNREACHABLE(); |
1523 } | 1517 } |
1524 InstructionOperand::ReplaceWith(operand, &allocated); | 1518 InstructionOperand::ReplaceWith(operand, &allocated); |
1525 if (is_tagged) { | 1519 if (is_tagged) { |
1526 TRACE("Fixed reg is tagged at %d\n", pos); | 1520 TRACE("Fixed reg is tagged at %d\n", pos); |
1527 auto instr = code()->InstructionAt(pos); | 1521 auto instr = code()->InstructionAt(pos); |
1528 if (instr->HasReferenceMap()) { | 1522 if (instr->HasReferenceMap()) { |
1529 instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); | 1523 instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1621 data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); | 1615 data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); |
1622 bool assigned = false; | 1616 bool assigned = false; |
1623 if (first_output->HasFixedPolicy()) { | 1617 if (first_output->HasFixedPolicy()) { |
1624 int output_vreg = first_output->virtual_register(); | 1618 int output_vreg = first_output->virtual_register(); |
1625 UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); | 1619 UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); |
1626 bool is_tagged = code()->IsReference(output_vreg); | 1620 bool is_tagged = code()->IsReference(output_vreg); |
1627 if (first_output->HasSecondaryStorage()) { | 1621 if (first_output->HasSecondaryStorage()) { |
1628 range->MarkHasPreassignedSlot(); | 1622 range->MarkHasPreassignedSlot(); |
1629 InstructionOperand* spill_op = AllocatedOperand::New( | 1623 InstructionOperand* spill_op = AllocatedOperand::New( |
1630 data()->code_zone(), LocationOperand::LocationKind::STACK_SLOT, | 1624 data()->code_zone(), LocationOperand::LocationKind::STACK_SLOT, |
1631 range->machine_type(), first_output->GetSecondaryStorage()); | 1625 range->representation(), first_output->GetSecondaryStorage()); |
1632 range->RecordSpillLocation(allocation_zone(), instr_index + 1, | 1626 range->RecordSpillLocation(allocation_zone(), instr_index + 1, |
1633 first_output); | 1627 first_output); |
1634 range->SetSpillOperand(spill_op); | 1628 range->SetSpillOperand(spill_op); |
1635 range->SetSpillStartIndex(instr_index + 1); | 1629 range->SetSpillStartIndex(instr_index + 1); |
1636 assigned = true; | 1630 assigned = true; |
1637 } | 1631 } |
1638 AllocateFixed(first_output, instr_index, is_tagged); | 1632 AllocateFixed(first_output, instr_index, is_tagged); |
1639 | 1633 |
1640 // This value is produced on the stack, we never need to spill it. | 1634 // This value is produced on the stack, we never need to spill it. |
1641 if (first_output->IsStackSlot()) { | 1635 if (first_output->IsStackSlot()) { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1820 data()->fixed_live_ranges()[index] = result; | 1814 data()->fixed_live_ranges()[index] = result; |
1821 } | 1815 } |
1822 return result; | 1816 return result; |
1823 } | 1817 } |
1824 | 1818 |
1825 | 1819 |
1826 TopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) { | 1820 TopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) { |
1827 DCHECK(index < config()->num_double_registers()); | 1821 DCHECK(index < config()->num_double_registers()); |
1828 auto result = data()->fixed_double_live_ranges()[index]; | 1822 auto result = data()->fixed_double_live_ranges()[index]; |
1829 if (result == nullptr) { | 1823 if (result == nullptr) { |
1830 result = data()->NewLiveRange(FixedDoubleLiveRangeID(index), kRepFloat64); | 1824 result = data()->NewLiveRange(FixedDoubleLiveRangeID(index), |
| 1825 MachineRepresentation::kFloat64); |
1831 DCHECK(result->IsFixed()); | 1826 DCHECK(result->IsFixed()); |
1832 result->set_assigned_register(index); | 1827 result->set_assigned_register(index); |
1833 data()->MarkAllocated(DOUBLE_REGISTERS, index); | 1828 data()->MarkAllocated(DOUBLE_REGISTERS, index); |
1834 data()->fixed_double_live_ranges()[index] = result; | 1829 data()->fixed_double_live_ranges()[index] = result; |
1835 } | 1830 } |
1836 return result; | 1831 return result; |
1837 } | 1832 } |
1838 | 1833 |
1839 | 1834 |
1840 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { | 1835 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { |
(...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3093 InstructionOperand spill_operand; | 3088 InstructionOperand spill_operand; |
3094 if (((range->HasSpillOperand() && | 3089 if (((range->HasSpillOperand() && |
3095 !range->GetSpillOperand()->IsConstant()) || | 3090 !range->GetSpillOperand()->IsConstant()) || |
3096 range->HasSpillRange())) { | 3091 range->HasSpillRange())) { |
3097 if (range->HasSpillOperand()) { | 3092 if (range->HasSpillOperand()) { |
3098 spill_operand = *range->GetSpillOperand(); | 3093 spill_operand = *range->GetSpillOperand(); |
3099 } else { | 3094 } else { |
3100 spill_operand = range->GetSpillRangeOperand(); | 3095 spill_operand = range->GetSpillRangeOperand(); |
3101 } | 3096 } |
3102 DCHECK(spill_operand.IsStackSlot()); | 3097 DCHECK(spill_operand.IsStackSlot()); |
3103 DCHECK_EQ(kRepTagged, | 3098 DCHECK_EQ(MachineRepresentation::kTagged, |
3104 AllocatedOperand::cast(spill_operand).machine_type()); | 3099 AllocatedOperand::cast(spill_operand).representation()); |
3105 } | 3100 } |
3106 | 3101 |
3107 // Step through the safe points to see whether they are in the range. | 3102 // Step through the safe points to see whether they are in the range. |
3108 for (auto it = first_it; it != reference_maps->end(); ++it) { | 3103 for (auto it = first_it; it != reference_maps->end(); ++it) { |
3109 auto map = *it; | 3104 auto map = *it; |
3110 int safe_point = map->instruction_position(); | 3105 int safe_point = map->instruction_position(); |
3111 | 3106 |
3112 // The safe points are sorted so we can stop searching here. | 3107 // The safe points are sorted so we can stop searching here. |
3113 if (safe_point - 1 > end) break; | 3108 if (safe_point - 1 > end) break; |
3114 | 3109 |
(...skipping 20 matching lines...) Expand all Loading... |
3135 } | 3130 } |
3136 | 3131 |
3137 if (!cur->spilled()) { | 3132 if (!cur->spilled()) { |
3138 TRACE( | 3133 TRACE( |
3139 "Pointer in register for range %d:%d (start at %d) " | 3134 "Pointer in register for range %d:%d (start at %d) " |
3140 "at safe point %d\n", | 3135 "at safe point %d\n", |
3141 range->vreg(), cur->relative_id(), cur->Start().value(), | 3136 range->vreg(), cur->relative_id(), cur->Start().value(), |
3142 safe_point); | 3137 safe_point); |
3143 auto operand = cur->GetAssignedOperand(); | 3138 auto operand = cur->GetAssignedOperand(); |
3144 DCHECK(!operand.IsStackSlot()); | 3139 DCHECK(!operand.IsStackSlot()); |
3145 DCHECK_EQ(kRepTagged, AllocatedOperand::cast(operand).machine_type()); | 3140 DCHECK_EQ(MachineRepresentation::kTagged, |
| 3141 AllocatedOperand::cast(operand).representation()); |
3146 map->RecordReference(AllocatedOperand::cast(operand)); | 3142 map->RecordReference(AllocatedOperand::cast(operand)); |
3147 } | 3143 } |
3148 } | 3144 } |
3149 } | 3145 } |
3150 } | 3146 } |
3151 | 3147 |
3152 | 3148 |
3153 namespace { | 3149 namespace { |
3154 | 3150 |
3155 class LiveRangeBound { | 3151 class LiveRangeBound { |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3445 auto eliminate = moves->PrepareInsertAfter(move); | 3441 auto eliminate = moves->PrepareInsertAfter(move); |
3446 to_insert.push_back(move); | 3442 to_insert.push_back(move); |
3447 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3443 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
3448 } | 3444 } |
3449 } | 3445 } |
3450 | 3446 |
3451 | 3447 |
3452 } // namespace compiler | 3448 } // namespace compiler |
3453 } // namespace internal | 3449 } // namespace internal |
3454 } // namespace v8 | 3450 } // namespace v8 |
OLD | NEW |