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