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 |