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

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

Issue 1018853003: [turbofan] add non fixed slot constraint to register allocator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months 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.h » ('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/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 21 matching lines...) Expand all
32 32
33 static void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) { 33 static void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
34 auto it = std::find(v->begin(), v->end(), range); 34 auto it = std::find(v->begin(), v->end(), range);
35 DCHECK(it != v->end()); 35 DCHECK(it != v->end());
36 v->erase(it); 36 v->erase(it);
37 } 37 }
38 38
39 39
40 UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand, 40 UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
41 InstructionOperand* hint) 41 InstructionOperand* hint)
42 : operand_(operand), 42 : operand_(operand), hint_(hint), pos_(pos), next_(nullptr), flags_(0) {
43 hint_(hint), 43 bool register_beneficial = true;
44 pos_(pos), 44 UsePositionType type = UsePositionType::kAny;
45 next_(nullptr),
46 requires_reg_(false),
47 register_beneficial_(true) {
48 if (operand_ != nullptr && operand_->IsUnallocated()) { 45 if (operand_ != nullptr && operand_->IsUnallocated()) {
49 const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_); 46 const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
50 requires_reg_ = unalloc->HasRegisterPolicy(); 47 if (unalloc->HasRegisterPolicy()) {
51 register_beneficial_ = !unalloc->HasAnyPolicy(); 48 type = UsePositionType::kRequiresRegister;
49 } else if (unalloc->HasSlotPolicy()) {
50 type = UsePositionType::kRequiresSlot;
51 register_beneficial = false;
52 } else {
53 register_beneficial = !unalloc->HasAnyPolicy();
54 }
52 } 55 }
56 flags_ = TypeField::encode(type) |
57 RegisterBeneficialField::encode(register_beneficial);
53 DCHECK(pos_.IsValid()); 58 DCHECK(pos_.IsValid());
54 } 59 }
55 60
56 61
57 bool UsePosition::HasHint() const { 62 bool UsePosition::HasHint() const {
58 return hint_ != nullptr && !hint_->IsUnallocated(); 63 return hint_ != nullptr && !hint_->IsUnallocated();
59 } 64 }
60 65
61 66
62 bool UsePosition::RequiresRegister() const { return requires_reg_; } 67 void UsePosition::set_type(UsePositionType type, bool register_beneficial) {
63 68 DCHECK_IMPLIES(type == UsePositionType::kRequiresSlot, !register_beneficial);
64 69 flags_ = TypeField::encode(type) |
65 bool UsePosition::RegisterIsBeneficial() const { return register_beneficial_; } 70 RegisterBeneficialField::encode(register_beneficial);
71 }
66 72
67 73
68 void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) { 74 void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
69 DCHECK(Contains(pos) && pos.Value() != start().Value()); 75 DCHECK(Contains(pos) && pos.Value() != start().Value());
70 auto after = new (zone) UseInterval(pos, end_); 76 auto after = new (zone) UseInterval(pos, end_);
71 after->next_ = next_; 77 after->next_ = next_;
72 next_ = after; 78 next_ = after;
73 end_ = pos; 79 end_ = pos;
74 } 80 }
75 81
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 return false; 116 return false;
111 } 117 }
112 118
113 119
114 #endif 120 #endif
115 121
116 122
117 LiveRange::LiveRange(int id, Zone* zone) 123 LiveRange::LiveRange(int id, Zone* zone)
118 : id_(id), 124 : id_(id),
119 spilled_(false), 125 spilled_(false),
126 has_slot_use_(false),
120 is_phi_(false), 127 is_phi_(false),
121 is_non_loop_phi_(false), 128 is_non_loop_phi_(false),
122 kind_(UNALLOCATED_REGISTERS), 129 kind_(UNALLOCATED_REGISTERS),
123 assigned_register_(kInvalidAssignment), 130 assigned_register_(kInvalidAssignment),
124 last_interval_(nullptr), 131 last_interval_(nullptr),
125 first_interval_(nullptr), 132 first_interval_(nullptr),
126 first_pos_(nullptr), 133 first_pos_(nullptr),
127 parent_(nullptr), 134 parent_(nullptr),
128 next_(nullptr), 135 next_(nullptr),
129 current_interval_(nullptr), 136 current_interval_(nullptr),
130 last_processed_use_(nullptr), 137 last_processed_use_(nullptr),
131 current_hint_operand_(nullptr), 138 current_hint_operand_(nullptr),
132 spill_start_index_(kMaxInt), 139 spill_start_index_(kMaxInt),
133 spill_type_(SpillType::kNoSpillType), 140 spill_type_(SpillType::kNoSpillType),
134 spill_operand_(nullptr), 141 spill_operand_(nullptr),
135 spills_at_definition_(nullptr) {} 142 spills_at_definition_(nullptr) {}
136 143
137 144
138 void LiveRange::set_assigned_register(int reg, 145 void LiveRange::set_assigned_register(int reg,
139 InstructionOperandCache* operand_cache) { 146 InstructionOperandCache* operand_cache) {
140 DCHECK(!HasRegisterAssigned() && !IsSpilled()); 147 DCHECK(!HasRegisterAssigned() && !IsSpilled());
141 assigned_register_ = reg; 148 assigned_register_ = reg;
142 // TODO(dcarney): stop aliasing hint operands. 149 // TODO(dcarney): stop aliasing hint operands.
143 ConvertUsesToOperand(GetAssignedOperand(operand_cache)); 150 ConvertUsesToOperand(GetAssignedOperand(operand_cache), nullptr);
144 } 151 }
145 152
146 153
147 void LiveRange::MakeSpilled() { 154 void LiveRange::MakeSpilled() {
148 DCHECK(!IsSpilled()); 155 DCHECK(!IsSpilled());
149 DCHECK(!TopLevel()->HasNoSpillType()); 156 DCHECK(!TopLevel()->HasNoSpillType());
150 spilled_ = true; 157 spilled_ = true;
151 assigned_register_ = kInvalidAssignment; 158 assigned_register_ = kInvalidAssignment;
152 } 159 }
153 160
154 161
155 void LiveRange::SpillAtDefinition(Zone* zone, int gap_index, 162 void LiveRange::SpillAtDefinition(Zone* zone, int gap_index,
156 InstructionOperand* operand) { 163 InstructionOperand* operand) {
157 DCHECK(HasNoSpillType()); 164 DCHECK(HasNoSpillType());
158 spills_at_definition_ = new (zone) 165 spills_at_definition_ = new (zone)
159 SpillAtDefinitionList(gap_index, operand, spills_at_definition_); 166 SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
160 } 167 }
161 168
162 169
163 void LiveRange::CommitSpillsAtDefinition(InstructionSequence* sequence, 170 void LiveRange::CommitSpillsAtDefinition(InstructionSequence* sequence,
164 InstructionOperand* op) { 171 InstructionOperand* op,
165 auto to_spill = TopLevel()->spills_at_definition_; 172 bool might_be_duplicated) {
166 if (to_spill == nullptr) return; 173 DCHECK(!IsChild());
167 auto zone = sequence->zone(); 174 auto zone = sequence->zone();
168 for (; to_spill != nullptr; to_spill = to_spill->next) { 175 for (auto to_spill = spills_at_definition_; to_spill != nullptr;
176 to_spill = to_spill->next) {
169 auto gap = sequence->GapAt(to_spill->gap_index); 177 auto gap = sequence->GapAt(to_spill->gap_index);
170 auto move = gap->GetOrCreateParallelMove(GapInstruction::START, zone); 178 auto move = gap->GetOrCreateParallelMove(GapInstruction::START, zone);
179 // Skip insertion if it's possible that the move exists already as a
180 // constraint move from a fixed output register to a slot.
181 if (might_be_duplicated) {
182 bool found = false;
183 auto move_ops = move->move_operands();
184 for (auto move_op = move_ops->begin(); move_op != move_ops->end();
185 ++move_op) {
186 if (move_op->IsEliminated()) continue;
187 if (move_op->source()->Equals(to_spill->operand) &&
188 move_op->destination()->Equals(op)) {
189 found = true;
190 break;
191 }
192 }
193 if (found) continue;
194 }
171 move->AddMove(to_spill->operand, op, zone); 195 move->AddMove(to_spill->operand, op, zone);
172 } 196 }
173 TopLevel()->spills_at_definition_ = nullptr;
174 } 197 }
175 198
176 199
177 void LiveRange::SetSpillOperand(InstructionOperand* operand) { 200 void LiveRange::SetSpillOperand(InstructionOperand* operand) {
178 DCHECK(HasNoSpillType()); 201 DCHECK(HasNoSpillType());
179 DCHECK(!operand->IsUnallocated()); 202 DCHECK(!operand->IsUnallocated());
180 spill_type_ = SpillType::kSpillOperand; 203 spill_type_ = SpillType::kSpillOperand;
181 spill_operand_ = operand; 204 spill_operand_ = operand;
182 } 205 }
183 206
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 while (pos != nullptr && pos->pos().Value() < start.Value()) { 250 while (pos != nullptr && pos->pos().Value() < start.Value()) {
228 if (pos->RegisterIsBeneficial()) prev = pos; 251 if (pos->RegisterIsBeneficial()) prev = pos;
229 pos = pos->next(); 252 pos = pos->next();
230 } 253 }
231 return prev; 254 return prev;
232 } 255 }
233 256
234 257
235 UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) { 258 UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) {
236 UsePosition* pos = NextUsePosition(start); 259 UsePosition* pos = NextUsePosition(start);
237 while (pos != nullptr && !pos->RequiresRegister()) { 260 while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) {
238 pos = pos->next(); 261 pos = pos->next();
239 } 262 }
240 return pos; 263 return pos;
241 } 264 }
242 265
243 266
244 bool LiveRange::CanBeSpilled(LifetimePosition pos) { 267 bool LiveRange::CanBeSpilled(LifetimePosition pos) {
245 // We cannot spill a live range that has a use requiring a register 268 // We cannot spill a live range that has a use requiring a register
246 // at the current or the immediate next position. 269 // at the current or the immediate next position.
247 auto use_pos = NextRegisterPosition(pos); 270 auto use_pos = NextRegisterPosition(pos);
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 use_pos->next_ = prev->next_; 525 use_pos->next_ = prev->next_;
503 prev->next_ = use_pos; 526 prev->next_ = use_pos;
504 } 527 }
505 528
506 if (prev_hint == nullptr && use_pos->HasHint()) { 529 if (prev_hint == nullptr && use_pos->HasHint()) {
507 current_hint_operand_ = hint; 530 current_hint_operand_ = hint;
508 } 531 }
509 } 532 }
510 533
511 534
512 void LiveRange::ConvertUsesToOperand(InstructionOperand* op) { 535 void LiveRange::ConvertUsesToOperand(InstructionOperand* op,
513 auto use_pos = first_pos(); 536 InstructionOperand* spill_op) {
514 while (use_pos != nullptr) { 537 for (auto pos = first_pos(); pos != nullptr; pos = pos->next()) {
515 DCHECK(Start().Value() <= use_pos->pos().Value() && 538 DCHECK(Start().Value() <= pos->pos().Value() &&
516 use_pos->pos().Value() <= End().Value()); 539 pos->pos().Value() <= End().Value());
517 540 if (!pos->HasOperand()) {
518 if (use_pos->HasOperand()) { 541 continue;
519 DCHECK(op->IsRegister() || op->IsDoubleRegister() ||
520 !use_pos->RequiresRegister());
521 use_pos->operand()->ConvertTo(op->kind(), op->index());
522 } 542 }
523 use_pos = use_pos->next(); 543 switch (pos->type()) {
544 case UsePositionType::kRequiresSlot:
545 if (spill_op != nullptr) {
546 pos->operand()->ConvertTo(spill_op->kind(), spill_op->index());
547 }
548 break;
549 case UsePositionType::kRequiresRegister:
550 DCHECK(op->IsRegister() || op->IsDoubleRegister());
551 // Fall through.
552 case UsePositionType::kAny:
553 pos->operand()->ConvertTo(op->kind(), op->index());
554 break;
555 }
524 } 556 }
525 } 557 }
526 558
527 559
528 bool LiveRange::CanCover(LifetimePosition position) const { 560 bool LiveRange::CanCover(LifetimePosition position) const {
529 if (IsEmpty()) return false; 561 if (IsEmpty()) return false;
530 return Start().Value() <= position.Value() && 562 return Start().Value() <= position.Value() &&
531 position.Value() < End().Value(); 563 position.Value() < End().Value();
532 } 564 }
533 565
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 : InstructionOperand::STACK_SLOT; 982 : InstructionOperand::STACK_SLOT;
951 auto op = InstructionOperand::New(code_zone(), op_kind, index); 983 auto op = InstructionOperand::New(code_zone(), op_kind, index);
952 range->SetOperand(op); 984 range->SetOperand(op);
953 } 985 }
954 } 986 }
955 987
956 988
957 void RegisterAllocator::CommitAssignment() { 989 void RegisterAllocator::CommitAssignment() {
958 for (auto range : live_ranges()) { 990 for (auto range : live_ranges()) {
959 if (range == nullptr || range->IsEmpty()) continue; 991 if (range == nullptr || range->IsEmpty()) continue;
960 // Register assignments were committed in set_assigned_register.
961 if (range->HasRegisterAssigned()) continue;
962 auto assigned = range->GetAssignedOperand(operand_cache()); 992 auto assigned = range->GetAssignedOperand(operand_cache());
963 range->ConvertUsesToOperand(assigned); 993 InstructionOperand* spill_operand = nullptr;
964 if (range->IsSpilled()) { 994 if (!range->TopLevel()->HasNoSpillType()) {
965 range->CommitSpillsAtDefinition(code(), assigned); 995 spill_operand = range->TopLevel()->GetSpillOperand();
996 }
997 range->ConvertUsesToOperand(assigned, spill_operand);
998 if (!range->IsChild() && spill_operand != nullptr) {
999 range->CommitSpillsAtDefinition(code(), spill_operand,
1000 range->has_slot_use());
966 } 1001 }
967 } 1002 }
968 } 1003 }
969 1004
970 1005
971 SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { 1006 SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
972 auto spill_range = new (local_zone()) SpillRange(range, local_zone()); 1007 auto spill_range = new (local_zone()) SpillRange(range, local_zone());
973 spill_ranges().push_back(spill_range); 1008 spill_ranges().push_back(spill_range);
974 return spill_range; 1009 return spill_range;
975 } 1010 }
976 1011
977 1012
978 bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) { 1013 bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) {
979 if (range->IsChild() || !range->is_phi()) return false; 1014 if (range->IsChild() || !range->is_phi()) return false;
980 DCHECK(range->HasNoSpillType()); 1015 DCHECK(!range->HasSpillOperand());
981 1016
982 auto lookup = phi_map_.find(range->id()); 1017 auto lookup = phi_map_.find(range->id());
983 DCHECK(lookup != phi_map_.end()); 1018 DCHECK(lookup != phi_map_.end());
984 auto phi = lookup->second.phi; 1019 auto phi = lookup->second.phi;
985 auto block = lookup->second.block; 1020 auto block = lookup->second.block;
986 // Count the number of spilled operands. 1021 // Count the number of spilled operands.
987 size_t spilled_count = 0; 1022 size_t spilled_count = 0;
988 LiveRange* first_op = nullptr; 1023 LiveRange* first_op = nullptr;
989 for (size_t i = 0; i < phi->operands().size(); i++) { 1024 for (size_t i = 0; i < phi->operands().size(); i++) {
990 int op = phi->operands()[i]; 1025 int op = phi->operands()[i];
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 } 1068 }
1034 1069
1035 // If the range does not need register soon, spill it to the merged 1070 // If the range does not need register soon, spill it to the merged
1036 // spill range. 1071 // spill range.
1037 auto next_pos = range->Start(); 1072 auto next_pos = range->Start();
1038 if (code()->IsGapAt(next_pos.InstructionIndex())) { 1073 if (code()->IsGapAt(next_pos.InstructionIndex())) {
1039 next_pos = next_pos.NextInstruction(); 1074 next_pos = next_pos.NextInstruction();
1040 } 1075 }
1041 auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos); 1076 auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
1042 if (pos == nullptr) { 1077 if (pos == nullptr) {
1043 auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel()); 1078 auto spill_range = range->TopLevel()->HasSpillRange()
1079 ? range->TopLevel()->GetSpillRange()
1080 : AssignSpillRangeToLiveRange(range->TopLevel());
1044 CHECK(first_op_spill->TryMerge(spill_range)); 1081 CHECK(first_op_spill->TryMerge(spill_range));
1045 Spill(range); 1082 Spill(range);
1046 return true; 1083 return true;
1047 } else if (pos->pos().Value() > range->Start().NextInstruction().Value()) { 1084 } else if (pos->pos().Value() > range->Start().NextInstruction().Value()) {
1048 auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel()); 1085 auto spill_range = range->TopLevel()->HasSpillRange()
1086 ? range->TopLevel()->GetSpillRange()
1087 : AssignSpillRangeToLiveRange(range->TopLevel());
1049 CHECK(first_op_spill->TryMerge(spill_range)); 1088 CHECK(first_op_spill->TryMerge(spill_range));
1050 SpillBetween(range, range->Start(), pos->pos()); 1089 SpillBetween(range, range->Start(), pos->pos());
1051 DCHECK(UnhandledIsSorted()); 1090 DCHECK(UnhandledIsSorted());
1052 return true; 1091 return true;
1053 } 1092 }
1054 return false; 1093 return false;
1055 } 1094 }
1056 1095
1057 1096
1058 void RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) { 1097 void RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) {
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 if (from->IsUnallocated()) { 1336 if (from->IsUnallocated()) {
1298 live->Add(UnallocatedOperand::cast(from)->virtual_register()); 1337 live->Add(UnallocatedOperand::cast(from)->virtual_register());
1299 } 1338 }
1300 } 1339 }
1301 } 1340 }
1302 } else { 1341 } else {
1303 // Process output, inputs, and temps of this non-gap instruction. 1342 // Process output, inputs, and temps of this non-gap instruction.
1304 for (size_t i = 0; i < instr->OutputCount(); i++) { 1343 for (size_t i = 0; i < instr->OutputCount(); i++) {
1305 auto output = instr->OutputAt(i); 1344 auto output = instr->OutputAt(i);
1306 if (output->IsUnallocated()) { 1345 if (output->IsUnallocated()) {
1346 // Unsupported.
1347 DCHECK(!UnallocatedOperand::cast(output)->HasSlotPolicy());
1307 int out_vreg = UnallocatedOperand::cast(output)->virtual_register(); 1348 int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
1308 live->Remove(out_vreg); 1349 live->Remove(out_vreg);
1309 } else if (output->IsConstant()) { 1350 } else if (output->IsConstant()) {
1310 int out_vreg = output->index(); 1351 int out_vreg = output->index();
1311 live->Remove(out_vreg); 1352 live->Remove(out_vreg);
1312 } 1353 }
1313 Define(curr_position, output, nullptr); 1354 Define(curr_position, output, nullptr);
1314 } 1355 }
1315 1356
1316 if (instr->ClobbersRegisters()) { 1357 if (instr->ClobbersRegisters()) {
(...skipping 20 matching lines...) Expand all
1337 auto input = instr->InputAt(i); 1378 auto input = instr->InputAt(i);
1338 if (input->IsImmediate()) continue; // Ignore immediates. 1379 if (input->IsImmediate()) continue; // Ignore immediates.
1339 LifetimePosition use_pos; 1380 LifetimePosition use_pos;
1340 if (input->IsUnallocated() && 1381 if (input->IsUnallocated() &&
1341 UnallocatedOperand::cast(input)->IsUsedAtStart()) { 1382 UnallocatedOperand::cast(input)->IsUsedAtStart()) {
1342 use_pos = curr_position; 1383 use_pos = curr_position;
1343 } else { 1384 } else {
1344 use_pos = curr_position.InstructionEnd(); 1385 use_pos = curr_position.InstructionEnd();
1345 } 1386 }
1346 1387
1388 if (input->IsUnallocated()) {
1389 UnallocatedOperand* unalloc = UnallocatedOperand::cast(input);
1390 int vreg = unalloc->virtual_register();
1391 live->Add(vreg);
1392 if (unalloc->HasSlotPolicy()) {
1393 LiveRangeFor(vreg)->set_has_slot_use(true);
1394 }
1395 }
1347 Use(block_start_position, use_pos, input, nullptr); 1396 Use(block_start_position, use_pos, input, nullptr);
1348 if (input->IsUnallocated()) {
1349 live->Add(UnallocatedOperand::cast(input)->virtual_register());
1350 }
1351 } 1397 }
1352 1398
1353 for (size_t i = 0; i < instr->TempCount(); i++) { 1399 for (size_t i = 0; i < instr->TempCount(); i++) {
1354 auto temp = instr->TempAt(i); 1400 auto temp = instr->TempAt(i);
1401 // Unsupported.
1402 DCHECK_IMPLIES(temp->IsUnallocated(),
1403 !UnallocatedOperand::cast(temp)->HasSlotPolicy());
1355 if (instr->ClobbersTemps()) { 1404 if (instr->ClobbersTemps()) {
1356 if (temp->IsRegister()) continue; 1405 if (temp->IsRegister()) continue;
1357 if (temp->IsUnallocated()) { 1406 if (temp->IsUnallocated()) {
1358 UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp); 1407 UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp);
1359 if (temp_unalloc->HasFixedPolicy()) { 1408 if (temp_unalloc->HasFixedPolicy()) {
1360 continue; 1409 continue;
1361 } 1410 }
1362 } 1411 }
1363 } 1412 }
1364 Use(block_start_position, curr_position.InstructionEnd(), temp, 1413 Use(block_start_position, curr_position.InstructionEnd(), temp,
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 for (int i = block->rpo_number().ToInt() + 1; 1815 for (int i = block->rpo_number().ToInt() + 1;
1767 i < block->loop_end().ToInt(); ++i) { 1816 i < block->loop_end().ToInt(); ++i) {
1768 live_in_sets_[i]->Union(*live); 1817 live_in_sets_[i]->Union(*live);
1769 } 1818 }
1770 } 1819 }
1771 } 1820 }
1772 1821
1773 for (auto range : live_ranges()) { 1822 for (auto range : live_ranges()) {
1774 if (range == nullptr) continue; 1823 if (range == nullptr) continue;
1775 range->kind_ = RequiredRegisterKind(range->id()); 1824 range->kind_ = RequiredRegisterKind(range->id());
1825 // Give slots to all ranges with a non fixed slot use.
1826 if (range->has_slot_use() && range->HasNoSpillType()) {
1827 AssignSpillRangeToLiveRange(range);
1828 }
1776 // TODO(bmeurer): This is a horrible hack to make sure that for constant 1829 // TODO(bmeurer): This is a horrible hack to make sure that for constant
1777 // live ranges, every use requires the constant to be in a register. 1830 // live ranges, every use requires the constant to be in a register.
1778 // Without this hack, all uses with "any" policy would get the constant 1831 // Without this hack, all uses with "any" policy would get the constant
1779 // operand assigned. 1832 // operand assigned.
1780 if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) { 1833 if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
1781 for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) { 1834 for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) {
1782 pos->register_beneficial_ = true; 1835 if (pos->type() == UsePositionType::kRequiresSlot) continue;
1783 // TODO(dcarney): should the else case assert requires_reg_ == false? 1836 UsePositionType new_type = UsePositionType::kAny;
1784 // Can't mark phis as needing a register. 1837 // Can't mark phis as needing a register.
1785 if (!code() 1838 if (!code()
1786 ->InstructionAt(pos->pos().InstructionIndex()) 1839 ->InstructionAt(pos->pos().InstructionIndex())
1787 ->IsGapMoves()) { 1840 ->IsGapMoves()) {
1788 pos->requires_reg_ = true; 1841 new_type = UsePositionType::kRequiresRegister;
1789 } 1842 }
1843 pos->set_type(new_type, true);
1790 } 1844 }
1791 } 1845 }
1792 } 1846 }
1793 } 1847 }
1794 1848
1795 1849
1796 bool RegisterAllocator::ExistsUseWithoutDefinition() { 1850 bool RegisterAllocator::ExistsUseWithoutDefinition() {
1797 bool found = false; 1851 bool found = false;
1798 BitVector::Iterator iterator(live_in_sets_[0]); 1852 BitVector::Iterator iterator(live_in_sets_[0]);
1799 while (!iterator.Done()) { 1853 while (!iterator.Done()) {
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 } else { 2582 } else {
2529 DCHECK(range->Kind() == GENERAL_REGISTERS); 2583 DCHECK(range->Kind() == GENERAL_REGISTERS);
2530 assigned_registers_->Add(reg); 2584 assigned_registers_->Add(reg);
2531 } 2585 }
2532 range->set_assigned_register(reg, operand_cache()); 2586 range->set_assigned_register(reg, operand_cache());
2533 } 2587 }
2534 2588
2535 } // namespace compiler 2589 } // namespace compiler
2536 } // namespace internal 2590 } // namespace internal
2537 } // namespace v8 2591 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/register-allocator-verifier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698