| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 while (!iterator.Done()) { | 599 while (!iterator.Done()) { |
| 600 int operand_index = iterator.Current(); | 600 int operand_index = iterator.Current(); |
| 601 LiveRange* range = LiveRangeFor(operand_index); | 601 LiveRange* range = LiveRangeFor(operand_index); |
| 602 range->AddUseInterval(start, end, zone_); | 602 range->AddUseInterval(start, end, zone_); |
| 603 iterator.Advance(); | 603 iterator.Advance(); |
| 604 } | 604 } |
| 605 } | 605 } |
| 606 | 606 |
| 607 | 607 |
| 608 int LAllocator::FixedDoubleLiveRangeID(int index) { | 608 int LAllocator::FixedDoubleLiveRangeID(int index) { |
| 609 return -index - 1 - Register::kMaxNumAllocatableRegisters; | 609 return -index - 1 - Register::kNumAllocatableRegisters; |
| 610 } | 610 } |
| 611 | 611 |
| 612 | 612 |
| 613 LOperand* LAllocator::AllocateFixed(LUnallocated* operand, | 613 LOperand* LAllocator::AllocateFixed(LUnallocated* operand, |
| 614 int pos, | 614 int pos, |
| 615 bool is_tagged) { | 615 bool is_tagged) { |
| 616 TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); | 616 TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); |
| 617 ASSERT(operand->HasFixedPolicy()); | 617 ASSERT(operand->HasFixedPolicy()); |
| 618 if (operand->policy() == LUnallocated::FIXED_SLOT) { | 618 if (operand->policy() == LUnallocated::FIXED_SLOT) { |
| 619 operand->ConvertTo(LOperand::STACK_SLOT, operand->fixed_index()); | 619 operand->ConvertTo(LOperand::STACK_SLOT, operand->fixed_index()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 631 LInstruction* instr = InstructionAt(pos); | 631 LInstruction* instr = InstructionAt(pos); |
| 632 if (instr->HasPointerMap()) { | 632 if (instr->HasPointerMap()) { |
| 633 instr->pointer_map()->RecordPointer(operand, zone()); | 633 instr->pointer_map()->RecordPointer(operand, zone()); |
| 634 } | 634 } |
| 635 } | 635 } |
| 636 return operand; | 636 return operand; |
| 637 } | 637 } |
| 638 | 638 |
| 639 | 639 |
| 640 LiveRange* LAllocator::FixedLiveRangeFor(int index) { | 640 LiveRange* LAllocator::FixedLiveRangeFor(int index) { |
| 641 ASSERT(index < Register::kMaxNumAllocatableRegisters); | 641 ASSERT(index < Register::kNumAllocatableRegisters); |
| 642 LiveRange* result = fixed_live_ranges_[index]; | 642 LiveRange* result = fixed_live_ranges_[index]; |
| 643 if (result == NULL) { | 643 if (result == NULL) { |
| 644 result = new(zone_) LiveRange(FixedLiveRangeID(index), zone_); | 644 result = new(zone_) LiveRange(FixedLiveRangeID(index), zone_); |
| 645 ASSERT(result->IsFixed()); | 645 ASSERT(result->IsFixed()); |
| 646 result->set_assigned_register(index, GENERAL_REGISTERS, zone_); | 646 result->set_assigned_register(index, GENERAL_REGISTERS, zone_); |
| 647 fixed_live_ranges_[index] = result; | 647 fixed_live_ranges_[index] = result; |
| 648 } | 648 } |
| 649 return result; | 649 return result; |
| 650 } | 650 } |
| 651 | 651 |
| 652 | 652 |
| 653 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { | 653 LiveRange* LAllocator::FixedDoubleLiveRangeFor(int index) { |
| 654 ASSERT(index < DoubleRegister::NumAllocatableRegisters()); | 654 ASSERT(index < DoubleRegister::kNumAllocatableRegisters); |
| 655 LiveRange* result = fixed_double_live_ranges_[index]; | 655 LiveRange* result = fixed_double_live_ranges_[index]; |
| 656 if (result == NULL) { | 656 if (result == NULL) { |
| 657 result = new(zone_) LiveRange(FixedDoubleLiveRangeID(index), zone_); | 657 result = new(zone_) LiveRange(FixedDoubleLiveRangeID(index), zone_); |
| 658 ASSERT(result->IsFixed()); | 658 ASSERT(result->IsFixed()); |
| 659 result->set_assigned_register(index, DOUBLE_REGISTERS, zone_); | 659 result->set_assigned_register(index, DOUBLE_REGISTERS, zone_); |
| 660 fixed_double_live_ranges_[index] = result; | 660 fixed_double_live_ranges_[index] = result; |
| 661 } | 661 } |
| 662 return result; | 662 return result; |
| 663 } | 663 } |
| 664 | 664 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 } | 761 } |
| 762 } | 762 } |
| 763 } | 763 } |
| 764 move->AddMove(from, to, zone()); | 764 move->AddMove(from, to, zone()); |
| 765 } | 765 } |
| 766 | 766 |
| 767 | 767 |
| 768 void LAllocator::MeetRegisterConstraints(HBasicBlock* block) { | 768 void LAllocator::MeetRegisterConstraints(HBasicBlock* block) { |
| 769 int start = block->first_instruction_index(); | 769 int start = block->first_instruction_index(); |
| 770 int end = block->last_instruction_index(); | 770 int end = block->last_instruction_index(); |
| 771 if (start == -1) return; | |
| 772 for (int i = start; i <= end; ++i) { | 771 for (int i = start; i <= end; ++i) { |
| 773 if (IsGapAt(i)) { | 772 if (IsGapAt(i)) { |
| 774 LInstruction* instr = NULL; | 773 LInstruction* instr = NULL; |
| 775 LInstruction* prev_instr = NULL; | 774 LInstruction* prev_instr = NULL; |
| 776 if (i < end) instr = InstructionAt(i + 1); | 775 if (i < end) instr = InstructionAt(i + 1); |
| 777 if (i > start) prev_instr = InstructionAt(i - 1); | 776 if (i > start) prev_instr = InstructionAt(i - 1); |
| 778 MeetConstraintsBetween(prev_instr, instr, i); | 777 MeetConstraintsBetween(prev_instr, instr, i); |
| 779 if (!AllocationOk()) return; | 778 if (!AllocationOk()) return; |
| 780 } | 779 } |
| 781 } | 780 } |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 | 939 |
| 941 if (instr != NULL) { | 940 if (instr != NULL) { |
| 942 LOperand* output = instr->Output(); | 941 LOperand* output = instr->Output(); |
| 943 if (output != NULL) { | 942 if (output != NULL) { |
| 944 if (output->IsUnallocated()) { | 943 if (output->IsUnallocated()) { |
| 945 live->Remove(LUnallocated::cast(output)->virtual_register()); | 944 live->Remove(LUnallocated::cast(output)->virtual_register()); |
| 946 } | 945 } |
| 947 Define(curr_position, output, NULL); | 946 Define(curr_position, output, NULL); |
| 948 } | 947 } |
| 949 | 948 |
| 950 if (instr->ClobbersRegisters()) { | 949 if (instr->IsMarkedAsCall()) { |
| 951 for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) { | 950 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { |
| 952 if (output == NULL || !output->IsRegister() || | 951 if (output == NULL || !output->IsRegister() || |
| 953 output->index() != i) { | 952 output->index() != i) { |
| 954 LiveRange* range = FixedLiveRangeFor(i); | 953 LiveRange* range = FixedLiveRangeFor(i); |
| 955 range->AddUseInterval(curr_position, | 954 range->AddUseInterval(curr_position, |
| 956 curr_position.InstructionEnd(), | 955 curr_position.InstructionEnd(), |
| 957 zone_); | 956 zone_); |
| 958 } | 957 } |
| 959 } | 958 } |
| 960 } | 959 } |
| 961 | 960 |
| 962 if (instr->ClobbersDoubleRegisters()) { | 961 if (instr->IsMarkedAsCall()) { |
| 963 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) { | 962 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { |
| 964 if (output == NULL || !output->IsDoubleRegister() || | 963 if (output == NULL || !output->IsDoubleRegister() || |
| 965 output->index() != i) { | 964 output->index() != i) { |
| 966 LiveRange* range = FixedDoubleLiveRangeFor(i); | 965 LiveRange* range = FixedDoubleLiveRangeFor(i); |
| 967 range->AddUseInterval(curr_position, | 966 range->AddUseInterval(curr_position, |
| 968 curr_position.InstructionEnd(), | 967 curr_position.InstructionEnd(), |
| 969 zone_); | 968 zone_); |
| 970 } | 969 } |
| 971 } | 970 } |
| 972 } | 971 } |
| 973 | 972 |
| 974 for (UseIterator it(instr); !it.Done(); it.Advance()) { | 973 for (UseIterator it(instr); !it.Done(); it.Advance()) { |
| 975 LOperand* input = it.Current(); | 974 LOperand* input = it.Current(); |
| 976 | 975 |
| 977 LifetimePosition use_pos; | 976 LifetimePosition use_pos; |
| 978 if (input->IsUnallocated() && | 977 if (input->IsUnallocated() && |
| 979 LUnallocated::cast(input)->IsUsedAtStart()) { | 978 LUnallocated::cast(input)->IsUsedAtStart()) { |
| 980 use_pos = curr_position; | 979 use_pos = curr_position; |
| 981 } else { | 980 } else { |
| 982 use_pos = curr_position.InstructionEnd(); | 981 use_pos = curr_position.InstructionEnd(); |
| 983 } | 982 } |
| 984 | 983 |
| 985 Use(block_start_position, use_pos, input, NULL); | 984 Use(block_start_position, use_pos, input, NULL); |
| 986 if (input->IsUnallocated()) { | 985 if (input->IsUnallocated()) { |
| 987 live->Add(LUnallocated::cast(input)->virtual_register()); | 986 live->Add(LUnallocated::cast(input)->virtual_register()); |
| 988 } | 987 } |
| 989 } | 988 } |
| 990 | 989 |
| 991 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 990 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
| 992 LOperand* temp = it.Current(); | 991 LOperand* temp = it.Current(); |
| 993 if (instr->ClobbersTemps()) { | 992 if (instr->IsMarkedAsCall()) { |
| 994 if (temp->IsRegister()) continue; | 993 if (temp->IsRegister()) continue; |
| 995 if (temp->IsUnallocated()) { | 994 if (temp->IsUnallocated()) { |
| 996 LUnallocated* temp_unalloc = LUnallocated::cast(temp); | 995 LUnallocated* temp_unalloc = LUnallocated::cast(temp); |
| 997 if (temp_unalloc->HasFixedPolicy()) { | 996 if (temp_unalloc->HasFixedPolicy()) { |
| 998 continue; | 997 continue; |
| 999 } | 998 } |
| 1000 } | 999 } |
| 1001 } | 1000 } |
| 1002 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); | 1001 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); |
| 1003 Define(curr_position, temp, NULL); | 1002 Define(curr_position, temp, NULL); |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 } | 1317 } |
| 1319 } | 1318 } |
| 1320 | 1319 |
| 1321 #ifdef DEBUG | 1320 #ifdef DEBUG |
| 1322 if (block_id == 0) { | 1321 if (block_id == 0) { |
| 1323 BitVector::Iterator iterator(live); | 1322 BitVector::Iterator iterator(live); |
| 1324 bool found = false; | 1323 bool found = false; |
| 1325 while (!iterator.Done()) { | 1324 while (!iterator.Done()) { |
| 1326 found = true; | 1325 found = true; |
| 1327 int operand_index = iterator.Current(); | 1326 int operand_index = iterator.Current(); |
| 1328 if (chunk_->info()->IsStub()) { | 1327 PrintF("Function: %s\n", |
| 1329 CodeStub::Major major_key = chunk_->info()->code_stub()->MajorKey(); | 1328 *chunk_->info()->function()->debug_name()->ToCString()); |
| 1330 PrintF("Function: %s\n", CodeStub::MajorName(major_key, false)); | |
| 1331 } else { | |
| 1332 ASSERT(chunk_->info()->IsOptimizing()); | |
| 1333 PrintF("Function: %s\n", | |
| 1334 *chunk_->info()->function()->debug_name()->ToCString()); | |
| 1335 } | |
| 1336 PrintF("Value %d used before first definition!\n", operand_index); | 1329 PrintF("Value %d used before first definition!\n", operand_index); |
| 1337 LiveRange* range = LiveRangeFor(operand_index); | 1330 LiveRange* range = LiveRangeFor(operand_index); |
| 1338 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); | 1331 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); |
| 1339 iterator.Advance(); | 1332 iterator.Advance(); |
| 1340 } | 1333 } |
| 1341 ASSERT(!found); | 1334 ASSERT(!found); |
| 1342 } | 1335 } |
| 1343 #endif | 1336 #endif |
| 1344 } | 1337 } |
| 1345 } | 1338 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1471 instruction->MarkSpilledRegister(reg_index, spill_operand); | 1464 instruction->MarkSpilledRegister(reg_index, spill_operand); |
| 1472 } | 1465 } |
| 1473 } | 1466 } |
| 1474 } | 1467 } |
| 1475 } | 1468 } |
| 1476 } | 1469 } |
| 1477 | 1470 |
| 1478 | 1471 |
| 1479 void LAllocator::AllocateGeneralRegisters() { | 1472 void LAllocator::AllocateGeneralRegisters() { |
| 1480 HPhase phase("L_Allocate general registers", this); | 1473 HPhase phase("L_Allocate general registers", this); |
| 1481 num_registers_ = Register::NumAllocatableRegisters(); | 1474 num_registers_ = Register::kNumAllocatableRegisters; |
| 1482 AllocateRegisters(); | 1475 AllocateRegisters(); |
| 1483 } | 1476 } |
| 1484 | 1477 |
| 1485 | 1478 |
| 1486 void LAllocator::AllocateDoubleRegisters() { | 1479 void LAllocator::AllocateDoubleRegisters() { |
| 1487 HPhase phase("L_Allocate double registers", this); | 1480 HPhase phase("L_Allocate double registers", this); |
| 1488 num_registers_ = DoubleRegister::NumAllocatableRegisters(); | 1481 num_registers_ = DoubleRegister::kNumAllocatableRegisters; |
| 1489 mode_ = DOUBLE_REGISTERS; | 1482 mode_ = DOUBLE_REGISTERS; |
| 1490 AllocateRegisters(); | 1483 AllocateRegisters(); |
| 1491 } | 1484 } |
| 1492 | 1485 |
| 1493 | 1486 |
| 1494 void LAllocator::AllocateRegisters() { | 1487 void LAllocator::AllocateRegisters() { |
| 1495 ASSERT(unhandled_live_ranges_.is_empty()); | 1488 ASSERT(unhandled_live_ranges_.is_empty()); |
| 1496 | 1489 |
| 1497 for (int i = 0; i < live_ranges_.length(); ++i) { | 1490 for (int i = 0; i < live_ranges_.length(); ++i) { |
| 1498 if (live_ranges_[i] != NULL) { | 1491 if (live_ranges_[i] != NULL) { |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 void LAllocator::InactiveToActive(LiveRange* range) { | 1750 void LAllocator::InactiveToActive(LiveRange* range) { |
| 1758 ASSERT(inactive_live_ranges_.Contains(range)); | 1751 ASSERT(inactive_live_ranges_.Contains(range)); |
| 1759 inactive_live_ranges_.RemoveElement(range); | 1752 inactive_live_ranges_.RemoveElement(range); |
| 1760 active_live_ranges_.Add(range, zone()); | 1753 active_live_ranges_.Add(range, zone()); |
| 1761 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); | 1754 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); |
| 1762 } | 1755 } |
| 1763 | 1756 |
| 1764 | 1757 |
| 1765 // TryAllocateFreeReg and AllocateBlockedReg assume this | 1758 // TryAllocateFreeReg and AllocateBlockedReg assume this |
| 1766 // when allocating local arrays. | 1759 // when allocating local arrays. |
| 1767 STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >= | 1760 STATIC_ASSERT(DoubleRegister::kNumAllocatableRegisters >= |
| 1768 Register::kMaxNumAllocatableRegisters); | 1761 Register::kNumAllocatableRegisters); |
| 1769 | 1762 |
| 1770 | 1763 |
| 1771 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { | 1764 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { |
| 1772 LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters]; | 1765 LifetimePosition free_until_pos[DoubleRegister::kNumAllocatableRegisters]; |
| 1773 | 1766 |
| 1774 for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; i++) { | 1767 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { |
| 1775 free_until_pos[i] = LifetimePosition::MaxPosition(); | 1768 free_until_pos[i] = LifetimePosition::MaxPosition(); |
| 1776 } | 1769 } |
| 1777 | 1770 |
| 1778 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1771 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
| 1779 LiveRange* cur_active = active_live_ranges_.at(i); | 1772 LiveRange* cur_active = active_live_ranges_.at(i); |
| 1780 free_until_pos[cur_active->assigned_register()] = | 1773 free_until_pos[cur_active->assigned_register()] = |
| 1781 LifetimePosition::FromInstructionIndex(0); | 1774 LifetimePosition::FromInstructionIndex(0); |
| 1782 } | 1775 } |
| 1783 | 1776 |
| 1784 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { | 1777 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 void LAllocator::AllocateBlockedReg(LiveRange* current) { | 1846 void LAllocator::AllocateBlockedReg(LiveRange* current) { |
| 1854 UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 1847 UsePosition* register_use = current->NextRegisterPosition(current->Start()); |
| 1855 if (register_use == NULL) { | 1848 if (register_use == NULL) { |
| 1856 // There is no use in the current live range that requires a register. | 1849 // There is no use in the current live range that requires a register. |
| 1857 // We can just spill it. | 1850 // We can just spill it. |
| 1858 Spill(current); | 1851 Spill(current); |
| 1859 return; | 1852 return; |
| 1860 } | 1853 } |
| 1861 | 1854 |
| 1862 | 1855 |
| 1863 LifetimePosition use_pos[DoubleRegister::kMaxNumAllocatableRegisters]; | 1856 LifetimePosition use_pos[DoubleRegister::kNumAllocatableRegisters]; |
| 1864 LifetimePosition block_pos[DoubleRegister::kMaxNumAllocatableRegisters]; | 1857 LifetimePosition block_pos[DoubleRegister::kNumAllocatableRegisters]; |
| 1865 | 1858 |
| 1866 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { | 1859 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { |
| 1867 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 1860 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); |
| 1868 } | 1861 } |
| 1869 | 1862 |
| 1870 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1863 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
| 1871 LiveRange* range = active_live_ranges_[i]; | 1864 LiveRange* range = active_live_ranges_[i]; |
| 1872 int cur_reg = range->assigned_register(); | 1865 int cur_reg = range->assigned_register(); |
| 1873 if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { | 1866 if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { |
| 1874 block_pos[cur_reg] = use_pos[cur_reg] = | 1867 block_pos[cur_reg] = use_pos[cur_reg] = |
| 1875 LifetimePosition::FromInstructionIndex(0); | 1868 LifetimePosition::FromInstructionIndex(0); |
| 1876 } else { | 1869 } else { |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2117 LiveRange* current = live_ranges()->at(i); | 2110 LiveRange* current = live_ranges()->at(i); |
| 2118 if (current != NULL) current->Verify(); | 2111 if (current != NULL) current->Verify(); |
| 2119 } | 2112 } |
| 2120 } | 2113 } |
| 2121 | 2114 |
| 2122 | 2115 |
| 2123 #endif | 2116 #endif |
| 2124 | 2117 |
| 2125 | 2118 |
| 2126 } } // namespace v8::internal | 2119 } } // namespace v8::internal |
| OLD | NEW |