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

Side by Side Diff: src/compiler/register-allocator.cc

Issue 1513543003: [turbofan] Make MachineType a pair of enums. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Moar rebase Created 5 years 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
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/register-allocator-verifier.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/register-allocator-verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698