Chromium Code Reviews| 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 |