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

Unified Diff: runtime/vm/flow_graph_allocator.cc

Issue 1377113004: VM: Support phis with pair representations. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rebased Created 5 years, 2 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
« no previous file with comments | « runtime/vm/flow_graph.cc ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_allocator.cc
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 93d964ab067b2c6f308936cd0e09b5e4cad57c55..208a4afbd8e8de0a726326ce18bb6fd2f55696eb 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -222,11 +222,14 @@ void SSALivenessAnalysis::ComputeInitialSets() {
if (block->IsJoinEntry()) {
JoinEntryInstr* join = block->AsJoinEntry();
for (PhiIterator it(join); !it.Done(); it.Advance()) {
- // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation.
PhiInstr* phi = it.Current();
ASSERT(phi != NULL);
kill->Add(phi->ssa_temp_index());
live_in->Remove(phi->ssa_temp_index());
+ if (phi->HasPairRepresentation()) {
+ kill->Add(ToSecondPairVreg(phi->ssa_temp_index()));
+ live_in->Remove(ToSecondPairVreg(phi->ssa_temp_index()));
+ }
// If a phi input is not defined by the corresponding predecessor it
// must be marked live-in for that predecessor.
@@ -239,6 +242,12 @@ void SSALivenessAnalysis::ComputeInitialSets() {
if (!kill_[pred->postorder_number()]->Contains(use)) {
live_in_[pred->postorder_number()]->Add(use);
}
+ if (phi->HasPairRepresentation()) {
+ const intptr_t second_use = ToSecondPairVreg(use);
+ if (!kill_[pred->postorder_number()]->Contains(second_use)) {
+ live_in_[pred->postorder_number()]->Add(second_use);
+ }
+ }
}
}
} else if (block->IsCatchBlockEntry()) {
@@ -774,20 +783,18 @@ Instruction* FlowGraphAllocator::ConnectOutgoingPhiMoves(
// Search for the index of the current block in the predecessors of
// the join.
- const intptr_t pred_idx = join->IndexOfPredecessor(block);
+ const intptr_t pred_index = join->IndexOfPredecessor(block);
// Record the corresponding phi input use for each phi.
- intptr_t move_idx = 0;
+ intptr_t move_index = 0;
for (PhiIterator it(join); !it.Done(); it.Advance()) {
- // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation.
PhiInstr* phi = it.Current();
- Value* val = phi->InputAt(pred_idx);
- MoveOperands* move = parallel_move->MoveOperandsAt(move_idx);
+ Value* val = phi->InputAt(pred_index);
+ MoveOperands* move = parallel_move->MoveOperandsAt(move_index++);
ConstantInstr* constant = val->definition()->AsConstant();
if (constant != NULL) {
move->set_src(Location::Constant(constant));
- move_idx++;
continue;
}
@@ -796,8 +803,7 @@ Instruction* FlowGraphAllocator::ConnectOutgoingPhiMoves(
// g g'
// value --*
//
-
- const intptr_t vreg = val->definition()->ssa_temp_index();
+ intptr_t vreg = val->definition()->ssa_temp_index();
LiveRange* range = GetLiveRange(vreg);
if (interfere_at_backedge != NULL) interfere_at_backedge->Add(vreg);
@@ -806,9 +812,23 @@ Instruction* FlowGraphAllocator::ConnectOutgoingPhiMoves(
pos,
move->src_slot(),
GetLiveRange(phi->ssa_temp_index())->assigned_location_slot());
-
move->set_src(Location::PrefersRegister());
- move_idx++;
+
+ if (val->definition()->HasPairRepresentation()) {
+ move = parallel_move->MoveOperandsAt(move_index++);
+ vreg = ToSecondPairVreg(vreg);
+ range = GetLiveRange(vreg);
+ if (interfere_at_backedge != NULL) {
+ interfere_at_backedge->Add(vreg);
+ }
+ range->AddUseInterval(block->start_pos(), pos);
+ range->AddHintedUse(
+ pos,
+ move->src_slot(),
+ GetLiveRange(ToSecondPairVreg(
+ phi->ssa_temp_index()))->assigned_location_slot());
+ move->set_src(Location::PrefersRegister());
+ }
}
// Begin backward iteration with the instruction before the parallel
@@ -826,11 +846,11 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) {
const bool is_loop_header = BlockInfoAt(join->start_pos())->is_loop_header();
intptr_t move_idx = 0;
for (PhiIterator it(join); !it.Done(); it.Advance()) {
- // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation.
PhiInstr* phi = it.Current();
ASSERT(phi != NULL);
const intptr_t vreg = phi->ssa_temp_index();
ASSERT(vreg >= 0);
+ const bool is_pair_phi = phi->HasPairRepresentation();
// Expected shape of live range:
//
@@ -839,9 +859,14 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) {
//
LiveRange* range = GetLiveRange(vreg);
range->DefineAt(pos); // Shorten live range.
-
if (is_loop_header) range->mark_loop_phi();
+ if (is_pair_phi) {
+ LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg));
+ second_range->DefineAt(pos); // Shorten live range.
+ if (is_loop_header) second_range->mark_loop_phi();
+ }
+
for (intptr_t pred_idx = 0; pred_idx < phi->InputCount(); pred_idx++) {
BlockEntryInstr* pred = join->PredecessorAt(pred_idx);
GotoInstr* goto_instr = pred->last_instruction()->AsGoto();
@@ -850,15 +875,26 @@ void FlowGraphAllocator::ConnectIncomingPhiMoves(JoinEntryInstr* join) {
goto_instr->parallel_move()->MoveOperandsAt(move_idx);
move->set_dest(Location::PrefersRegister());
range->AddUse(pos, move->dest_slot());
+ if (is_pair_phi) {
+ LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg));
+ MoveOperands* second_move =
+ goto_instr->parallel_move()->MoveOperandsAt(move_idx + 1);
+ second_move->set_dest(Location::PrefersRegister());
+ second_range->AddUse(pos, second_move->dest_slot());
+ }
}
// All phi resolution moves are connected. Phi's live range is
// complete.
AssignSafepoints(phi, range);
-
CompleteRange(range, RegisterKindForResult(phi));
+ if (is_pair_phi) {
+ LiveRange* second_range = GetLiveRange(ToSecondPairVreg(vreg));
+ AssignSafepoints(phi, second_range);
+ CompleteRange(second_range, RegisterKindForResult(phi));
+ }
- move_idx++;
+ move_idx += is_pair_phi ? 2 : 1;
}
}
@@ -1499,10 +1535,11 @@ void FlowGraphAllocator::NumberInstructions() {
// For join entry predecessors create phi resolution moves if
// necessary. They will be populated by the register allocator.
JoinEntryInstr* join = block->AsJoinEntry();
- if ((join != NULL) &&
- (join->phis() != NULL) &&
- !join->phis()->is_empty()) {
- const intptr_t phi_count = join->phis()->length();
+ if (join != NULL) {
+ intptr_t move_count = 0;
+ for (PhiIterator it(join); !it.Done(); it.Advance()) {
+ move_count += it.Current()->HasPairRepresentation() ? 2 : 1;
+ }
for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
// Insert the move between the last two instructions of the
// predecessor block (all such blocks have at least two instructions:
@@ -1513,7 +1550,7 @@ void FlowGraphAllocator::NumberInstructions() {
ParallelMoveInstr* move = last->AsGoto()->GetParallelMove();
// Populate the ParallelMove with empty moves.
- for (intptr_t j = 0; j < phi_count; j++) {
+ for (intptr_t j = 0; j < move_count; j++) {
move->AddMove(Location::NoLocation(), Location::NoLocation());
}
}
@@ -2023,7 +2060,6 @@ intptr_t FlowGraphAllocator::FirstIntersectionWithAllocated(
void ReachingDefs::AddPhi(PhiInstr* phi) {
- // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation.
if (phi->reaching_defs() == NULL) {
Zone* zone = flow_graph_.zone();
phi->set_reaching_defs(new(zone) BitVector(
@@ -2037,6 +2073,9 @@ void ReachingDefs::AddPhi(PhiInstr* phi) {
depends_on_phi = true;
}
phi->reaching_defs()->Add(input->ssa_temp_index());
+ if (phi->HasPairRepresentation()) {
+ phi->reaching_defs()->Add(ToSecondPairVreg(input->ssa_temp_index()));
+ }
}
// If this phi depends on another phi then we need fix point iteration.
@@ -2048,7 +2087,6 @@ void ReachingDefs::AddPhi(PhiInstr* phi) {
void ReachingDefs::Compute() {
// Transitively collect all phis that are used by the given phi.
for (intptr_t i = 0; i < phis_.length(); i++) {
- // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation.
PhiInstr* phi = phis_[i];
// Add all phis that affect this phi to the list.
@@ -2153,18 +2191,27 @@ bool FlowGraphAllocator::AllocateFreeRegister(LiveRange* unallocated) {
for (PhiIterator it(loop_header->entry()->AsJoinEntry());
!it.Done();
it.Advance()) {
- // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation.
PhiInstr* phi = it.Current();
ASSERT(phi->is_alive());
const intptr_t phi_vreg = phi->ssa_temp_index();
LiveRange* range = GetLiveRange(phi_vreg);
if (range->assigned_location().kind() == register_kind_) {
const intptr_t reg = range->assigned_location().register_code();
-
if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) {
used_on_backedge[reg] = true;
}
}
+ if (phi->HasPairRepresentation()) {
+ const intptr_t second_phi_vreg = ToSecondPairVreg(phi_vreg);
+ LiveRange* second_range = GetLiveRange(second_phi_vreg);
+ if (second_range->assigned_location().kind() == register_kind_) {
+ const intptr_t reg =
+ second_range->assigned_location().register_code();
+ if (!reaching_defs_.Get(phi)->Contains(unallocated->vreg())) {
+ used_on_backedge[reg] = true;
+ }
+ }
+ }
}
if (used_on_backedge[candidate]) {
@@ -2877,11 +2924,12 @@ void FlowGraphAllocator::CollectRepresentations() {
if (block->IsJoinEntry()) {
JoinEntryInstr* join = block->AsJoinEntry();
for (PhiIterator it(join); !it.Done(); it.Advance()) {
- // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation.
PhiInstr* phi = it.Current();
- if ((phi != NULL) && (phi->ssa_temp_index() >= 0)) {
- ASSERT(!phi->HasPairRepresentation());
- value_representations_[phi->ssa_temp_index()] =
+ ASSERT(phi != NULL && phi->ssa_temp_index() >= 0);
+ value_representations_[phi->ssa_temp_index()] =
+ RepresentationForRange(phi->representation());
+ if (phi->HasPairRepresentation()) {
+ value_representations_[ToSecondPairVreg(phi->ssa_temp_index())] =
RepresentationForRange(phi->representation());
}
}
« no previous file with comments | « runtime/vm/flow_graph.cc ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698