Index: runtime/vm/flow_graph_allocator.cc |
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc |
index ac39023f54f2d00d58eef45012170d99899d9f49..1332661b9cc9e7f7cd36e3a79c4cabc40c67a820 100644 |
--- a/runtime/vm/flow_graph_allocator.cc |
+++ b/runtime/vm/flow_graph_allocator.cc |
@@ -580,6 +580,24 @@ void FlowGraphAllocator::BuildLiveRanges() { |
} |
+static Location::Kind RegisterKindFromPolicy(Location loc) { |
+ if (loc.policy() == Location::kRequiresXmmRegister) { |
+ return Location::kXmmRegister; |
+ } else { |
+ return Location::kRegister; |
+ } |
+} |
+ |
+ |
+static Location::Kind RegisterKindForResult(Instruction* instr) { |
+ if (instr->representation() == kUnboxedDouble) { |
+ return Location::kXmmRegister; |
+ } else { |
+ return Location::kRegister; |
+ } |
+} |
+ |
+ |
// |
// When describing shape of live ranges in comments below we are going to use |
// the following notation: |
@@ -700,8 +718,7 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(BlockEntryInstr* block) { |
// complete. |
AssignSafepoints(range); |
- // TODO(vegorov): unboxed double phis. |
- CompleteRange(range, Location::kRegister); |
+ CompleteRange(range, RegisterKindForResult(phi)); |
move_idx++; |
} |
@@ -753,24 +770,6 @@ void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
} |
-static Location::Kind RegisterKindFromPolicy(Location loc) { |
- if (loc.policy() == Location::kRequiresXmmRegister) { |
- return Location::kXmmRegister; |
- } else { |
- return Location::kRegister; |
- } |
-} |
- |
- |
-static Location::Kind RegisterKindForResult(Instruction* instr) { |
- if (instr->representation() == kUnboxedDouble) { |
- return Location::kXmmRegister; |
- } else { |
- return Location::kRegister; |
- } |
-} |
- |
- |
// Create and update live ranges corresponding to instruction's inputs, |
// temporaries and output. |
void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
@@ -871,6 +870,14 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
pos + 1); |
} |
+ for (intptr_t reg = 0; reg < kNumberOfXmmRegisters; reg++) { |
+ BlockLocation( |
+ Location::XmmRegisterLocation(static_cast<XmmRegister>(reg)), |
+ pos, |
+ pos + 1); |
+ } |
+ |
+ |
#if defined(DEBUG) |
// Verify that temps, inputs and output were specified as fixed |
// locations. Every register is blocked now so attempt to |
@@ -1188,7 +1195,8 @@ UsePosition* AllocationFinger::FirstRegisterUse(intptr_t after) { |
use = use->next()) { |
Location* loc = use->location_slot(); |
if (loc->IsUnallocated() && |
- (loc->policy() == Location::kRequiresRegister)) { |
+ ((loc->policy() == Location::kRequiresRegister) || |
+ (loc->policy() == Location::kRequiresXmmRegister))) { |
first_register_use_ = use; |
return use; |
} |
@@ -1434,9 +1442,15 @@ void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) { |
if (register_kind_ == Location::kRegister) { |
range->set_spill_slot(Location::StackSlot(idx)); |
} else { |
+ // Double spill slots are essentially one (x64) or two (ia32) normal |
+ // word size spill slots. We use the index of the slot with the lowest |
+ // address as an index for the double spill slot. In terms of indexes |
+ // this relation is inverted: so we have to take the highest index. |
+ const intptr_t slot_idx = |
+ idx * kDoubleSpillSlotFactor + (kDoubleSpillSlotFactor - 1); |
range->set_spill_slot( |
Location::DoubleStackSlot( |
- cpu_spill_slot_count_ + idx * kDoubleSpillSlotFactor)); |
+ cpu_spill_slot_count_ + slot_idx)); |
} |
spilled_.Add(range); |
@@ -1674,7 +1688,7 @@ void FlowGraphAllocator::AssignNonFreeRegister(LiveRange* unallocated, |
if (allocated->vreg() < 0) continue; // Can't be evicted. |
if (EvictIntersection(allocated, unallocated)) { |
// If allocated was not spilled convert all pending uses. |
- if (allocated->assigned_location().IsRegister()) { |
+ if (allocated->assigned_location().IsMachineRegister()) { |
ASSERT(allocated->End() <= unallocated->Start()); |
ConvertAllUses(allocated); |
} |