| 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" | 6 #include "src/compiler/pipeline-statistics.h" |
| 7 #include "src/compiler/register-allocator.h" | 7 #include "src/compiler/register-allocator.h" |
| 8 #include "src/string-stream.h" | 8 #include "src/string-stream.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 1107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 | 1118 |
| 1119 bool RegisterAllocator::Allocate(PipelineStatistics* stats) { | 1119 bool RegisterAllocator::Allocate(PipelineStatistics* stats) { |
| 1120 assigned_registers_ = new (code_zone()) | 1120 assigned_registers_ = new (code_zone()) |
| 1121 BitVector(config()->num_general_registers(), code_zone()); | 1121 BitVector(config()->num_general_registers(), code_zone()); |
| 1122 assigned_double_registers_ = new (code_zone()) | 1122 assigned_double_registers_ = new (code_zone()) |
| 1123 BitVector(config()->num_aliased_double_registers(), code_zone()); | 1123 BitVector(config()->num_aliased_double_registers(), code_zone()); |
| 1124 { | 1124 { |
| 1125 PhaseScope phase_scope(stats, "meet register constraints"); | 1125 PhaseScope phase_scope(stats, "meet register constraints"); |
| 1126 MeetRegisterConstraints(); | 1126 MeetRegisterConstraints(); |
| 1127 } | 1127 } |
| 1128 if (!AllocationOk()) return false; | |
| 1129 { | 1128 { |
| 1130 PhaseScope phase_scope(stats, "resolve phis"); | 1129 PhaseScope phase_scope(stats, "resolve phis"); |
| 1131 ResolvePhis(); | 1130 ResolvePhis(); |
| 1132 } | 1131 } |
| 1133 { | 1132 { |
| 1134 PhaseScope phase_scope(stats, "build live ranges"); | 1133 PhaseScope phase_scope(stats, "build live ranges"); |
| 1135 BuildLiveRanges(); | 1134 BuildLiveRanges(); |
| 1136 } | 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()); |
| 1137 { | 1144 { |
| 1138 PhaseScope phase_scope(stats, "allocate general registers"); | 1145 PhaseScope phase_scope(stats, "allocate general registers"); |
| 1139 AllocateGeneralRegisters(); | 1146 AllocateGeneralRegisters(); |
| 1140 } | 1147 } |
| 1141 if (!AllocationOk()) return false; | 1148 if (!AllocationOk()) return false; |
| 1142 { | 1149 { |
| 1143 PhaseScope phase_scope(stats, "allocate double registers"); | 1150 PhaseScope phase_scope(stats, "allocate double registers"); |
| 1144 AllocateDoubleRegisters(); | 1151 AllocateDoubleRegisters(); |
| 1145 } | 1152 } |
| 1146 if (!AllocationOk()) return false; | 1153 if (!AllocationOk()) return false; |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1480 range->EnsureInterval(start, end, local_zone()); | 1487 range->EnsureInterval(start, end, local_zone()); |
| 1481 iterator.Advance(); | 1488 iterator.Advance(); |
| 1482 } | 1489 } |
| 1483 | 1490 |
| 1484 // Insert all values into the live in sets of all blocks in the loop. | 1491 // Insert all values into the live in sets of all blocks in the loop. |
| 1485 for (int i = block->rpo_number().ToInt() + 1; | 1492 for (int i = block->rpo_number().ToInt() + 1; |
| 1486 i < block->loop_end().ToInt(); ++i) { | 1493 i < block->loop_end().ToInt(); ++i) { |
| 1487 live_in_sets_[i]->Union(*live); | 1494 live_in_sets_[i]->Union(*live); |
| 1488 } | 1495 } |
| 1489 } | 1496 } |
| 1490 | |
| 1491 #ifdef DEBUG | |
| 1492 if (block_id == 0) { | |
| 1493 BitVector::Iterator iterator(live); | |
| 1494 bool found = false; | |
| 1495 while (!iterator.Done()) { | |
| 1496 found = true; | |
| 1497 int operand_index = iterator.Current(); | |
| 1498 PrintF("Register allocator error: live v%d reached first block.\n", | |
| 1499 operand_index); | |
| 1500 LiveRange* range = LiveRangeFor(operand_index); | |
| 1501 PrintF(" (first use is at %d)\n", range->first_pos()->pos().Value()); | |
| 1502 if (debug_name() == nullptr) { | |
| 1503 PrintF("\n"); | |
| 1504 } else { | |
| 1505 PrintF(" (function: %s)\n", debug_name()); | |
| 1506 } | |
| 1507 iterator.Advance(); | |
| 1508 } | |
| 1509 DCHECK(!found); | |
| 1510 } | |
| 1511 #endif | |
| 1512 } | 1497 } |
| 1513 | 1498 |
| 1514 for (int i = 0; i < live_ranges_.length(); ++i) { | 1499 for (int i = 0; i < live_ranges_.length(); ++i) { |
| 1515 if (live_ranges_[i] != NULL) { | 1500 if (live_ranges_[i] != NULL) { |
| 1516 live_ranges_[i]->kind_ = RequiredRegisterKind(live_ranges_[i]->id()); | 1501 live_ranges_[i]->kind_ = RequiredRegisterKind(live_ranges_[i]->id()); |
| 1517 | 1502 |
| 1518 // TODO(bmeurer): This is a horrible hack to make sure that for constant | 1503 // TODO(bmeurer): This is a horrible hack to make sure that for constant |
| 1519 // live ranges, every use requires the constant to be in a register. | 1504 // live ranges, every use requires the constant to be in a register. |
| 1520 // Without this hack, all uses with "any" policy would get the constant | 1505 // Without this hack, all uses with "any" policy would get the constant |
| 1521 // operand assigned. | 1506 // operand assigned. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1532 ->IsGapMoves()) { | 1517 ->IsGapMoves()) { |
| 1533 pos->requires_reg_ = true; | 1518 pos->requires_reg_ = true; |
| 1534 } | 1519 } |
| 1535 } | 1520 } |
| 1536 } | 1521 } |
| 1537 } | 1522 } |
| 1538 } | 1523 } |
| 1539 } | 1524 } |
| 1540 | 1525 |
| 1541 | 1526 |
| 1527 bool RegisterAllocator::ExistsUseWithoutDefinition() { |
| 1528 bool found = false; |
| 1529 BitVector::Iterator iterator(live_in_sets_[0]); |
| 1530 while (!iterator.Done()) { |
| 1531 found = true; |
| 1532 int operand_index = iterator.Current(); |
| 1533 PrintF("Register allocator error: live v%d reached first block.\n", |
| 1534 operand_index); |
| 1535 LiveRange* range = LiveRangeFor(operand_index); |
| 1536 PrintF(" (first use is at %d)\n", range->first_pos()->pos().Value()); |
| 1537 if (debug_name() == nullptr) { |
| 1538 PrintF("\n"); |
| 1539 } else { |
| 1540 PrintF(" (function: %s)\n", debug_name()); |
| 1541 } |
| 1542 iterator.Advance(); |
| 1543 } |
| 1544 return found; |
| 1545 } |
| 1546 |
| 1547 |
| 1542 bool RegisterAllocator::SafePointsAreInOrder() const { | 1548 bool RegisterAllocator::SafePointsAreInOrder() const { |
| 1543 int safe_point = 0; | 1549 int safe_point = 0; |
| 1544 const PointerMapDeque* pointer_maps = code()->pointer_maps(); | 1550 const PointerMapDeque* pointer_maps = code()->pointer_maps(); |
| 1545 for (PointerMapDeque::const_iterator it = pointer_maps->begin(); | 1551 for (PointerMapDeque::const_iterator it = pointer_maps->begin(); |
| 1546 it != pointer_maps->end(); ++it) { | 1552 it != pointer_maps->end(); ++it) { |
| 1547 PointerMap* map = *it; | 1553 PointerMap* map = *it; |
| 1548 if (safe_point > map->instruction_position()) return false; | 1554 if (safe_point > map->instruction_position()) return false; |
| 1549 safe_point = map->instruction_position(); | 1555 safe_point = map->instruction_position(); |
| 1550 } | 1556 } |
| 1551 return true; | 1557 return true; |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2318 } else { | 2324 } else { |
| 2319 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2325 DCHECK(range->Kind() == GENERAL_REGISTERS); |
| 2320 assigned_registers_->Add(reg); | 2326 assigned_registers_->Add(reg); |
| 2321 } | 2327 } |
| 2322 range->set_assigned_register(reg, code_zone()); | 2328 range->set_assigned_register(reg, code_zone()); |
| 2323 } | 2329 } |
| 2324 | 2330 |
| 2325 } | 2331 } |
| 2326 } | 2332 } |
| 2327 } // namespace v8::internal::compiler | 2333 } // namespace v8::internal::compiler |
| OLD | NEW |