Index: runtime/vm/flow_graph_allocator.cc |
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc |
index db6d1e0704716cefbc0f7f2a424fbf7d0aa6a7a3..168cfb7c37dea97a7949f145450e6cc738ee72c4 100644 |
--- a/runtime/vm/flow_graph_allocator.cc |
+++ b/runtime/vm/flow_graph_allocator.cc |
@@ -635,7 +635,6 @@ static Location::Kind RegisterKindFromPolicy(Location loc) { |
static Location::Kind RegisterKindForResult(Instruction* instr) { |
if ((instr->representation() == kUnboxedDouble) || |
- (instr->representation() == kUnboxedMint) || |
(instr->representation() == kUnboxedFloat32x4) || |
(instr->representation() == kUnboxedInt32x4) || |
(instr->representation() == kUnboxedFloat64x2) || |
@@ -805,8 +804,12 @@ void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
for (intptr_t i = 0; i < env->Length(); ++i) { |
Value* value = env->ValueAt(i); |
- locations[i] = Location::Any(); |
Definition* def = value->definition(); |
+ if (def->HasPairRepresentation()) { |
+ locations[i] = Location::Pair(Location::Any(), Location::Any()); |
+ } else { |
+ locations[i] = Location::Any(); |
+ } |
if (def->IsPushArgument()) { |
// Frame size is unknown until after allocation. |
@@ -830,13 +833,23 @@ void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, |
continue; |
} |
- LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
- range->AddUseInterval(block_start_pos, use_pos); |
- range->AddUse(use_pos, &locations[i]); |
- |
if (def->HasPairRepresentation()) { |
- LiveRange* range = |
+ PairLocation* location_pair = locations[i].AsPairLocation(); |
+ { |
+ // First live range. |
+ LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
+ range->AddUseInterval(block_start_pos, use_pos); |
+ range->AddUse(use_pos, location_pair->SlotAt(0)); |
+ } |
+ { |
+ // Second live range. |
+ LiveRange* range = |
GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); |
+ range->AddUseInterval(block_start_pos, use_pos); |
+ range->AddUse(use_pos, location_pair->SlotAt(1)); |
+ } |
+ } else { |
+ LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
range->AddUseInterval(block_start_pos, use_pos); |
range->AddUse(use_pos, &locations[i]); |
} |
@@ -872,13 +885,25 @@ void FlowGraphAllocator::ProcessMaterializationUses( |
continue; |
} |
- locations[i] = Location::Any(); |
- |
- LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
- range->AddUseInterval(block_start_pos, use_pos); |
- range->AddUse(use_pos, &locations[i]); |
if (def->HasPairRepresentation()) { |
- LiveRange* range = GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); |
+ locations[i] = Location::Pair(Location::Any(), Location::Any()); |
+ PairLocation* location_pair = locations[i].AsPairLocation(); |
+ { |
+ // First live range. |
+ LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
+ range->AddUseInterval(block_start_pos, use_pos); |
+ range->AddUse(use_pos, location_pair->SlotAt(0)); |
+ } |
+ { |
+ // Second live range. |
+ LiveRange* range = |
+ GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); |
+ range->AddUseInterval(block_start_pos, use_pos); |
+ range->AddUse(use_pos, location_pair->SlotAt(1)); |
+ } |
+ } else { |
+ locations[i] = Location::Any(); |
+ LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
range->AddUseInterval(block_start_pos, use_pos); |
range->AddUse(use_pos, &locations[i]); |
} |
@@ -892,7 +917,8 @@ void FlowGraphAllocator::ProcessOneInput(BlockEntryInstr* block, |
intptr_t pos, |
Location* in_ref, |
Value* input, |
- intptr_t vreg) { |
+ intptr_t vreg, |
+ RegisterSet* live_registers) { |
ASSERT(in_ref != NULL); |
ASSERT(!in_ref->IsPairLocation()); |
ASSERT(input != NULL); |
@@ -906,6 +932,9 @@ void FlowGraphAllocator::ProcessOneInput(BlockEntryInstr* block, |
// value --* |
// register [-----) |
// |
+ if (live_registers != NULL) { |
+ live_registers->Add(*in_ref, range->representation()); |
+ } |
MoveOperands* move = |
AddMoveAt(pos - 1, *in_ref, Location::Any()); |
BlockLocation(*in_ref, pos - 1, pos + 1); |
@@ -1117,6 +1146,12 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
locs->out(0).IsUnallocated() && |
(locs->out(0).policy() == Location::kSameAsFirstInput); |
+ // Output is same as first input which is a pair. |
+ if (output_same_as_first_input && locs->in(0).IsPairLocation()) { |
+ // Make out into a PairLocation. |
+ locs->set_out(0, Location::Pair(Location::RequiresRegister(), |
+ Location::RequiresRegister())); |
+ } |
// Add uses from the deoptimization environment. |
if (current->env() != NULL) ProcessEnvironmentUses(block, current); |
@@ -1131,6 +1166,10 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
// the location is the first register or second register. |
Value* input = current->InputAt(j); |
Location* in_ref = locs->in_slot(j); |
+ RegisterSet* live_registers = NULL; |
+ if (locs->HasCallOnSlowPath()) { |
+ live_registers = locs->live_registers(); |
+ } |
if (in_ref->IsPairLocation()) { |
ASSERT(input->definition()->HasPairRepresentation()); |
PairLocation* pair = in_ref->AsPairLocation(); |
@@ -1138,12 +1177,12 @@ void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, |
// Each element of the pair is assigned it's own virtual register number |
// and is allocated its own LiveRange. |
ProcessOneInput(block, pos, pair->SlotAt(0), |
- input, vreg); |
+ input, vreg, live_registers); |
ProcessOneInput(block, pos, pair->SlotAt(1), input, |
- ToSecondPairVreg(vreg)); |
+ ToSecondPairVreg(vreg), live_registers); |
} else { |
ProcessOneInput(block, pos, in_ref, input, |
- input->definition()->ssa_temp_index()); |
+ input->definition()->ssa_temp_index(), live_registers); |
} |
} |
} |
@@ -1525,6 +1564,16 @@ UsePosition* AllocationFinger::FirstRegisterBeneficialUse(intptr_t after) { |
} |
+UsePosition* AllocationFinger::FirstInterferingUse(intptr_t after) { |
+ if (IsInstructionEndPosition(after)) { |
+ // If after is a position at the end of the instruction disregard |
+ // any use occuring at it. |
+ after += 1; |
+ } |
+ return FirstRegisterUse(after); |
+} |
+ |
+ |
void AllocationFinger::UpdateAfterSplit(intptr_t first_use_after_split_pos) { |
if ((first_register_use_ != NULL) && |
(first_register_use_->pos() >= first_use_after_split_pos)) { |
@@ -1698,7 +1747,8 @@ LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range, |
split_pos = ToInstructionStart(to) - 1; |
} |
- ASSERT((split_pos != kIllegalPosition) && (from < split_pos)); |
+ ASSERT(split_pos != kIllegalPosition); |
+ ASSERT(from < split_pos); |
return range->SplitAt(split_pos); |
} |
@@ -1825,8 +1875,7 @@ void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) { |
ASSERT(need_quad); |
location = Location::QuadStackSlot(slot_idx); |
} else { |
- ASSERT((range->representation() == kUnboxedDouble) || |
- (range->representation() == kUnboxedMint)); |
+ ASSERT((range->representation() == kUnboxedDouble)); |
location = Location::DoubleStackSlot(slot_idx); |
} |
range->set_spill_slot(location); |
@@ -2201,9 +2250,8 @@ bool FlowGraphAllocator::UpdateFreeUntil(intptr_t reg, |
return false; |
} |
- const UsePosition* use = |
- allocated->finger()->FirstRegisterBeneficialUse(unallocated->Start()); |
- |
+ UsePosition* use = |
+ allocated->finger()->FirstInterferingUse(start); |
if ((use != NULL) && ((ToInstructionStart(use->pos()) - start) <= 1)) { |
// This register is blocked by interval that is used |
// as register in the current instruction and can't |
@@ -2283,7 +2331,7 @@ bool FlowGraphAllocator::EvictIntersection(LiveRange* allocated, |
if (intersection == kMaxPosition) return false; |
const intptr_t spill_position = first_unallocated->start(); |
- UsePosition* use = allocated->finger()->FirstRegisterUse(spill_position); |
+ UsePosition* use = allocated->finger()->FirstInterferingUse(spill_position); |
if (use == NULL) { |
// No register uses after this point. |
SpillAfter(allocated, spill_position); |
@@ -2318,6 +2366,7 @@ MoveOperands* FlowGraphAllocator::AddMoveAt(intptr_t pos, |
void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) { |
+ ASSERT(!loc.IsPairLocation()); |
ASSERT(use->location_slot() != NULL); |
Location* slot = use->location_slot(); |
ASSERT(slot->IsUnallocated()); |
@@ -2352,7 +2401,7 @@ void FlowGraphAllocator::ConvertAllUses(LiveRange* range) { |
safepoint = safepoint->next()) { |
if (!safepoint->locs()->always_calls()) { |
ASSERT(safepoint->locs()->can_call()); |
- safepoint->locs()->live_registers()->Add(loc); |
+ safepoint->locs()->live_registers()->Add(loc, range->representation()); |
} |
} |
} |
@@ -2666,12 +2715,22 @@ void FlowGraphAllocator::ResolveControlFlow() { |
} |
+static Representation RepresentationForRange(Representation definition_rep) { |
+ if (definition_rep == kUnboxedMint) { |
+ // kUnboxedMint is split into two ranges, each of which are kUntagged. |
+ return kUntagged; |
+ } |
+ return definition_rep; |
+} |
+ |
+ |
void FlowGraphAllocator::CollectRepresentations() { |
// Parameters. |
GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); |
for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); ++i) { |
Definition* def = (*graph_entry->initial_definitions())[i]; |
- value_representations_[def->ssa_temp_index()] = def->representation(); |
+ value_representations_[def->ssa_temp_index()] = |
+ RepresentationForRange(def->representation()); |
ASSERT(!def->HasPairRepresentation()); |
} |
@@ -2687,7 +2746,9 @@ void FlowGraphAllocator::CollectRepresentations() { |
i < catch_entry->initial_definitions()->length(); |
++i) { |
Definition* def = (*catch_entry->initial_definitions())[i]; |
- value_representations_[def->ssa_temp_index()] = def->representation(); |
+ ASSERT(!def->HasPairRepresentation()); |
+ value_representations_[def->ssa_temp_index()] = |
+ RepresentationForRange(def->representation()); |
} |
} |
// Phis. |
@@ -2697,7 +2758,9 @@ void FlowGraphAllocator::CollectRepresentations() { |
// TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. |
PhiInstr* phi = it.Current(); |
if ((phi != NULL) && (phi->ssa_temp_index() >= 0)) { |
- value_representations_[phi->ssa_temp_index()] = phi->representation(); |
+ ASSERT(!phi->HasPairRepresentation()); |
+ value_representations_[phi->ssa_temp_index()] = |
+ RepresentationForRange(phi->representation()); |
} |
} |
} |
@@ -2708,9 +2771,11 @@ void FlowGraphAllocator::CollectRepresentations() { |
Definition* def = instr_it.Current()->AsDefinition(); |
if ((def != NULL) && (def->ssa_temp_index() >= 0)) { |
const intptr_t vreg = def->ssa_temp_index(); |
- value_representations_[vreg] = def->representation(); |
+ value_representations_[vreg] = |
+ RepresentationForRange(def->representation()); |
if (def->HasPairRepresentation()) { |
- value_representations_[ToSecondPairVreg(vreg)] = def->representation(); |
+ value_representations_[ToSecondPairVreg(vreg)] = |
+ RepresentationForRange(def->representation()); |
} |
} |
} |