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

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: 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..0c8d33e15c1fd5344d579ca1a1cc283a54f29bf0 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -991,6 +991,7 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
if (to->IsUnallocated()) {
int to_vreg = UnallocatedOperand::cast(to)->virtual_register();
LiveRange* to_range = LiveRangeFor(to_vreg);
+ // TODO(dcarney): this in no longer reachable.
Jarin 2014/11/19 15:43:04 How about DCHECK(!to_range->is_phi()), then?
dcarney 2014/11/19 15:55:48 i just nuked all the is_phi stuff instead
if (to_range->is_phi()) {
if (to_range->is_non_loop_phi()) {
hint = to_range->current_hint_operand();
@@ -1082,36 +1083,16 @@ 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()) {
@@ -1123,17 +1104,8 @@ void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
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 +1238,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,13 +1314,33 @@ void RegisterAllocator::ResolveControlFlow() {
LiveRangeFinder finder(*this);
for (auto block : code()->instruction_blocks()) {
if (CanEagerlyResolveControlFlow(block)) continue;
+ /* resolve phis */
Jarin 2014/11/19 15:43:04 // style comment?
dcarney 2014/11/19 15:55:48 Done.
+ for (auto phi : block->phis()) {
+ // TODO(dcarney): optimize this - no need to CreateAssignedOperand here
+ // and in ResolveControlFlow.
+ auto* block_bound =
Jarin 2014/11/19 15:43:04 Yeah, this would deserve some comment and/or clean
dcarney 2014/11/19 15:55:48 cleaned up
+ 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);
+ phi->inputs()[pred_index] =
+ pred_bound->range_->CreateAssignedOperand(code_zone());
+ ResolveControlFlow(block, block_bound->range_, pred_block,
+ pred_bound->range_);
+ 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())
@@ -1395,29 +1399,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
« 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