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

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

Issue 738853002: [turbofan]: delay ssa deconstruction in register allocator (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/compiler/register-allocator-verifier.cc » ('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 66e250c4c2cfd2f9422913d3c66f088cdeb5a94b..a9cdf51b5636d7d2d0f484c6e2e36875e89cf3c9 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -100,8 +100,6 @@ 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),
@@ -990,19 +988,12 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
InstructionOperand* hint = to;
if (to->IsUnallocated()) {
int to_vreg = UnallocatedOperand::cast(to)->virtual_register();
- LiveRange* to_range = LiveRangeFor(to_vreg);
- if (to_range->is_phi()) {
- if (to_range->is_non_loop_phi()) {
- hint = to_range->current_hint_operand();
- }
+ if (live->Contains(to_vreg)) {
+ Define(curr_position, to, from);
+ live->Remove(to_vreg);
} else {
- if (live->Contains(to_vreg)) {
- Define(curr_position, to, from);
- live->Remove(to_vreg);
- } else {
- cur->Eliminate();
- continue;
- }
+ cur->Eliminate();
+ continue;
}
} else {
Define(curr_position, to, from);
@@ -1082,58 +1073,24 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
}
-void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
+void RegisterAllocator::ProcessPhis(const InstructionBlock* block) {
for (auto phi : block->phis()) {
- UnallocatedOperand* phi_operand =
- new (code_zone()) UnallocatedOperand(UnallocatedOperand::NONE);
+ auto output = phi->output();
int phi_vreg = phi->virtual_register();
- phi_operand->set_virtual_register(phi_vreg);
-
- for (size_t i = 0; i < phi->operands().size(); ++i) {
- UnallocatedOperand* operand =
- new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY);
- operand->set_virtual_register(phi->operands()[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, operand,
- phi_operand);
-
- Instruction* branch = InstructionAt(cur_block->last_instruction_index());
- DCHECK(!branch->HasPointerMap());
- USE(branch);
- }
-
LiveRange* live_range = LiveRangeFor(phi_vreg);
BlockStartInstruction* block_start =
code()->GetBlockStart(block->rpo_number());
- block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone())
- ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone());
+ 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);
- if (!AllocationOk()) return;
- }
-}
-
-
-void RegisterAllocator::ResolvePhis() {
- // Process the blocks in reverse order.
- for (auto i = code()->instruction_blocks().rbegin();
- i != code()->instruction_blocks().rend(); ++i) {
- ResolvePhis(*i);
}
}
@@ -1266,6 +1223,18 @@ class LiveRangeBoundArray {
}
}
+ LiveRangeBound* FindPred(const InstructionBlock* pred) {
+ const LifetimePosition pred_end =
+ LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
+ return Find(pred_end);
+ }
+
+ LiveRangeBound* FindSucc(const InstructionBlock* succ) {
+ const LifetimePosition succ_start =
+ LifetimePosition::FromInstructionIndex(succ->first_instruction_index());
+ return Find(succ_start);
+ }
+
void Find(const InstructionBlock* block, const InstructionBlock* pred,
FindResult* result) const {
const LifetimePosition pred_end =
@@ -1330,19 +1299,39 @@ 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++;
+ }
+ }
BitVector* live = live_in_sets_[block->rpo_number().ToInt()];
BitVector::Iterator iterator(live);
while (!iterator.Done()) {
- LiveRangeBoundArray* array = finder.ArrayFor(iterator.Current());
+ auto* array = finder.ArrayFor(iterator.Current());
for (auto pred : block->predecessors()) {
FindResult result;
- const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
+ const auto* pred_block = code()->InstructionBlockAt(pred);
array->Find(block, pred_block, &result);
if (result.cur_cover_ == result.pred_cover_ ||
result.cur_cover_->IsSpilled())
continue;
- ResolveControlFlow(block, result.cur_cover_, pred_block,
- result.pred_cover_);
+ InstructionOperand* pred_op =
+ result.pred_cover_->CreateAssignedOperand(code_zone());
+ InstructionOperand* cur_op =
+ result.cur_cover_->CreateAssignedOperand(code_zone());
+ ResolveControlFlow(block, cur_op, pred_block, pred_op);
}
iterator.Advance();
}
@@ -1351,26 +1340,23 @@ void RegisterAllocator::ResolveControlFlow() {
void RegisterAllocator::ResolveControlFlow(const InstructionBlock* block,
- const LiveRange* cur_cover,
+ InstructionOperand* cur_op,
const InstructionBlock* pred,
- const LiveRange* pred_cover) {
- InstructionOperand* pred_op = pred_cover->CreateAssignedOperand(code_zone());
- InstructionOperand* cur_op = cur_cover->CreateAssignedOperand(code_zone());
- if (!pred_op->Equals(cur_op)) {
- GapInstruction* gap = NULL;
- if (block->PredecessorCount() == 1) {
- gap = code()->GapAt(block->first_instruction_index());
- } else {
- DCHECK(pred->SuccessorCount() == 1);
- gap = GetLastGap(pred);
+ InstructionOperand* pred_op) {
+ if (pred_op->Equals(cur_op)) return;
+ GapInstruction* gap = nullptr;
+ if (block->PredecessorCount() == 1) {
+ gap = code()->GapAt(block->first_instruction_index());
+ } else {
+ DCHECK(pred->SuccessorCount() == 1);
+ gap = GetLastGap(pred);
- Instruction* branch = InstructionAt(pred->last_instruction_index());
- DCHECK(!branch->HasPointerMap());
- USE(branch);
- }
- gap->GetOrCreateParallelMove(GapInstruction::START, code_zone())
- ->AddMove(pred_op, cur_op, code_zone());
+ Instruction* branch = InstructionAt(pred->last_instruction_index());
+ DCHECK(!branch->HasPointerMap());
+ USE(branch);
}
+ gap->GetOrCreateParallelMove(GapInstruction::START, code_zone())
+ ->AddMove(pred_op, cur_op, code_zone());
}
@@ -1395,29 +1381,6 @@ void RegisterAllocator::BuildLiveRanges() {
// block.
int phi_vreg = phi->virtual_register();
live->Remove(phi_vreg);
-
- InstructionOperand* hint = NULL;
- InstructionOperand* phi_operand = NULL;
- GapInstruction* gap =
- GetLastGap(code()->InstructionBlockAt(block->predecessors()[0]));
-
- // TODO(titzer): no need to create the parallel move if it doesn't exit.
- 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
@@ -1462,13 +1425,7 @@ void RegisterAllocator::BuildLiveRanges() {
for (UsePosition* pos = range->first_pos(); pos != NULL;
pos = pos->next_) {
pos->register_beneficial_ = 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;
- }
+ pos->requires_reg_ = true;
}
}
}
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/register-allocator-verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698