| Index: src/compiler/register-allocator.cc
|
| diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
|
| index fcb935a940cf81cbc077cfc34d1f8006b3119fb1..05bc8ba795c1b46fd59b35f1463b5b999fbb12c0 100644
|
| --- a/src/compiler/register-allocator.cc
|
| +++ b/src/compiler/register-allocator.cc
|
| @@ -767,7 +767,9 @@ void TopLevelLiveRange::CommitSpillMoves(InstructionSequence* sequence,
|
| }
|
| if (found) continue;
|
| }
|
| - move->AddMove(*to_spill->operand, op);
|
| + if (!has_preassigned_slot()) {
|
| + move->AddMove(*to_spill->operand, op);
|
| + }
|
| }
|
| }
|
|
|
| @@ -1126,6 +1128,7 @@ bool SpillRange::IsIntersectingWith(SpillRange* other) const {
|
|
|
|
|
| bool SpillRange::TryMerge(SpillRange* other) {
|
| + if (HasSlot() || other->HasSlot()) return false;
|
| // TODO(dcarney): byte widths should be compared here not kinds.
|
| if (live_ranges_[0]->kind() != other->live_ranges_[0]->kind() ||
|
| IsIntersectingWith(other)) {
|
| @@ -1227,7 +1230,8 @@ RegisterAllocationData::RegisterAllocationData(
|
| delayed_references_(allocation_zone()),
|
| assigned_registers_(nullptr),
|
| assigned_double_registers_(nullptr),
|
| - virtual_register_count_(code->VirtualRegisterCount()) {
|
| + virtual_register_count_(code->VirtualRegisterCount()),
|
| + preassigned_slot_ranges_(zone) {
|
| DCHECK(this->config()->num_general_registers() <=
|
| RegisterConfiguration::kMaxGeneralRegisters);
|
| DCHECK(this->config()->num_double_registers() <=
|
| @@ -1620,14 +1624,8 @@ void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
|
| bool is_tagged = code()->IsReference(output_vreg);
|
| if (first_output->HasSecondaryStorage()) {
|
| range->MarkHasPreassignedSlot();
|
| - InstructionOperand* spill_op = AllocatedOperand::New(
|
| - data()->code_zone(), LocationOperand::LocationKind::STACK_SLOT,
|
| - range->representation(), first_output->GetSecondaryStorage());
|
| - range->RecordSpillLocation(allocation_zone(), instr_index + 1,
|
| - first_output);
|
| - range->SetSpillOperand(spill_op);
|
| - range->SetSpillStartIndex(instr_index + 1);
|
| - assigned = true;
|
| + data()->preassigned_slot_ranges().push_back(
|
| + std::make_pair(range, first_output->GetSecondaryStorage()));
|
| }
|
| AllocateFixed(first_output, instr_index, is_tagged);
|
|
|
| @@ -2159,6 +2157,14 @@ void LiveRangeBuilder::BuildLiveRanges() {
|
| }
|
| }
|
| }
|
| + for (auto preassigned : data()->preassigned_slot_ranges()) {
|
| + TopLevelLiveRange* range = preassigned.first;
|
| + int slot_id = preassigned.second;
|
| + SpillRange* spill = range->HasSpillRange()
|
| + ? range->GetSpillRange()
|
| + : data()->AssignSpillRangeToLiveRange(range);
|
| + spill->set_assigned_slot(slot_id);
|
| + }
|
| #ifdef DEBUG
|
| Verify();
|
| #endif
|
| @@ -2978,9 +2984,11 @@ void OperandAssigner::AssignSpillSlots() {
|
| for (SpillRange* range : spill_ranges) {
|
| if (range == nullptr || range->IsEmpty()) continue;
|
| // Allocate a new operand referring to the spill slot.
|
| - int byte_width = range->ByteWidth();
|
| - int index = data()->frame()->AllocateSpillSlot(byte_width);
|
| - range->set_assigned_slot(index);
|
| + if (!range->HasSlot()) {
|
| + int byte_width = range->ByteWidth();
|
| + int index = data()->frame()->AllocateSpillSlot(byte_width);
|
| + range->set_assigned_slot(index);
|
| + }
|
| }
|
| }
|
|
|
|
|