| 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 |