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/bit-vector.h" | 5 #include "src/bit-vector.h" |
6 #include "src/compiler/instruction.h" | 6 #include "src/compiler/instruction.h" |
7 #include "src/compiler/register-allocator-verifier.h" | 7 #include "src/compiler/register-allocator-verifier.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 switch (unallocated->extended_policy()) { | 165 switch (unallocated->extended_policy()) { |
166 case UnallocatedOperand::ANY: | 166 case UnallocatedOperand::ANY: |
167 case UnallocatedOperand::NONE: | 167 case UnallocatedOperand::NONE: |
168 if (sequence()->IsFloat(vreg)) { | 168 if (sequence()->IsFloat(vreg)) { |
169 constraint->type_ = kNoneDouble; | 169 constraint->type_ = kNoneDouble; |
170 } else { | 170 } else { |
171 constraint->type_ = kNone; | 171 constraint->type_ = kNone; |
172 } | 172 } |
173 break; | 173 break; |
174 case UnallocatedOperand::FIXED_REGISTER: | 174 case UnallocatedOperand::FIXED_REGISTER: |
175 constraint->type_ = kFixedRegister; | 175 if (unallocated->HasSecondaryStorage()) { |
| 176 constraint->type_ = kRegisterAndSlot; |
| 177 constraint->spilled_slot_ = unallocated->GetSecondaryStorage(); |
| 178 } else { |
| 179 constraint->type_ = kFixedRegister; |
| 180 } |
176 constraint->value_ = unallocated->fixed_register_index(); | 181 constraint->value_ = unallocated->fixed_register_index(); |
177 break; | 182 break; |
178 case UnallocatedOperand::FIXED_DOUBLE_REGISTER: | 183 case UnallocatedOperand::FIXED_DOUBLE_REGISTER: |
179 constraint->type_ = kFixedDoubleRegister; | 184 constraint->type_ = kFixedDoubleRegister; |
180 constraint->value_ = unallocated->fixed_register_index(); | 185 constraint->value_ = unallocated->fixed_register_index(); |
181 break; | 186 break; |
182 case UnallocatedOperand::MUST_HAVE_REGISTER: | 187 case UnallocatedOperand::MUST_HAVE_REGISTER: |
183 if (sequence()->IsFloat(vreg)) { | 188 if (sequence()->IsFloat(vreg)) { |
184 constraint->type_ = kDoubleRegister; | 189 constraint->type_ = kDoubleRegister; |
185 } else { | 190 } else { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 case kRegister: | 223 case kRegister: |
219 CHECK(op->IsRegister()); | 224 CHECK(op->IsRegister()); |
220 return; | 225 return; |
221 case kDoubleRegister: | 226 case kDoubleRegister: |
222 CHECK(op->IsDoubleRegister()); | 227 CHECK(op->IsDoubleRegister()); |
223 return; | 228 return; |
224 case kExplicit: | 229 case kExplicit: |
225 CHECK(op->IsExplicit()); | 230 CHECK(op->IsExplicit()); |
226 return; | 231 return; |
227 case kFixedRegister: | 232 case kFixedRegister: |
| 233 case kRegisterAndSlot: |
228 CHECK(op->IsRegister()); | 234 CHECK(op->IsRegister()); |
229 CHECK_EQ(LocationOperand::cast(op)->GetRegister().code(), | 235 CHECK_EQ(LocationOperand::cast(op)->GetRegister().code(), |
230 constraint->value_); | 236 constraint->value_); |
231 return; | 237 return; |
232 case kFixedDoubleRegister: | 238 case kFixedDoubleRegister: |
233 CHECK(op->IsDoubleRegister()); | 239 CHECK(op->IsDoubleRegister()); |
234 CHECK_EQ(LocationOperand::cast(op)->GetDoubleRegister().code(), | 240 CHECK_EQ(LocationOperand::cast(op)->GetDoubleRegister().code(), |
235 constraint->value_); | 241 constraint->value_); |
236 return; | 242 return; |
237 case kFixedSlot: | 243 case kFixedSlot: |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 for (auto it = map().begin(); it != map().end();) { | 385 for (auto it = map().begin(); it != map().end();) { |
380 auto op = it->first; | 386 auto op = it->first; |
381 if (op->IsRegister() || op->IsDoubleRegister()) { | 387 if (op->IsRegister() || op->IsDoubleRegister()) { |
382 map().erase(it++); | 388 map().erase(it++); |
383 } else { | 389 } else { |
384 ++it; | 390 ++it; |
385 } | 391 } |
386 } | 392 } |
387 } | 393 } |
388 | 394 |
389 void Define(Zone* zone, const InstructionOperand* op, int virtual_register) { | 395 MapValue* Define(Zone* zone, const InstructionOperand* op, |
| 396 int virtual_register) { |
390 auto value = new (zone) MapValue(); | 397 auto value = new (zone) MapValue(); |
391 value->define_vreg = virtual_register; | 398 value->define_vreg = virtual_register; |
392 auto res = map().insert(std::make_pair(op, value)); | 399 auto res = map().insert(std::make_pair(op, value)); |
393 if (!res.second) res.first->second = value; | 400 if (!res.second) res.first->second = value; |
| 401 return value; |
394 } | 402 } |
395 | 403 |
396 void Use(const InstructionOperand* op, int use_vreg, bool initial_pass) { | 404 void Use(const InstructionOperand* op, int use_vreg, bool initial_pass) { |
397 auto it = map().find(op); | 405 auto it = map().find(op); |
398 CHECK(it != map().end()); | 406 CHECK(it != map().end()); |
399 auto v = it->second; | 407 auto v = it->second; |
400 if (v->define_vreg != kInvalidVreg) { | 408 if (v->define_vreg != kInvalidVreg) { |
401 CHECK_EQ(v->define_vreg, use_vreg); | 409 CHECK_EQ(v->define_vreg, use_vreg); |
402 } | 410 } |
403 // Already used this vreg in this block. | 411 // Already used this vreg in this block. |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 } | 705 } |
698 } | 706 } |
699 for (size_t i = 0; i < instr->TempCount(); ++i, ++count) { | 707 for (size_t i = 0; i < instr->TempCount(); ++i, ++count) { |
700 current->Drop(instr->TempAt(i)); | 708 current->Drop(instr->TempAt(i)); |
701 } | 709 } |
702 if (instr->IsCall()) { | 710 if (instr->IsCall()) { |
703 current->DropRegisters(config()); | 711 current->DropRegisters(config()); |
704 } | 712 } |
705 for (size_t i = 0; i < instr->OutputCount(); ++i, ++count) { | 713 for (size_t i = 0; i < instr->OutputCount(); ++i, ++count) { |
706 int virtual_register = op_constraints[count].virtual_register_; | 714 int virtual_register = op_constraints[count].virtual_register_; |
707 current->Define(zone(), instr->OutputAt(i), virtual_register); | 715 OperandMap::MapValue* value = |
| 716 current->Define(zone(), instr->OutputAt(i), virtual_register); |
| 717 if (op_constraints[count].type_ == kRegisterAndSlot) { |
| 718 const AllocatedOperand* reg_op = |
| 719 AllocatedOperand::cast(instr->OutputAt(i)); |
| 720 MachineType mt = reg_op->machine_type(); |
| 721 const AllocatedOperand* stack_op = AllocatedOperand::New( |
| 722 zone(), LocationOperand::LocationKind::STACK_SLOT, mt, |
| 723 op_constraints[i].spilled_slot_); |
| 724 auto insert_result = |
| 725 current->map().insert(std::make_pair(stack_op, value)); |
| 726 DCHECK(insert_result.second); |
| 727 USE(insert_result); |
| 728 } |
708 } | 729 } |
709 } | 730 } |
710 } | 731 } |
711 } | 732 } |
712 | 733 |
713 } // namespace compiler | 734 } // namespace compiler |
714 } // namespace internal | 735 } // namespace internal |
715 } // namespace v8 | 736 } // namespace v8 |
OLD | NEW |