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

Unified Diff: runtime/vm/flow_graph_allocator.cc

Issue 252333002: Use GPRs for mints (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 7 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 4a3d66dc4f371fc85a04fe32470edf14a8bfde2e..bfc098f8a727cf7458891c635ecc29caee3e2064 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -398,11 +398,24 @@ void LiveRange::Print() {
return;
}
- OS::Print(" live range v%" Pd " [%" Pd ", %" Pd ") in ",
- vreg(), Start(), End());
+ OS::Print(" live range v%" Pd " [%" Pd ", %" Pd ") in ", vreg(),
+ Start(),
+ End());
assigned_location().Print();
+ if (spill_slot_.HasStackIndex()) {
+ intptr_t stack_slot = spill_slot_.stack_index();
+ OS::Print(" allocated spill slot: %" Pd "", stack_slot);
+ }
OS::Print("\n");
+ SafepointPosition* safepoint = first_safepoint();
+ while (safepoint != NULL) {
+ OS::Print(" Safepoint [%" Pd "]: ", safepoint->pos());
+ safepoint->locs()->stack_bitmap()->Print();
+ OS::Print("\n");
+ safepoint = safepoint->next();
+ }
+
UsePosition* use_pos = uses_;
for (UseInterval* interval = first_use_interval_;
interval != NULL;
@@ -564,6 +577,7 @@ void FlowGraphAllocator::BuildLiveRanges() {
GraphEntryInstr* graph_entry = flow_graph_.graph_entry();
for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) {
Definition* defn = (*graph_entry->initial_definitions())[i];
+ ASSERT(!defn->HasPairRepresentation());
LiveRange* range = GetLiveRange(defn->ssa_temp_index());
range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos());
range->DefineAt(graph_entry->start_pos());
@@ -612,11 +626,14 @@ void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn,
// in stack maps.
spill_slots_.Add(range_end);
quad_spill_slots_.Add(false);
+ untagged_spill_slots_.Add(false);
+ // Note, all incoming parameters are assumed to be tagged.
MarkAsObjectAtSafepoints(range);
} else if (defn->IsConstant() && block->IsCatchBlockEntry()) {
// Constants at catch block entries consume spill slots.
spill_slots_.Add(range_end);
quad_spill_slots_.Add(false);
+ untagged_spill_slots_.Add(false);
}
}
@@ -632,7 +649,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) ||
@@ -802,8 +818,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.
@@ -827,13 +847,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]);
}
@@ -869,13 +899,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]);
}
@@ -889,7 +931,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);
@@ -903,6 +946,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);
@@ -1114,6 +1160,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);
@@ -1128,6 +1180,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();
@@ -1135,12 +1191,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);
}
}
}
@@ -1522,6 +1578,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)) {
@@ -1695,7 +1761,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);
}
@@ -1769,6 +1836,8 @@ void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) {
((range->representation() == kUnboxedFloat32x4) ||
(range->representation() == kUnboxedInt32x4) ||
(range->representation() == kUnboxedFloat64x2));
+ const bool need_untagged = (register_kind_ == Location::kRegister) &&
+ ((range->representation() == kUntagged));
// 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
@@ -1780,6 +1849,7 @@ void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) {
: 0;
for (; idx < spill_slots_.length(); idx++) {
if ((need_quad == quad_spill_slots_[idx]) &&
+ (need_untagged == untagged_spill_slots_[idx]) &&
(spill_slots_[idx] <= start)) {
break;
}
@@ -1789,9 +1859,11 @@ void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) {
// No free spill slot found. Allocate a new one.
spill_slots_.Add(0);
quad_spill_slots_.Add(need_quad);
+ untagged_spill_slots_.Add(need_untagged);
if (need_quad) { // Allocate two double stack slots if we need quad slot.
spill_slots_.Add(0);
quad_spill_slots_.Add(need_quad);
+ untagged_spill_slots_.Add(need_untagged);
}
}
@@ -1822,8 +1894,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);
@@ -1841,6 +1912,7 @@ void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) {
for (SafepointPosition* safepoint = range->first_safepoint();
safepoint != NULL;
safepoint = safepoint->next()) {
+ // Mark the stack slot as having an object.
safepoint->locs()->stack_bitmap()->Set(stack_index, true);
}
range = range->next_sibling();
@@ -2199,9 +2271,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
@@ -2281,7 +2352,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);
@@ -2316,6 +2387,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());
@@ -2350,7 +2422,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());
}
}
}
@@ -2669,12 +2741,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());
}
@@ -2690,7 +2772,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.
@@ -2700,7 +2784,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());
}
}
}
@@ -2711,9 +2797,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());
}
}
}
@@ -2761,6 +2849,7 @@ void FlowGraphAllocator::AllocateRegisters() {
cpu_spill_slot_count_ = spill_slots_.length();
spill_slots_.Clear();
quad_spill_slots_.Clear();
+ untagged_spill_slots_.Clear();
PrepareForAllocation(Location::kFpuRegister,
kNumberOfFpuRegisters,

Powered by Google App Engine
This is Rietveld 408576698