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/linkage.h" | 5 #include "src/compiler/linkage.h" |
6 #include "src/compiler/pipeline-statistics.h" | |
7 #include "src/compiler/register-allocator.h" | 6 #include "src/compiler/register-allocator.h" |
8 #include "src/string-stream.h" | 7 #include "src/string-stream.h" |
9 | 8 |
10 namespace v8 { | 9 namespace v8 { |
11 namespace internal { | 10 namespace internal { |
12 namespace compiler { | 11 namespace compiler { |
13 | 12 |
14 static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) { | 13 static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) { |
15 return a.Value() < b.Value() ? a : b; | 14 return a.Value() < b.Value() ? a : b; |
16 } | 15 } |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 num_registers_(-1), | 528 num_registers_(-1), |
530 allocation_ok_(true) { | 529 allocation_ok_(true) { |
531 DCHECK(this->config()->num_general_registers() <= | 530 DCHECK(this->config()->num_general_registers() <= |
532 RegisterConfiguration::kMaxGeneralRegisters); | 531 RegisterConfiguration::kMaxGeneralRegisters); |
533 DCHECK(this->config()->num_double_registers() <= | 532 DCHECK(this->config()->num_double_registers() <= |
534 RegisterConfiguration::kMaxDoubleRegisters); | 533 RegisterConfiguration::kMaxDoubleRegisters); |
535 // TryAllocateFreeReg and AllocateBlockedReg assume this | 534 // TryAllocateFreeReg and AllocateBlockedReg assume this |
536 // when allocating local arrays. | 535 // when allocating local arrays. |
537 DCHECK(this->config()->num_double_registers() >= | 536 DCHECK(this->config()->num_double_registers() >= |
538 this->config()->num_general_registers()); | 537 this->config()->num_general_registers()); |
| 538 assigned_registers_ = |
| 539 new (code_zone()) BitVector(config->num_general_registers(), code_zone()); |
| 540 assigned_double_registers_ = new (code_zone()) |
| 541 BitVector(config->num_aliased_double_registers(), code_zone()); |
| 542 frame->SetAllocatedRegisters(assigned_registers_); |
| 543 frame->SetAllocatedDoubleRegisters(assigned_double_registers_); |
539 } | 544 } |
540 | 545 |
541 | 546 |
542 void RegisterAllocator::InitializeLivenessAnalysis() { | 547 void RegisterAllocator::InitializeLivenessAnalysis() { |
543 // Initialize the live_in sets for each block to NULL. | 548 // Initialize the live_in sets for each block to NULL. |
544 int block_count = code()->InstructionBlockCount(); | 549 int block_count = code()->InstructionBlockCount(); |
545 live_in_sets_.Initialize(block_count, local_zone()); | 550 live_in_sets_.Initialize(block_count, local_zone()); |
546 live_in_sets_.AddBlock(NULL, block_count, local_zone()); | 551 live_in_sets_.AddBlock(NULL, block_count, local_zone()); |
547 } | 552 } |
548 | 553 |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1109 | 1114 |
1110 // We use the phi-ness of some nodes in some later heuristics. | 1115 // We use the phi-ness of some nodes in some later heuristics. |
1111 live_range->set_is_phi(true); | 1116 live_range->set_is_phi(true); |
1112 if (!block->IsLoopHeader()) { | 1117 if (!block->IsLoopHeader()) { |
1113 live_range->set_is_non_loop_phi(true); | 1118 live_range->set_is_non_loop_phi(true); |
1114 } | 1119 } |
1115 } | 1120 } |
1116 } | 1121 } |
1117 | 1122 |
1118 | 1123 |
1119 bool RegisterAllocator::Allocate(PipelineStatistics* stats) { | |
1120 assigned_registers_ = new (code_zone()) | |
1121 BitVector(config()->num_general_registers(), code_zone()); | |
1122 assigned_double_registers_ = new (code_zone()) | |
1123 BitVector(config()->num_aliased_double_registers(), code_zone()); | |
1124 { | |
1125 PhaseScope phase_scope(stats, "meet register constraints"); | |
1126 MeetRegisterConstraints(); | |
1127 } | |
1128 { | |
1129 PhaseScope phase_scope(stats, "resolve phis"); | |
1130 ResolvePhis(); | |
1131 } | |
1132 { | |
1133 PhaseScope phase_scope(stats, "build live ranges"); | |
1134 BuildLiveRanges(); | |
1135 } | |
1136 if (FLAG_trace_turbo) { | |
1137 OFStream os(stdout); | |
1138 PrintableInstructionSequence printable = {config(), code()}; | |
1139 os << "----- Instruction sequence before register allocation -----\n" | |
1140 << printable; | |
1141 } | |
1142 // This can be triggered in debug mode. | |
1143 DCHECK(!ExistsUseWithoutDefinition()); | |
1144 { | |
1145 PhaseScope phase_scope(stats, "allocate general registers"); | |
1146 AllocateGeneralRegisters(); | |
1147 } | |
1148 if (!AllocationOk()) return false; | |
1149 { | |
1150 PhaseScope phase_scope(stats, "allocate double registers"); | |
1151 AllocateDoubleRegisters(); | |
1152 } | |
1153 if (!AllocationOk()) return false; | |
1154 { | |
1155 PhaseScope phase_scope(stats, "populate pointer maps"); | |
1156 PopulatePointerMaps(); | |
1157 } | |
1158 { | |
1159 PhaseScope phase_scope(stats, "connect ranges"); | |
1160 ConnectRanges(); | |
1161 } | |
1162 { | |
1163 PhaseScope phase_scope(stats, "resolve control flow"); | |
1164 ResolveControlFlow(); | |
1165 } | |
1166 frame()->SetAllocatedRegisters(assigned_registers_); | |
1167 frame()->SetAllocatedDoubleRegisters(assigned_double_registers_); | |
1168 return true; | |
1169 } | |
1170 | |
1171 | |
1172 void RegisterAllocator::MeetRegisterConstraints() { | 1124 void RegisterAllocator::MeetRegisterConstraints() { |
1173 for (auto block : code()->instruction_blocks()) { | 1125 for (auto block : code()->instruction_blocks()) { |
1174 MeetRegisterConstraints(block); | 1126 MeetRegisterConstraints(block); |
1175 if (!AllocationOk()) return; | 1127 if (!AllocationOk()) return; |
1176 } | 1128 } |
1177 } | 1129 } |
1178 | 1130 |
1179 | 1131 |
1180 void RegisterAllocator::ResolvePhis() { | 1132 void RegisterAllocator::ResolvePhis() { |
1181 // Process the blocks in reverse order. | 1133 // Process the blocks in reverse order. |
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 } else { | 2276 } else { |
2325 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2277 DCHECK(range->Kind() == GENERAL_REGISTERS); |
2326 assigned_registers_->Add(reg); | 2278 assigned_registers_->Add(reg); |
2327 } | 2279 } |
2328 range->set_assigned_register(reg, code_zone()); | 2280 range->set_assigned_register(reg, code_zone()); |
2329 } | 2281 } |
2330 | 2282 |
2331 } | 2283 } |
2332 } | 2284 } |
2333 } // namespace v8::internal::compiler | 2285 } // namespace v8::internal::compiler |
OLD | NEW |