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

Unified Diff: runtime/vm/flow_graph_allocator.cc

Issue 13801014: Fix bug in ParallelMoveResolver::EmitSwap: implement swaps of FPU spill slots. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix typo Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_allocator.cc
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index c1f8f32ae3de9e664b8cae436d610f400da0314b..3b89ebad25f2a9007eddb9decafaa0b6642315ea 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -606,6 +606,7 @@ void FlowGraphAllocator::BuildLiveRanges() {
if (flow_graph_.num_copied_params() > 0) {
ASSERT(spill_slots_.length() == slot_index);
spill_slots_.Add(range->End());
+ quad_spill_slots_.Add(false);
}
AssignSafepoints(range);
} else {
@@ -993,9 +994,8 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
}
for (intptr_t reg = 0; reg < kNumberOfFpuRegisters; reg++) {
- Representation ignored = kNoRepresentation;
BlockLocation(
- Location::FpuRegisterLocation(static_cast<FpuRegister>(reg), ignored),
+ Location::FpuRegisterLocation(static_cast<FpuRegister>(reg)),
pos,
pos + 1);
}
@@ -1581,40 +1581,76 @@ void FlowGraphAllocator::SpillAfter(LiveRange* range, intptr_t from) {
void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) {
ASSERT(range->spill_slot().IsInvalid());
+ // Compute range start and end.
+ LiveRange* last_sibling = range;
+ while (last_sibling->next_sibling() != NULL) {
+ last_sibling = last_sibling->next_sibling();
+ }
+
+ const intptr_t start = range->Start();
+ const intptr_t end = last_sibling->End();
+
+ // During fpu register allocation spill slot indices are computed in terms of
+ // double (64bit) stack slots. We treat quad stack slot (128bit) as a
+ // consecutive pair of two double spill slots.
+ // Special care is taken to never allocate the same index to both
+ // double and quad spill slots as it complicates disambiguation during
+ // parallel move resolution.
+ const bool need_quad = (register_kind_ == Location::kFpuRegister) &&
+ ((range->representation() == kUnboxedFloat32x4) ||
+ (range->representation() == kUnboxedUint32x4));
+
+ // Search for a free spill slot among allocated: the value in it should be
+ // dead and its type should match (e.g. it should not be a part of the quad if
+ // we are allocating normal double slot).
intptr_t idx = 0;
for (; idx < spill_slots_.length(); idx++) {
- if (spill_slots_[idx] <= range->Start()) break;
+ if ((need_quad == quad_spill_slots_[idx]) &&
+ (spill_slots_[idx] <= start)) {
+ break;
+ }
}
- if (idx == spill_slots_.length()) spill_slots_.Add(0);
-
- LiveRange* last_sibling = range;
- while (last_sibling->next_sibling() != NULL) {
- last_sibling = last_sibling->next_sibling();
+ if (idx == spill_slots_.length()) {
+ // No free spill slot found. Allocate a new one.
+ spill_slots_.Add(0);
+ quad_spill_slots_.Add(need_quad);
+ if (need_quad) { // Allocate two double stack slots if we need quad slot.
+ spill_slots_.Add(0);
+ quad_spill_slots_.Add(need_quad);
+ }
}
- spill_slots_[idx] = last_sibling->End();
+ // Set spill slot expiration boundary to the live range's end.
+ spill_slots_[idx] = end;
+ if (need_quad) {
+ ASSERT(quad_spill_slots_[idx] && quad_spill_slots_[idx + 1]);
+ idx++; // Use the higher index it corresponds to the lower stack address.
+ spill_slots_[idx] = end;
+ } else {
+ ASSERT(!quad_spill_slots_[idx]);
+ }
+
+ // Assign spill slot to the range.
if (register_kind_ == Location::kRegister) {
range->set_spill_slot(Location::StackSlot(idx));
} else {
- // FPU register spill slots are essentially two (x64) or four (ia32) normal
- // word size spill slots. We use the index of the slot with the lowest
- // address as an index for the FPU register spill slot. In terms of indexes
- // this relation is inverted: so we have to take the highest index.
+ // We use the index of the slot with the lowest address as an index for the
+ // FPU register spill slot. In terms of indexes this relation is inverted:
+ // so we have to take the highest index.
const intptr_t slot_idx = cpu_spill_slot_count_ +
- idx * kFpuRegisterSpillFactor + (kFpuRegisterSpillFactor - 1);
+ idx * kDoubleSpillFactor + (kDoubleSpillFactor - 1);
Location location;
- if (range->representation() == kUnboxedFloat32x4) {
- location = Location::Float32x4StackSlot(slot_idx);
- } else if (range->representation() == kUnboxedUint32x4) {
- location = Location::Uint32x4StackSlot(slot_idx);
+ if ((range->representation() == kUnboxedFloat32x4) ||
+ (range->representation() == kUnboxedUint32x4)) {
+ ASSERT(need_quad);
+ location = Location::QuadStackSlot(slot_idx);
} else {
ASSERT((range->representation() == kUnboxedDouble) ||
(range->representation() == kUnboxedMint));
- location = Location::DoubleStackSlot(slot_idx,
- range->representation());
+ location = Location::DoubleStackSlot(slot_idx);
}
range->set_spill_slot(location);
}
@@ -1815,7 +1851,7 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
TRACE_ALLOC(OS::Print(
"considering %s for v%"Pd": has interference on the back edge"
" {loop [%"Pd", %"Pd")}\n",
- MakeRegisterLocation(candidate, kUnboxedDouble).Name(),
+ MakeRegisterLocation(candidate).Name(),
unallocated->vreg(),
loop_header->entry()->start_pos(),
loop_header->last_block()->end_pos()));
@@ -1833,7 +1869,7 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
free_until = intersection;
TRACE_ALLOC(OS::Print(
"found %s for v%"Pd" with no interference on the back edge\n",
- MakeRegisterLocation(candidate, kUnboxedDouble).Name(),
+ MakeRegisterLocation(candidate).Name(),
candidate));
break;
}
@@ -1842,7 +1878,7 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
}
TRACE_ALLOC(OS::Print("assigning free register "));
- TRACE_ALLOC(MakeRegisterLocation(candidate, kUnboxedDouble).Print());
+ TRACE_ALLOC(MakeRegisterLocation(candidate).Print());
TRACE_ALLOC(OS::Print(" to v%"Pd"\n", unallocated->vreg()));
if (free_until != kMaxPosition) {
@@ -1853,8 +1889,7 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
}
registers_[candidate].Add(unallocated);
- unallocated->set_assigned_location(
- MakeRegisterLocation(candidate, unallocated->representation()));
+ unallocated->set_assigned_location(MakeRegisterLocation(candidate));
return true;
}
@@ -1945,7 +1980,7 @@ void FlowGraphAllocator::AllocateAnyRegister(LiveRange* unallocated) {
}
TRACE_ALLOC(OS::Print("assigning blocked register "));
- TRACE_ALLOC(MakeRegisterLocation(candidate, kUnboxedDouble).Print());
+ TRACE_ALLOC(MakeRegisterLocation(candidate).Print());
TRACE_ALLOC(OS::Print(" to live range v%"Pd" until %"Pd"\n",
unallocated->vreg(), blocked_at));
@@ -2051,8 +2086,7 @@ void FlowGraphAllocator::AssignNonFreeRegister(LiveRange* unallocated,
if (first_evicted != -1) RemoveEvicted(reg, first_evicted);
registers_[reg].Add(unallocated);
- unallocated->set_assigned_location(
- MakeRegisterLocation(reg, unallocated->representation()));
+ unallocated->set_assigned_location(MakeRegisterLocation(reg));
}
@@ -2522,6 +2556,7 @@ void FlowGraphAllocator::AllocateRegisters() {
cpu_spill_slot_count_ = spill_slots_.length();
spill_slots_.Clear();
+ quad_spill_slots_.Clear();
PrepareForAllocation(Location::kFpuRegister,
kNumberOfFpuRegisters,
@@ -2534,8 +2569,7 @@ void FlowGraphAllocator::AllocateRegisters() {
GraphEntryInstr* entry = block_order_[0]->AsGraphEntry();
ASSERT(entry != NULL);
- intptr_t double_spill_slot_count =
- spill_slots_.length() * kFpuRegisterSpillFactor;
+ intptr_t double_spill_slot_count = spill_slots_.length() * kDoubleSpillFactor;
entry->set_spill_slot_count(cpu_spill_slot_count_ + double_spill_slot_count);
if (FLAG_print_ssa_liveranges) {

Powered by Google App Engine
This is Rietveld 408576698