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::kNumAllocatableRegisters; | 609 return -index - 1 - Register::kMaxNumAllocatableRegisters; |
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::kNumAllocatableRegisters); | 641 ASSERT(index < Register::kMaxNumAllocatableRegisters); |
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::kNumAllocatableRegisters); | 654 ASSERT(index < DoubleRegister::NumAllocatableRegisters()); |
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; |
771 for (int i = start; i <= end; ++i) { | 772 for (int i = start; i <= end; ++i) { |
772 if (IsGapAt(i)) { | 773 if (IsGapAt(i)) { |
773 LInstruction* instr = NULL; | 774 LInstruction* instr = NULL; |
774 LInstruction* prev_instr = NULL; | 775 LInstruction* prev_instr = NULL; |
775 if (i < end) instr = InstructionAt(i + 1); | 776 if (i < end) instr = InstructionAt(i + 1); |
776 if (i > start) prev_instr = InstructionAt(i - 1); | 777 if (i > start) prev_instr = InstructionAt(i - 1); |
777 MeetConstraintsBetween(prev_instr, instr, i); | 778 MeetConstraintsBetween(prev_instr, instr, i); |
778 if (!AllocationOk()) return; | 779 if (!AllocationOk()) return; |
779 } | 780 } |
780 } | 781 } |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
939 | 940 |
940 if (instr != NULL) { | 941 if (instr != NULL) { |
941 LOperand* output = instr->Output(); | 942 LOperand* output = instr->Output(); |
942 if (output != NULL) { | 943 if (output != NULL) { |
943 if (output->IsUnallocated()) { | 944 if (output->IsUnallocated()) { |
944 live->Remove(LUnallocated::cast(output)->virtual_register()); | 945 live->Remove(LUnallocated::cast(output)->virtual_register()); |
945 } | 946 } |
946 Define(curr_position, output, NULL); | 947 Define(curr_position, output, NULL); |
947 } | 948 } |
948 | 949 |
949 if (instr->IsMarkedAsCall()) { | 950 if (instr->ClobbersRegisters()) { |
950 for (int i = 0; i < Register::kNumAllocatableRegisters; ++i) { | 951 for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) { |
951 if (output == NULL || !output->IsRegister() || | 952 if (output == NULL || !output->IsRegister() || |
952 output->index() != i) { | 953 output->index() != i) { |
953 LiveRange* range = FixedLiveRangeFor(i); | 954 LiveRange* range = FixedLiveRangeFor(i); |
954 range->AddUseInterval(curr_position, | 955 range->AddUseInterval(curr_position, |
955 curr_position.InstructionEnd(), | 956 curr_position.InstructionEnd(), |
956 zone_); | 957 zone_); |
957 } | 958 } |
958 } | 959 } |
959 } | 960 } |
960 | 961 |
961 if (instr->IsMarkedAsCall()) { | 962 if (instr->ClobbersDoubleRegisters()) { |
962 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; ++i) { | 963 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) { |
963 if (output == NULL || !output->IsDoubleRegister() || | 964 if (output == NULL || !output->IsDoubleRegister() || |
964 output->index() != i) { | 965 output->index() != i) { |
965 LiveRange* range = FixedDoubleLiveRangeFor(i); | 966 LiveRange* range = FixedDoubleLiveRangeFor(i); |
966 range->AddUseInterval(curr_position, | 967 range->AddUseInterval(curr_position, |
967 curr_position.InstructionEnd(), | 968 curr_position.InstructionEnd(), |
968 zone_); | 969 zone_); |
969 } | 970 } |
970 } | 971 } |
971 } | 972 } |
972 | 973 |
973 for (UseIterator it(instr); !it.Done(); it.Advance()) { | 974 for (UseIterator it(instr); !it.Done(); it.Advance()) { |
974 LOperand* input = it.Current(); | 975 LOperand* input = it.Current(); |
975 | 976 |
976 LifetimePosition use_pos; | 977 LifetimePosition use_pos; |
977 if (input->IsUnallocated() && | 978 if (input->IsUnallocated() && |
978 LUnallocated::cast(input)->IsUsedAtStart()) { | 979 LUnallocated::cast(input)->IsUsedAtStart()) { |
979 use_pos = curr_position; | 980 use_pos = curr_position; |
980 } else { | 981 } else { |
981 use_pos = curr_position.InstructionEnd(); | 982 use_pos = curr_position.InstructionEnd(); |
982 } | 983 } |
983 | 984 |
984 Use(block_start_position, use_pos, input, NULL); | 985 Use(block_start_position, use_pos, input, NULL); |
985 if (input->IsUnallocated()) { | 986 if (input->IsUnallocated()) { |
986 live->Add(LUnallocated::cast(input)->virtual_register()); | 987 live->Add(LUnallocated::cast(input)->virtual_register()); |
987 } | 988 } |
988 } | 989 } |
989 | 990 |
990 for (TempIterator it(instr); !it.Done(); it.Advance()) { | 991 for (TempIterator it(instr); !it.Done(); it.Advance()) { |
991 LOperand* temp = it.Current(); | 992 LOperand* temp = it.Current(); |
992 if (instr->IsMarkedAsCall()) { | 993 if (instr->ClobbersTemps()) { |
993 if (temp->IsRegister()) continue; | 994 if (temp->IsRegister()) continue; |
994 if (temp->IsUnallocated()) { | 995 if (temp->IsUnallocated()) { |
995 LUnallocated* temp_unalloc = LUnallocated::cast(temp); | 996 LUnallocated* temp_unalloc = LUnallocated::cast(temp); |
996 if (temp_unalloc->HasFixedPolicy()) { | 997 if (temp_unalloc->HasFixedPolicy()) { |
997 continue; | 998 continue; |
998 } | 999 } |
999 } | 1000 } |
1000 } | 1001 } |
1001 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); | 1002 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); |
1002 Define(curr_position, temp, NULL); | 1003 Define(curr_position, temp, NULL); |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1317 } | 1318 } |
1318 } | 1319 } |
1319 | 1320 |
1320 #ifdef DEBUG | 1321 #ifdef DEBUG |
1321 if (block_id == 0) { | 1322 if (block_id == 0) { |
1322 BitVector::Iterator iterator(live); | 1323 BitVector::Iterator iterator(live); |
1323 bool found = false; | 1324 bool found = false; |
1324 while (!iterator.Done()) { | 1325 while (!iterator.Done()) { |
1325 found = true; | 1326 found = true; |
1326 int operand_index = iterator.Current(); | 1327 int operand_index = iterator.Current(); |
1327 PrintF("Function: %s\n", | 1328 if (chunk_->info()->IsStub()) { |
1328 *chunk_->info()->function()->debug_name()->ToCString()); | 1329 CodeStub::Major major_key = chunk_->info()->code_stub()->MajorKey(); |
| 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 } |
1329 PrintF("Value %d used before first definition!\n", operand_index); | 1336 PrintF("Value %d used before first definition!\n", operand_index); |
1330 LiveRange* range = LiveRangeFor(operand_index); | 1337 LiveRange* range = LiveRangeFor(operand_index); |
1331 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); | 1338 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); |
1332 iterator.Advance(); | 1339 iterator.Advance(); |
1333 } | 1340 } |
1334 ASSERT(!found); | 1341 ASSERT(!found); |
1335 } | 1342 } |
1336 #endif | 1343 #endif |
1337 } | 1344 } |
1338 } | 1345 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 instruction->MarkSpilledRegister(reg_index, spill_operand); | 1471 instruction->MarkSpilledRegister(reg_index, spill_operand); |
1465 } | 1472 } |
1466 } | 1473 } |
1467 } | 1474 } |
1468 } | 1475 } |
1469 } | 1476 } |
1470 | 1477 |
1471 | 1478 |
1472 void LAllocator::AllocateGeneralRegisters() { | 1479 void LAllocator::AllocateGeneralRegisters() { |
1473 HPhase phase("L_Allocate general registers", this); | 1480 HPhase phase("L_Allocate general registers", this); |
1474 num_registers_ = Register::kNumAllocatableRegisters; | 1481 num_registers_ = Register::NumAllocatableRegisters(); |
1475 AllocateRegisters(); | 1482 AllocateRegisters(); |
1476 } | 1483 } |
1477 | 1484 |
1478 | 1485 |
1479 void LAllocator::AllocateDoubleRegisters() { | 1486 void LAllocator::AllocateDoubleRegisters() { |
1480 HPhase phase("L_Allocate double registers", this); | 1487 HPhase phase("L_Allocate double registers", this); |
1481 num_registers_ = DoubleRegister::kNumAllocatableRegisters; | 1488 num_registers_ = DoubleRegister::NumAllocatableRegisters(); |
1482 mode_ = DOUBLE_REGISTERS; | 1489 mode_ = DOUBLE_REGISTERS; |
1483 AllocateRegisters(); | 1490 AllocateRegisters(); |
1484 } | 1491 } |
1485 | 1492 |
1486 | 1493 |
1487 void LAllocator::AllocateRegisters() { | 1494 void LAllocator::AllocateRegisters() { |
1488 ASSERT(unhandled_live_ranges_.is_empty()); | 1495 ASSERT(unhandled_live_ranges_.is_empty()); |
1489 | 1496 |
1490 for (int i = 0; i < live_ranges_.length(); ++i) { | 1497 for (int i = 0; i < live_ranges_.length(); ++i) { |
1491 if (live_ranges_[i] != NULL) { | 1498 if (live_ranges_[i] != NULL) { |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1750 void LAllocator::InactiveToActive(LiveRange* range) { | 1757 void LAllocator::InactiveToActive(LiveRange* range) { |
1751 ASSERT(inactive_live_ranges_.Contains(range)); | 1758 ASSERT(inactive_live_ranges_.Contains(range)); |
1752 inactive_live_ranges_.RemoveElement(range); | 1759 inactive_live_ranges_.RemoveElement(range); |
1753 active_live_ranges_.Add(range, zone()); | 1760 active_live_ranges_.Add(range, zone()); |
1754 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); | 1761 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); |
1755 } | 1762 } |
1756 | 1763 |
1757 | 1764 |
1758 // TryAllocateFreeReg and AllocateBlockedReg assume this | 1765 // TryAllocateFreeReg and AllocateBlockedReg assume this |
1759 // when allocating local arrays. | 1766 // when allocating local arrays. |
1760 STATIC_ASSERT(DoubleRegister::kNumAllocatableRegisters >= | 1767 STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >= |
1761 Register::kNumAllocatableRegisters); | 1768 Register::kMaxNumAllocatableRegisters); |
1762 | 1769 |
1763 | 1770 |
1764 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { | 1771 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { |
1765 LifetimePosition free_until_pos[DoubleRegister::kNumAllocatableRegisters]; | 1772 LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters]; |
1766 | 1773 |
1767 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { | 1774 for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; i++) { |
1768 free_until_pos[i] = LifetimePosition::MaxPosition(); | 1775 free_until_pos[i] = LifetimePosition::MaxPosition(); |
1769 } | 1776 } |
1770 | 1777 |
1771 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1778 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
1772 LiveRange* cur_active = active_live_ranges_.at(i); | 1779 LiveRange* cur_active = active_live_ranges_.at(i); |
1773 free_until_pos[cur_active->assigned_register()] = | 1780 free_until_pos[cur_active->assigned_register()] = |
1774 LifetimePosition::FromInstructionIndex(0); | 1781 LifetimePosition::FromInstructionIndex(0); |
1775 } | 1782 } |
1776 | 1783 |
1777 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { | 1784 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1846 void LAllocator::AllocateBlockedReg(LiveRange* current) { | 1853 void LAllocator::AllocateBlockedReg(LiveRange* current) { |
1847 UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 1854 UsePosition* register_use = current->NextRegisterPosition(current->Start()); |
1848 if (register_use == NULL) { | 1855 if (register_use == NULL) { |
1849 // There is no use in the current live range that requires a register. | 1856 // There is no use in the current live range that requires a register. |
1850 // We can just spill it. | 1857 // We can just spill it. |
1851 Spill(current); | 1858 Spill(current); |
1852 return; | 1859 return; |
1853 } | 1860 } |
1854 | 1861 |
1855 | 1862 |
1856 LifetimePosition use_pos[DoubleRegister::kNumAllocatableRegisters]; | 1863 LifetimePosition use_pos[DoubleRegister::kMaxNumAllocatableRegisters]; |
1857 LifetimePosition block_pos[DoubleRegister::kNumAllocatableRegisters]; | 1864 LifetimePosition block_pos[DoubleRegister::kMaxNumAllocatableRegisters]; |
1858 | 1865 |
1859 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { | 1866 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { |
1860 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 1867 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); |
1861 } | 1868 } |
1862 | 1869 |
1863 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1870 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
1864 LiveRange* range = active_live_ranges_[i]; | 1871 LiveRange* range = active_live_ranges_[i]; |
1865 int cur_reg = range->assigned_register(); | 1872 int cur_reg = range->assigned_register(); |
1866 if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { | 1873 if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { |
1867 block_pos[cur_reg] = use_pos[cur_reg] = | 1874 block_pos[cur_reg] = use_pos[cur_reg] = |
1868 LifetimePosition::FromInstructionIndex(0); | 1875 LifetimePosition::FromInstructionIndex(0); |
1869 } else { | 1876 } else { |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2110 LiveRange* current = live_ranges()->at(i); | 2117 LiveRange* current = live_ranges()->at(i); |
2111 if (current != NULL) current->Verify(); | 2118 if (current != NULL) current->Verify(); |
2112 } | 2119 } |
2113 } | 2120 } |
2114 | 2121 |
2115 | 2122 |
2116 #endif | 2123 #endif |
2117 | 2124 |
2118 | 2125 |
2119 } } // namespace v8::internal | 2126 } } // namespace v8::internal |
OLD | NEW |