OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/lithium-allocator.h" | 5 #include "src/lithium-allocator.h" |
6 | 6 |
7 #include "src/hydrogen.h" | 7 #include "src/hydrogen.h" |
8 #include "src/lithium-inl.h" | 8 #include "src/lithium-inl.h" |
9 #include "src/lithium-allocator-inl.h" | 9 #include "src/lithium-allocator-inl.h" |
| 10 #include "src/register-configuration.h" |
10 #include "src/string-stream.h" | 11 #include "src/string-stream.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 | 15 |
15 static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) { | 16 static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) { |
16 return a.Value() < b.Value() ? a : b; | 17 return a.Value() < b.Value() ? a : b; |
17 } | 18 } |
18 | 19 |
19 | 20 |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 while (!iterator.Done()) { | 579 while (!iterator.Done()) { |
579 int operand_index = iterator.Current(); | 580 int operand_index = iterator.Current(); |
580 LiveRange* range = LiveRangeFor(operand_index); | 581 LiveRange* range = LiveRangeFor(operand_index); |
581 range->AddUseInterval(start, end, zone()); | 582 range->AddUseInterval(start, end, zone()); |
582 iterator.Advance(); | 583 iterator.Advance(); |
583 } | 584 } |
584 } | 585 } |
585 | 586 |
586 | 587 |
587 int LAllocator::FixedDoubleLiveRangeID(int index) { | 588 int LAllocator::FixedDoubleLiveRangeID(int index) { |
588 return -index - 1 - Register::kMaxNumAllocatableRegisters; | 589 return -index - 1 - Register::kNumRegisters; |
589 } | 590 } |
590 | 591 |
591 | 592 |
592 LOperand* LAllocator::AllocateFixed(LUnallocated* operand, | 593 LOperand* LAllocator::AllocateFixed(LUnallocated* operand, |
593 int pos, | 594 int pos, |
594 bool is_tagged) { | 595 bool is_tagged) { |
595 TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); | 596 TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); |
596 DCHECK(operand->HasFixedPolicy()); | 597 DCHECK(operand->HasFixedPolicy()); |
597 if (operand->HasFixedSlotPolicy()) { | 598 if (operand->HasFixedSlotPolicy()) { |
598 operand->ConvertTo(LOperand::STACK_SLOT, operand->fixed_slot_index()); | 599 operand->ConvertTo(LOperand::STACK_SLOT, operand->fixed_slot_index()); |
(...skipping 11 matching lines...) Expand all Loading... |
610 LInstruction* instr = InstructionAt(pos); | 611 LInstruction* instr = InstructionAt(pos); |
611 if (instr->HasPointerMap()) { | 612 if (instr->HasPointerMap()) { |
612 instr->pointer_map()->RecordPointer(operand, chunk()->zone()); | 613 instr->pointer_map()->RecordPointer(operand, chunk()->zone()); |
613 } | 614 } |
614 } | 615 } |
615 return operand; | 616 return operand; |
616 } | 617 } |
617 | 618 |
618 | 619 |
619 LiveRange* LAllocator::FixedLiveRangeFor(int index) { | 620 LiveRange* LAllocator::FixedLiveRangeFor(int index) { |
620 DCHECK(index < Register::kMaxNumAllocatableRegisters); | 621 DCHECK(index < Register::kNumRegisters); |
621 LiveRange* result = fixed_live_ranges_[index]; | 622 LiveRange* result = fixed_live_ranges_[index]; |
622 if (result == NULL) { | 623 if (result == NULL) { |
623 result = new(zone()) LiveRange(FixedLiveRangeID(index), chunk()->zone()); | 624 result = new(zone()) LiveRange(FixedLiveRangeID(index), chunk()->zone()); |
624 DCHECK(result->IsFixed()); | 625 DCHECK(result->IsFixed()); |
625 result->kind_ = GENERAL_REGISTERS; | 626 result->kind_ = GENERAL_REGISTERS; |
626 SetLiveRangeAssignedRegister(result, index); | 627 SetLiveRangeAssignedRegister(result, index); |
627 fixed_live_ranges_[index] = result; | 628 fixed_live_ranges_[index] = result; |
628 } | 629 } |
629 return result; | 630 return result; |
630 } | 631 } |
631 | 632 |
632 | 633 |
633 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { | 634 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { |
634 DCHECK(index < DoubleRegister::NumAllocatableRegisters()); | 635 DCHECK(index < DoubleRegister::kMaxNumRegisters); |
635 LiveRange* result = fixed_double_live_ranges_[index]; | 636 LiveRange* result = fixed_double_live_ranges_[index]; |
636 if (result == NULL) { | 637 if (result == NULL) { |
637 result = new(zone()) LiveRange(FixedDoubleLiveRangeID(index), | 638 result = new(zone()) LiveRange(FixedDoubleLiveRangeID(index), |
638 chunk()->zone()); | 639 chunk()->zone()); |
639 DCHECK(result->IsFixed()); | 640 DCHECK(result->IsFixed()); |
640 result->kind_ = DOUBLE_REGISTERS; | 641 result->kind_ = DOUBLE_REGISTERS; |
641 SetLiveRangeAssignedRegister(result, index); | 642 SetLiveRangeAssignedRegister(result, index); |
642 fixed_double_live_ranges_[index] = result; | 643 fixed_double_live_ranges_[index] = result; |
643 } | 644 } |
644 return result; | 645 return result; |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 if (instr != NULL) { | 933 if (instr != NULL) { |
933 LOperand* output = instr->Output(); | 934 LOperand* output = instr->Output(); |
934 if (output != NULL) { | 935 if (output != NULL) { |
935 if (output->IsUnallocated()) { | 936 if (output->IsUnallocated()) { |
936 live->Remove(LUnallocated::cast(output)->virtual_register()); | 937 live->Remove(LUnallocated::cast(output)->virtual_register()); |
937 } | 938 } |
938 Define(curr_position, output, NULL); | 939 Define(curr_position, output, NULL); |
939 } | 940 } |
940 | 941 |
941 if (instr->ClobbersRegisters()) { | 942 if (instr->ClobbersRegisters()) { |
942 for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) { | 943 for (int i = 0; i < Register::kNumRegisters; ++i) { |
943 if (output == NULL || !output->IsRegister() || | 944 if (Register::from_code(i).IsAllocatable()) { |
944 output->index() != i) { | 945 if (output == NULL || !output->IsRegister() || |
945 LiveRange* range = FixedLiveRangeFor(i); | 946 output->index() != i) { |
946 range->AddUseInterval(curr_position, | 947 LiveRange* range = FixedLiveRangeFor(i); |
947 curr_position.InstructionEnd(), | 948 range->AddUseInterval(curr_position, |
948 zone()); | 949 curr_position.InstructionEnd(), zone()); |
| 950 } |
949 } | 951 } |
950 } | 952 } |
951 } | 953 } |
952 | 954 |
953 if (instr->ClobbersDoubleRegisters(isolate())) { | 955 if (instr->ClobbersDoubleRegisters(isolate())) { |
954 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) { | 956 for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) { |
955 if (output == NULL || !output->IsDoubleRegister() || | 957 if (DoubleRegister::from_code(i).IsAllocatable()) { |
956 output->index() != i) { | 958 if (output == NULL || !output->IsDoubleRegister() || |
957 LiveRange* range = FixedDoubleLiveRangeFor(i); | 959 output->index() != i) { |
958 range->AddUseInterval(curr_position, | 960 LiveRange* range = FixedDoubleLiveRangeFor(i); |
959 curr_position.InstructionEnd(), | 961 range->AddUseInterval(curr_position, |
960 zone()); | 962 curr_position.InstructionEnd(), zone()); |
| 963 } |
961 } | 964 } |
962 } | 965 } |
963 } | 966 } |
964 | 967 |
965 for (UseIterator it(instr); !it.Done(); it.Advance()) { | 968 for (UseIterator it(instr); !it.Done(); it.Advance()) { |
966 LOperand* input = it.Current(); | 969 LOperand* input = it.Current(); |
967 | 970 |
968 LifetimePosition use_pos; | 971 LifetimePosition use_pos; |
969 if (input->IsUnallocated() && | 972 if (input->IsUnallocated() && |
970 LUnallocated::cast(input)->IsUsedAtStart()) { | 973 LUnallocated::cast(input)->IsUsedAtStart()) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 AddMove(phi_operand, live_range->GetSpillOperand(), chunk()->zone()); | 1065 AddMove(phi_operand, live_range->GetSpillOperand(), chunk()->zone()); |
1063 live_range->SetSpillStartIndex(phi->block()->first_instruction_index()); | 1066 live_range->SetSpillStartIndex(phi->block()->first_instruction_index()); |
1064 } | 1067 } |
1065 } | 1068 } |
1066 | 1069 |
1067 | 1070 |
1068 bool LAllocator::Allocate(LChunk* chunk) { | 1071 bool LAllocator::Allocate(LChunk* chunk) { |
1069 DCHECK(chunk_ == NULL); | 1072 DCHECK(chunk_ == NULL); |
1070 chunk_ = static_cast<LPlatformChunk*>(chunk); | 1073 chunk_ = static_cast<LPlatformChunk*>(chunk); |
1071 assigned_registers_ = | 1074 assigned_registers_ = |
1072 new(chunk->zone()) BitVector(Register::NumAllocatableRegisters(), | 1075 new (chunk->zone()) BitVector(Register::kNumRegisters, chunk->zone()); |
1073 chunk->zone()); | 1076 assigned_double_registers_ = new (chunk->zone()) |
1074 assigned_double_registers_ = | 1077 BitVector(DoubleRegister::kMaxNumRegisters, chunk->zone()); |
1075 new(chunk->zone()) BitVector(DoubleRegister::NumAllocatableRegisters(), | |
1076 chunk->zone()); | |
1077 MeetRegisterConstraints(); | 1078 MeetRegisterConstraints(); |
1078 if (!AllocationOk()) return false; | 1079 if (!AllocationOk()) return false; |
1079 ResolvePhis(); | 1080 ResolvePhis(); |
1080 BuildLiveRanges(); | 1081 BuildLiveRanges(); |
1081 AllocateGeneralRegisters(); | 1082 AllocateGeneralRegisters(); |
1082 if (!AllocationOk()) return false; | 1083 if (!AllocationOk()) return false; |
1083 AllocateDoubleRegisters(); | 1084 AllocateDoubleRegisters(); |
1084 if (!AllocationOk()) return false; | 1085 if (!AllocationOk()) return false; |
1085 PopulatePointerMaps(); | 1086 PopulatePointerMaps(); |
1086 ConnectRanges(); | 1087 ConnectRanges(); |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1453 DCHECK(!operand->IsStackSlot()); | 1454 DCHECK(!operand->IsStackSlot()); |
1454 map->RecordPointer(operand, chunk()->zone()); | 1455 map->RecordPointer(operand, chunk()->zone()); |
1455 } | 1456 } |
1456 } | 1457 } |
1457 } | 1458 } |
1458 } | 1459 } |
1459 | 1460 |
1460 | 1461 |
1461 void LAllocator::AllocateGeneralRegisters() { | 1462 void LAllocator::AllocateGeneralRegisters() { |
1462 LAllocatorPhase phase("L_Allocate general registers", this); | 1463 LAllocatorPhase phase("L_Allocate general registers", this); |
1463 num_registers_ = Register::NumAllocatableRegisters(); | 1464 num_registers_ = |
| 1465 RegisterConfiguration::ArchDefault()->num_allocatable_general_registers(); |
| 1466 allocatable_register_codes_ = |
| 1467 RegisterConfiguration::ArchDefault()->allocatable_general_codes(); |
1464 mode_ = GENERAL_REGISTERS; | 1468 mode_ = GENERAL_REGISTERS; |
1465 AllocateRegisters(); | 1469 AllocateRegisters(); |
1466 } | 1470 } |
1467 | 1471 |
1468 | 1472 |
1469 void LAllocator::AllocateDoubleRegisters() { | 1473 void LAllocator::AllocateDoubleRegisters() { |
1470 LAllocatorPhase phase("L_Allocate double registers", this); | 1474 LAllocatorPhase phase("L_Allocate double registers", this); |
1471 num_registers_ = DoubleRegister::NumAllocatableRegisters(); | 1475 num_registers_ = |
| 1476 RegisterConfiguration::ArchDefault()->num_allocatable_double_registers(); |
| 1477 allocatable_register_codes_ = |
| 1478 RegisterConfiguration::ArchDefault()->allocatable_double_codes(); |
1472 mode_ = DOUBLE_REGISTERS; | 1479 mode_ = DOUBLE_REGISTERS; |
1473 AllocateRegisters(); | 1480 AllocateRegisters(); |
1474 } | 1481 } |
1475 | 1482 |
1476 | 1483 |
1477 void LAllocator::AllocateRegisters() { | 1484 void LAllocator::AllocateRegisters() { |
1478 DCHECK(unhandled_live_ranges_.is_empty()); | 1485 DCHECK(unhandled_live_ranges_.is_empty()); |
1479 | 1486 |
1480 for (int i = 0; i < live_ranges_.length(); ++i) { | 1487 for (int i = 0; i < live_ranges_.length(); ++i) { |
1481 if (live_ranges_[i] != NULL) { | 1488 if (live_ranges_[i] != NULL) { |
1482 if (live_ranges_[i]->Kind() == mode_) { | 1489 if (live_ranges_[i]->Kind() == mode_) { |
1483 AddToUnhandledUnsorted(live_ranges_[i]); | 1490 AddToUnhandledUnsorted(live_ranges_[i]); |
1484 } | 1491 } |
1485 } | 1492 } |
1486 } | 1493 } |
1487 SortUnhandled(); | 1494 SortUnhandled(); |
1488 DCHECK(UnhandledIsSorted()); | 1495 DCHECK(UnhandledIsSorted()); |
1489 | 1496 |
1490 DCHECK(reusable_slots_.is_empty()); | 1497 DCHECK(reusable_slots_.is_empty()); |
1491 DCHECK(active_live_ranges_.is_empty()); | 1498 DCHECK(active_live_ranges_.is_empty()); |
1492 DCHECK(inactive_live_ranges_.is_empty()); | 1499 DCHECK(inactive_live_ranges_.is_empty()); |
1493 | 1500 |
1494 if (mode_ == DOUBLE_REGISTERS) { | 1501 if (mode_ == DOUBLE_REGISTERS) { |
1495 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) { | 1502 for (int i = 0; i < fixed_double_live_ranges_.length(); ++i) { |
1496 LiveRange* current = fixed_double_live_ranges_.at(i); | 1503 LiveRange* current = fixed_double_live_ranges_.at(i); |
1497 if (current != NULL) { | 1504 if (current != NULL) { |
1498 AddToInactive(current); | 1505 AddToInactive(current); |
1499 } | 1506 } |
1500 } | 1507 } |
1501 } else { | 1508 } else { |
1502 DCHECK(mode_ == GENERAL_REGISTERS); | 1509 DCHECK(mode_ == GENERAL_REGISTERS); |
1503 for (int i = 0; i < fixed_live_ranges_.length(); ++i) { | 1510 for (int i = 0; i < fixed_live_ranges_.length(); ++i) { |
1504 LiveRange* current = fixed_live_ranges_.at(i); | 1511 LiveRange* current = fixed_live_ranges_.at(i); |
1505 if (current != NULL) { | 1512 if (current != NULL) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1579 } | 1586 } |
1580 | 1587 |
1581 reusable_slots_.Rewind(0); | 1588 reusable_slots_.Rewind(0); |
1582 active_live_ranges_.Rewind(0); | 1589 active_live_ranges_.Rewind(0); |
1583 inactive_live_ranges_.Rewind(0); | 1590 inactive_live_ranges_.Rewind(0); |
1584 } | 1591 } |
1585 | 1592 |
1586 | 1593 |
1587 const char* LAllocator::RegisterName(int allocation_index) { | 1594 const char* LAllocator::RegisterName(int allocation_index) { |
1588 if (mode_ == GENERAL_REGISTERS) { | 1595 if (mode_ == GENERAL_REGISTERS) { |
1589 return Register::AllocationIndexToString(allocation_index); | 1596 return Register::from_code(allocation_index).ToString(); |
1590 } else { | 1597 } else { |
1591 return DoubleRegister::AllocationIndexToString(allocation_index); | 1598 return DoubleRegister::from_code(allocation_index).ToString(); |
1592 } | 1599 } |
1593 } | 1600 } |
1594 | 1601 |
1595 | 1602 |
1596 void LAllocator::TraceAlloc(const char* msg, ...) { | 1603 void LAllocator::TraceAlloc(const char* msg, ...) { |
1597 if (FLAG_trace_alloc) { | 1604 if (FLAG_trace_alloc) { |
1598 va_list arguments; | 1605 va_list arguments; |
1599 va_start(arguments, msg); | 1606 va_start(arguments, msg); |
1600 base::OS::VPrint(msg, arguments); | 1607 base::OS::VPrint(msg, arguments); |
1601 va_end(arguments); | 1608 va_end(arguments); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1743 | 1750 |
1744 | 1751 |
1745 void LAllocator::InactiveToActive(LiveRange* range) { | 1752 void LAllocator::InactiveToActive(LiveRange* range) { |
1746 DCHECK(inactive_live_ranges_.Contains(range)); | 1753 DCHECK(inactive_live_ranges_.Contains(range)); |
1747 inactive_live_ranges_.RemoveElement(range); | 1754 inactive_live_ranges_.RemoveElement(range); |
1748 active_live_ranges_.Add(range, zone()); | 1755 active_live_ranges_.Add(range, zone()); |
1749 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); | 1756 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); |
1750 } | 1757 } |
1751 | 1758 |
1752 | 1759 |
1753 // TryAllocateFreeReg and AllocateBlockedReg assume this | 1760 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { |
1754 // when allocating local arrays. | 1761 DCHECK(DoubleRegister::kMaxNumRegisters >= Register::kNumRegisters); |
1755 STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >= | |
1756 Register::kMaxNumAllocatableRegisters); | |
1757 | 1762 |
| 1763 LifetimePosition free_until_pos[DoubleRegister::kMaxNumRegisters]; |
1758 | 1764 |
1759 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { | 1765 for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) { |
1760 LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters]; | |
1761 | |
1762 for (int i = 0; i < num_registers_; i++) { | |
1763 free_until_pos[i] = LifetimePosition::MaxPosition(); | 1766 free_until_pos[i] = LifetimePosition::MaxPosition(); |
1764 } | 1767 } |
1765 | 1768 |
1766 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1769 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
1767 LiveRange* cur_active = active_live_ranges_.at(i); | 1770 LiveRange* cur_active = active_live_ranges_.at(i); |
1768 free_until_pos[cur_active->assigned_register()] = | 1771 free_until_pos[cur_active->assigned_register()] = |
1769 LifetimePosition::FromInstructionIndex(0); | 1772 LifetimePosition::FromInstructionIndex(0); |
1770 } | 1773 } |
1771 | 1774 |
1772 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { | 1775 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { |
(...skipping 20 matching lines...) Expand all Loading... |
1793 if (free_until_pos[register_index].Value() >= current->End().Value()) { | 1796 if (free_until_pos[register_index].Value() >= current->End().Value()) { |
1794 TraceAlloc("Assigning preferred reg %s to live range %d\n", | 1797 TraceAlloc("Assigning preferred reg %s to live range %d\n", |
1795 RegisterName(register_index), | 1798 RegisterName(register_index), |
1796 current->id()); | 1799 current->id()); |
1797 SetLiveRangeAssignedRegister(current, register_index); | 1800 SetLiveRangeAssignedRegister(current, register_index); |
1798 return true; | 1801 return true; |
1799 } | 1802 } |
1800 } | 1803 } |
1801 | 1804 |
1802 // Find the register which stays free for the longest time. | 1805 // Find the register which stays free for the longest time. |
1803 int reg = 0; | 1806 int reg = allocatable_register_codes_[0]; |
1804 for (int i = 1; i < RegisterCount(); ++i) { | 1807 for (int i = 1; i < RegisterCount(); ++i) { |
1805 if (free_until_pos[i].Value() > free_until_pos[reg].Value()) { | 1808 int code = allocatable_register_codes_[i]; |
1806 reg = i; | 1809 if (free_until_pos[code].Value() > free_until_pos[reg].Value()) { |
| 1810 reg = code; |
1807 } | 1811 } |
1808 } | 1812 } |
1809 | 1813 |
1810 LifetimePosition pos = free_until_pos[reg]; | 1814 LifetimePosition pos = free_until_pos[reg]; |
1811 | 1815 |
1812 if (pos.Value() <= current->Start().Value()) { | 1816 if (pos.Value() <= current->Start().Value()) { |
1813 // All registers are blocked. | 1817 // All registers are blocked. |
1814 return false; | 1818 return false; |
1815 } | 1819 } |
1816 | 1820 |
(...skipping 21 matching lines...) Expand all Loading... |
1838 void LAllocator::AllocateBlockedReg(LiveRange* current) { | 1842 void LAllocator::AllocateBlockedReg(LiveRange* current) { |
1839 UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 1843 UsePosition* register_use = current->NextRegisterPosition(current->Start()); |
1840 if (register_use == NULL) { | 1844 if (register_use == NULL) { |
1841 // There is no use in the current live range that requires a register. | 1845 // There is no use in the current live range that requires a register. |
1842 // We can just spill it. | 1846 // We can just spill it. |
1843 Spill(current); | 1847 Spill(current); |
1844 return; | 1848 return; |
1845 } | 1849 } |
1846 | 1850 |
1847 | 1851 |
1848 LifetimePosition use_pos[DoubleRegister::kMaxNumAllocatableRegisters]; | 1852 LifetimePosition use_pos[DoubleRegister::kMaxNumRegisters]; |
1849 LifetimePosition block_pos[DoubleRegister::kMaxNumAllocatableRegisters]; | 1853 LifetimePosition block_pos[DoubleRegister::kMaxNumRegisters]; |
1850 | 1854 |
1851 for (int i = 0; i < num_registers_; i++) { | 1855 for (int i = 0; i < DoubleRegister::kMaxNumRegisters; i++) { |
1852 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 1856 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); |
1853 } | 1857 } |
1854 | 1858 |
1855 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1859 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
1856 LiveRange* range = active_live_ranges_[i]; | 1860 LiveRange* range = active_live_ranges_[i]; |
1857 int cur_reg = range->assigned_register(); | 1861 int cur_reg = range->assigned_register(); |
1858 if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { | 1862 if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { |
1859 block_pos[cur_reg] = use_pos[cur_reg] = | 1863 block_pos[cur_reg] = use_pos[cur_reg] = |
1860 LifetimePosition::FromInstructionIndex(0); | 1864 LifetimePosition::FromInstructionIndex(0); |
1861 } else { | 1865 } else { |
(...skipping 14 matching lines...) Expand all Loading... |
1876 if (!next_intersection.IsValid()) continue; | 1880 if (!next_intersection.IsValid()) continue; |
1877 int cur_reg = range->assigned_register(); | 1881 int cur_reg = range->assigned_register(); |
1878 if (range->IsFixed()) { | 1882 if (range->IsFixed()) { |
1879 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); | 1883 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); |
1880 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); | 1884 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); |
1881 } else { | 1885 } else { |
1882 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); | 1886 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); |
1883 } | 1887 } |
1884 } | 1888 } |
1885 | 1889 |
1886 int reg = 0; | 1890 int reg = allocatable_register_codes_[0]; |
1887 for (int i = 1; i < RegisterCount(); ++i) { | 1891 for (int i = 1; i < RegisterCount(); ++i) { |
1888 if (use_pos[i].Value() > use_pos[reg].Value()) { | 1892 int code = allocatable_register_codes_[i]; |
1889 reg = i; | 1893 if (use_pos[code].Value() > use_pos[reg].Value()) { |
| 1894 reg = code; |
1890 } | 1895 } |
1891 } | 1896 } |
1892 | 1897 |
1893 LifetimePosition pos = use_pos[reg]; | 1898 LifetimePosition pos = use_pos[reg]; |
1894 | 1899 |
1895 if (pos.Value() < register_use->pos().Value()) { | 1900 if (pos.Value() < register_use->pos().Value()) { |
1896 // All registers are blocked before the first use that requires a register. | 1901 // All registers are blocked before the first use that requires a register. |
1897 // Spill starting part of live range up to that use. | 1902 // Spill starting part of live range up to that use. |
1898 SpillBetween(current, current->Start(), register_use->pos()); | 1903 SpillBetween(current, current->Start(), register_use->pos()); |
1899 return; | 1904 return; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2180 } | 2185 } |
2181 | 2186 |
2182 #ifdef DEBUG | 2187 #ifdef DEBUG |
2183 if (allocator_ != NULL) allocator_->Verify(); | 2188 if (allocator_ != NULL) allocator_->Verify(); |
2184 #endif | 2189 #endif |
2185 } | 2190 } |
2186 | 2191 |
2187 | 2192 |
2188 } // namespace internal | 2193 } // namespace internal |
2189 } // namespace v8 | 2194 } // namespace v8 |
OLD | NEW |