OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/register-allocator.h" | 5 #include "src/compiler/register-allocator.h" |
6 | 6 |
7 #include "src/compiler/generic-node-inl.h" | 7 #include "src/compiler/generic-node-inl.h" |
8 #include "src/compiler/linkage.h" | 8 #include "src/compiler/linkage.h" |
9 #include "src/hydrogen.h" | 9 #include "src/hydrogen.h" |
10 #include "src/string-stream.h" | 10 #include "src/string-stream.h" |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 | 541 |
542 // All phi input operands corresponding to this successor edge are live | 542 // All phi input operands corresponding to this successor edge are live |
543 // out from this block. | 543 // out from this block. |
544 size_t index = successor->PredecessorIndexOf(block); | 544 size_t index = successor->PredecessorIndexOf(block); |
545 DCHECK(index < successor->PredecessorCount()); | 545 DCHECK(index < successor->PredecessorCount()); |
546 for (BasicBlock::const_iterator j = successor->begin(); | 546 for (BasicBlock::const_iterator j = successor->begin(); |
547 j != successor->end(); ++j) { | 547 j != successor->end(); ++j) { |
548 Node* phi = *j; | 548 Node* phi = *j; |
549 if (phi->opcode() != IrOpcode::kPhi) continue; | 549 if (phi->opcode() != IrOpcode::kPhi) continue; |
550 Node* input = phi->InputAt(static_cast<int>(index)); | 550 Node* input = phi->InputAt(static_cast<int>(index)); |
551 live_out->Add(input->id()); | 551 live_out->Add(code()->GetVirtualRegister(input)); |
552 } | 552 } |
553 } | 553 } |
554 | |
555 return live_out; | 554 return live_out; |
556 } | 555 } |
557 | 556 |
558 | 557 |
559 void RegisterAllocator::AddInitialIntervals(BasicBlock* block, | 558 void RegisterAllocator::AddInitialIntervals(BasicBlock* block, |
560 BitVector* live_out) { | 559 BitVector* live_out) { |
561 // Add an interval that includes the entire block to the live range for | 560 // Add an interval that includes the entire block to the live range for |
562 // each live_out value. | 561 // each live_out value. |
563 LifetimePosition start = | 562 LifetimePosition start = |
564 LifetimePosition::FromInstructionIndex(block->first_instruction_index()); | 563 LifetimePosition::FromInstructionIndex(block->first_instruction_index()); |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1059 } | 1058 } |
1060 | 1059 |
1061 | 1060 |
1062 void RegisterAllocator::ResolvePhis(BasicBlock* block) { | 1061 void RegisterAllocator::ResolvePhis(BasicBlock* block) { |
1063 for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) { | 1062 for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) { |
1064 Node* phi = *i; | 1063 Node* phi = *i; |
1065 if (phi->opcode() != IrOpcode::kPhi) continue; | 1064 if (phi->opcode() != IrOpcode::kPhi) continue; |
1066 | 1065 |
1067 UnallocatedOperand* phi_operand = | 1066 UnallocatedOperand* phi_operand = |
1068 new (code_zone()) UnallocatedOperand(UnallocatedOperand::NONE); | 1067 new (code_zone()) UnallocatedOperand(UnallocatedOperand::NONE); |
1069 phi_operand->set_virtual_register(phi->id()); | 1068 int phi_vreg = code()->GetVirtualRegister(phi); |
| 1069 phi_operand->set_virtual_register(phi_vreg); |
1070 | 1070 |
1071 size_t j = 0; | 1071 size_t j = 0; |
1072 Node::Inputs inputs = phi->inputs(); | 1072 Node::Inputs inputs = phi->inputs(); |
1073 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | 1073 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); |
1074 ++iter, ++j) { | 1074 ++iter, ++j) { |
1075 Node* op = *iter; | 1075 Node* op = *iter; |
1076 // TODO(mstarzinger): Use a ValueInputIterator instead. | 1076 // TODO(mstarzinger): Use a ValueInputIterator instead. |
1077 if (j >= block->PredecessorCount()) continue; | 1077 if (j >= block->PredecessorCount()) continue; |
1078 UnallocatedOperand* operand = | 1078 UnallocatedOperand* operand = |
1079 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); | 1079 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); |
1080 operand->set_virtual_register(op->id()); | 1080 operand->set_virtual_register(code()->GetVirtualRegister(op)); |
1081 BasicBlock* cur_block = block->PredecessorAt(j); | 1081 BasicBlock* cur_block = block->PredecessorAt(j); |
1082 // The gap move must be added without any special processing as in | 1082 // The gap move must be added without any special processing as in |
1083 // the AddConstraintsGapMove. | 1083 // the AddConstraintsGapMove. |
1084 code()->AddGapMove(cur_block->last_instruction_index() - 1, operand, | 1084 code()->AddGapMove(cur_block->last_instruction_index() - 1, operand, |
1085 phi_operand); | 1085 phi_operand); |
1086 | 1086 |
1087 Instruction* branch = InstructionAt(cur_block->last_instruction_index()); | 1087 Instruction* branch = InstructionAt(cur_block->last_instruction_index()); |
1088 DCHECK(!branch->HasPointerMap()); | 1088 DCHECK(!branch->HasPointerMap()); |
1089 USE(branch); | 1089 USE(branch); |
1090 } | 1090 } |
1091 | 1091 |
1092 LiveRange* live_range = LiveRangeFor(phi->id()); | 1092 LiveRange* live_range = LiveRangeFor(phi_vreg); |
1093 BlockStartInstruction* block_start = code()->GetBlockStart(block); | 1093 BlockStartInstruction* block_start = code()->GetBlockStart(block); |
1094 block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone()) | 1094 block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone()) |
1095 ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone()); | 1095 ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone()); |
1096 live_range->SetSpillStartIndex(block->first_instruction_index()); | 1096 live_range->SetSpillStartIndex(block->first_instruction_index()); |
1097 | 1097 |
1098 // We use the phi-ness of some nodes in some later heuristics. | 1098 // We use the phi-ness of some nodes in some later heuristics. |
1099 live_range->set_is_phi(true); | 1099 live_range->set_is_phi(true); |
1100 if (!block->IsLoopHeader()) { | 1100 if (!block->IsLoopHeader()) { |
1101 live_range->set_is_non_loop_phi(true); | 1101 live_range->set_is_non_loop_phi(true); |
1102 } | 1102 } |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1291 // live values. | 1291 // live values. |
1292 ProcessInstructions(block, live); | 1292 ProcessInstructions(block, live); |
1293 // All phi output operands are killed by this block. | 1293 // All phi output operands are killed by this block. |
1294 for (BasicBlock::const_iterator i = block->begin(); i != block->end(); | 1294 for (BasicBlock::const_iterator i = block->begin(); i != block->end(); |
1295 ++i) { | 1295 ++i) { |
1296 Node* phi = *i; | 1296 Node* phi = *i; |
1297 if (phi->opcode() != IrOpcode::kPhi) continue; | 1297 if (phi->opcode() != IrOpcode::kPhi) continue; |
1298 | 1298 |
1299 // The live range interval already ends at the first instruction of the | 1299 // The live range interval already ends at the first instruction of the |
1300 // block. | 1300 // block. |
1301 live->Remove(phi->id()); | 1301 int phi_vreg = code()->GetVirtualRegister(phi); |
| 1302 live->Remove(phi_vreg); |
1302 | 1303 |
1303 InstructionOperand* hint = NULL; | 1304 InstructionOperand* hint = NULL; |
1304 InstructionOperand* phi_operand = NULL; | 1305 InstructionOperand* phi_operand = NULL; |
1305 GapInstruction* gap = GetLastGap(block->PredecessorAt(0)); | 1306 GapInstruction* gap = GetLastGap(block->PredecessorAt(0)); |
1306 | 1307 |
1307 // TODO(titzer): no need to create the parallel move if it doesn't exit. | 1308 // TODO(titzer): no need to create the parallel move if it doesn't exit. |
1308 ParallelMove* move = | 1309 ParallelMove* move = |
1309 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()); | 1310 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()); |
1310 for (int j = 0; j < move->move_operands()->length(); ++j) { | 1311 for (int j = 0; j < move->move_operands()->length(); ++j) { |
1311 InstructionOperand* to = move->move_operands()->at(j).destination(); | 1312 InstructionOperand* to = move->move_operands()->at(j).destination(); |
1312 if (to->IsUnallocated() && | 1313 if (to->IsUnallocated() && |
1313 UnallocatedOperand::cast(to)->virtual_register() == phi->id()) { | 1314 UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) { |
1314 hint = move->move_operands()->at(j).source(); | 1315 hint = move->move_operands()->at(j).source(); |
1315 phi_operand = to; | 1316 phi_operand = to; |
1316 break; | 1317 break; |
1317 } | 1318 } |
1318 } | 1319 } |
1319 DCHECK(hint != NULL); | 1320 DCHECK(hint != NULL); |
1320 | 1321 |
1321 LifetimePosition block_start = LifetimePosition::FromInstructionIndex( | 1322 LifetimePosition block_start = LifetimePosition::FromInstructionIndex( |
1322 block->first_instruction_index()); | 1323 block->first_instruction_index()); |
1323 Define(block_start, phi_operand, hint); | 1324 Define(block_start, phi_operand, hint); |
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2220 allocator_zone_start_allocation_size_; | 2221 allocator_zone_start_allocation_size_; |
2221 isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size); | 2222 isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size); |
2222 } | 2223 } |
2223 #ifdef DEBUG | 2224 #ifdef DEBUG |
2224 if (allocator_ != NULL) allocator_->Verify(); | 2225 if (allocator_ != NULL) allocator_->Verify(); |
2225 #endif | 2226 #endif |
2226 } | 2227 } |
2227 } | 2228 } |
2228 } | 2229 } |
2229 } // namespace v8::internal::compiler | 2230 } // namespace v8::internal::compiler |
OLD | NEW |