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