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

Unified Diff: src/compiler/register-allocator.cc

Issue 751543002: [turbofan] put late ssa deconstruction in register allocator behind a flag (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 6 years, 1 month 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 | « src/compiler/register-allocator.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/register-allocator.cc
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
index 283603a44e1728e6a9c8ae82b79fa053415a5c73..3e1ac629417d6f5c8a66ccd425fc5f323df8730c 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -100,6 +100,8 @@ bool LiveRange::HasOverlap(UseInterval* target) const {
LiveRange::LiveRange(int id, Zone* zone)
: id_(id),
spilled_(false),
+ is_phi_(false),
+ is_non_loop_phi_(false),
kind_(UNALLOCATED_REGISTERS),
assigned_register_(kInvalidAssignment),
last_interval_(NULL),
@@ -1163,12 +1165,20 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
InstructionOperand* hint = to;
if (to->IsUnallocated()) {
int to_vreg = UnallocatedOperand::cast(to)->virtual_register();
- if (live->Contains(to_vreg)) {
- Define(curr_position, to, from);
- live->Remove(to_vreg);
+ LiveRange* to_range = LiveRangeFor(to_vreg);
+ if (to_range->is_phi()) {
+ DCHECK(!FLAG_turbo_delay_ssa_decon);
+ if (to_range->is_non_loop_phi()) {
+ hint = to_range->current_hint_operand();
+ }
} else {
- cur->Eliminate();
- continue;
+ if (live->Contains(to_vreg)) {
+ Define(curr_position, to, from);
+ live->Remove(to_vreg);
+ } else {
+ cur->Eliminate();
+ continue;
+ }
}
} else {
Define(curr_position, to, from);
@@ -1248,28 +1258,53 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
}
-void RegisterAllocator::ProcessPhis(const InstructionBlock* block) {
+void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
for (auto phi : block->phis()) {
auto output = phi->output();
int phi_vreg = phi->virtual_register();
+ if (!FLAG_turbo_delay_ssa_decon) {
+ for (size_t i = 0; i < phi->operands().size(); ++i) {
+ InstructionBlock* cur_block =
+ code()->InstructionBlockAt(block->predecessors()[i]);
+ // The gap move must be added without any special processing as in
+ // the AddConstraintsGapMove.
+ code()->AddGapMove(cur_block->last_instruction_index() - 1,
+ phi->inputs()[i], output);
+ DCHECK(!InstructionAt(cur_block->last_instruction_index())
+ ->HasPointerMap());
+ }
+ }
LiveRange* live_range = LiveRangeFor(phi_vreg);
BlockStartInstruction* block_start =
code()->GetBlockStart(block->rpo_number());
block_start->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone())
->AddMove(output, live_range->GetSpillOperand(), code_zone());
live_range->SetSpillStartIndex(block->first_instruction_index());
+ // We use the phi-ness of some nodes in some later heuristics.
+ live_range->set_is_phi(true);
+ if (!block->IsLoopHeader()) {
+ live_range->set_is_non_loop_phi(true);
+ }
}
}
void RegisterAllocator::MeetRegisterConstraints() {
for (auto block : code()->instruction_blocks()) {
- ProcessPhis(block);
MeetRegisterConstraints(block);
}
}
+void RegisterAllocator::ResolvePhis() {
+ // Process the blocks in reverse order.
+ for (auto i = code()->instruction_blocks().rbegin();
+ i != code()->instruction_blocks().rend(); ++i) {
+ ResolvePhis(*i);
+ }
+}
+
+
ParallelMove* RegisterAllocator::GetConnectingParallelMove(
LifetimePosition pos) {
int index = pos.InstructionIndex();
@@ -1474,21 +1509,24 @@ void RegisterAllocator::ResolveControlFlow() {
LiveRangeFinder finder(*this);
for (auto block : code()->instruction_blocks()) {
if (CanEagerlyResolveControlFlow(block)) continue;
- // resolve phis
- for (auto phi : block->phis()) {
- auto* block_bound =
- finder.ArrayFor(phi->virtual_register())->FindSucc(block);
- auto phi_output = block_bound->range_->CreateAssignedOperand(code_zone());
- phi->output()->ConvertTo(phi_output->kind(), phi_output->index());
- size_t pred_index = 0;
- for (auto pred : block->predecessors()) {
- const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
- auto* pred_bound =
- finder.ArrayFor(phi->operands()[pred_index])->FindPred(pred_block);
- auto pred_op = pred_bound->range_->CreateAssignedOperand(code_zone());
- phi->inputs()[pred_index] = pred_op;
- ResolveControlFlow(block, phi_output, pred_block, pred_op);
- pred_index++;
+ if (FLAG_turbo_delay_ssa_decon) {
+ // resolve phis
+ for (auto phi : block->phis()) {
+ auto* block_bound =
+ finder.ArrayFor(phi->virtual_register())->FindSucc(block);
+ auto phi_output =
+ block_bound->range_->CreateAssignedOperand(code_zone());
+ phi->output()->ConvertTo(phi_output->kind(), phi_output->index());
+ size_t pred_index = 0;
+ for (auto pred : block->predecessors()) {
+ const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
+ auto* pred_bound = finder.ArrayFor(phi->operands()[pred_index])
+ ->FindPred(pred_block);
+ auto pred_op = pred_bound->range_->CreateAssignedOperand(code_zone());
+ phi->inputs()[pred_index] = pred_op;
+ ResolveControlFlow(block, phi_output, pred_block, pred_op);
+ pred_index++;
+ }
}
}
BitVector* live = live_in_sets_[block->rpo_number().ToInt()];
@@ -1556,6 +1594,27 @@ void RegisterAllocator::BuildLiveRanges() {
// block.
int phi_vreg = phi->virtual_register();
live->Remove(phi_vreg);
+ if (!FLAG_turbo_delay_ssa_decon) {
+ InstructionOperand* hint = NULL;
+ InstructionOperand* phi_operand = NULL;
+ GapInstruction* gap =
+ GetLastGap(code()->InstructionBlockAt(block->predecessors()[0]));
+ ParallelMove* move =
+ gap->GetOrCreateParallelMove(GapInstruction::START, code_zone());
+ for (int j = 0; j < move->move_operands()->length(); ++j) {
+ InstructionOperand* to = move->move_operands()->at(j).destination();
+ if (to->IsUnallocated() &&
+ UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) {
+ hint = move->move_operands()->at(j).source();
+ phi_operand = to;
+ break;
+ }
+ }
+ DCHECK(hint != NULL);
+ LifetimePosition block_start = LifetimePosition::FromInstructionIndex(
+ block->first_instruction_index());
+ Define(block_start, phi_operand, hint);
+ }
}
// Now live is live_in for this block except not including values live
@@ -1600,7 +1659,13 @@ void RegisterAllocator::BuildLiveRanges() {
for (UsePosition* pos = range->first_pos(); pos != NULL;
pos = pos->next_) {
pos->register_beneficial_ = true;
- pos->requires_reg_ = true;
+ // TODO(dcarney): should the else case assert requires_reg_ == false?
+ // Can't mark phis as needing a register.
+ if (!code()
+ ->InstructionAt(pos->pos().InstructionIndex())
+ ->IsGapMoves()) {
+ pos->requires_reg_ = true;
+ }
}
}
}
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698