Chromium Code Reviews| 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()->IsOptimizing()) { |
| 1328 *chunk_->info()->function()->debug_name()->ToCString()); | 1329 PrintF("Function: %s\n", |
| 1330 *chunk_->info()->function()->debug_name()->ToCString()); | |
| 1331 } | |
|
Jakob Kummerow
2012/11/28 16:28:22
Again, it might be mighty helpful to print *chunk_
danno
2012/11/30 16:23:24
Done.
| |
| 1329 PrintF("Value %d used before first definition!\n", operand_index); | 1332 PrintF("Value %d used before first definition!\n", operand_index); |
| 1330 LiveRange* range = LiveRangeFor(operand_index); | 1333 LiveRange* range = LiveRangeFor(operand_index); |
| 1331 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); | 1334 PrintF("First use is at %d\n", range->first_pos()->pos().Value()); |
| 1332 iterator.Advance(); | 1335 iterator.Advance(); |
| 1333 } | 1336 } |
| 1334 ASSERT(!found); | 1337 ASSERT(!found); |
| 1335 } | 1338 } |
| 1336 #endif | 1339 #endif |
| 1337 } | 1340 } |
| 1338 } | 1341 } |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1464 instruction->MarkSpilledRegister(reg_index, spill_operand); | 1467 instruction->MarkSpilledRegister(reg_index, spill_operand); |
| 1465 } | 1468 } |
| 1466 } | 1469 } |
| 1467 } | 1470 } |
| 1468 } | 1471 } |
| 1469 } | 1472 } |
| 1470 | 1473 |
| 1471 | 1474 |
| 1472 void LAllocator::AllocateGeneralRegisters() { | 1475 void LAllocator::AllocateGeneralRegisters() { |
| 1473 HPhase phase("L_Allocate general registers", this); | 1476 HPhase phase("L_Allocate general registers", this); |
| 1474 num_registers_ = Register::kNumAllocatableRegisters; | 1477 num_registers_ = Register::NumAllocatableRegisters(); |
| 1475 AllocateRegisters(); | 1478 AllocateRegisters(); |
| 1476 } | 1479 } |
| 1477 | 1480 |
| 1478 | 1481 |
| 1479 void LAllocator::AllocateDoubleRegisters() { | 1482 void LAllocator::AllocateDoubleRegisters() { |
| 1480 HPhase phase("L_Allocate double registers", this); | 1483 HPhase phase("L_Allocate double registers", this); |
| 1481 num_registers_ = DoubleRegister::kNumAllocatableRegisters; | 1484 num_registers_ = DoubleRegister::NumAllocatableRegisters(); |
| 1482 mode_ = DOUBLE_REGISTERS; | 1485 mode_ = DOUBLE_REGISTERS; |
| 1483 AllocateRegisters(); | 1486 AllocateRegisters(); |
| 1484 } | 1487 } |
| 1485 | 1488 |
| 1486 | 1489 |
| 1487 void LAllocator::AllocateRegisters() { | 1490 void LAllocator::AllocateRegisters() { |
| 1488 ASSERT(unhandled_live_ranges_.is_empty()); | 1491 ASSERT(unhandled_live_ranges_.is_empty()); |
| 1489 | 1492 |
| 1490 for (int i = 0; i < live_ranges_.length(); ++i) { | 1493 for (int i = 0; i < live_ranges_.length(); ++i) { |
| 1491 if (live_ranges_[i] != NULL) { | 1494 if (live_ranges_[i] != NULL) { |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1750 void LAllocator::InactiveToActive(LiveRange* range) { | 1753 void LAllocator::InactiveToActive(LiveRange* range) { |
| 1751 ASSERT(inactive_live_ranges_.Contains(range)); | 1754 ASSERT(inactive_live_ranges_.Contains(range)); |
| 1752 inactive_live_ranges_.RemoveElement(range); | 1755 inactive_live_ranges_.RemoveElement(range); |
| 1753 active_live_ranges_.Add(range, zone()); | 1756 active_live_ranges_.Add(range, zone()); |
| 1754 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); | 1757 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); |
| 1755 } | 1758 } |
| 1756 | 1759 |
| 1757 | 1760 |
| 1758 // TryAllocateFreeReg and AllocateBlockedReg assume this | 1761 // TryAllocateFreeReg and AllocateBlockedReg assume this |
| 1759 // when allocating local arrays. | 1762 // when allocating local arrays. |
| 1760 STATIC_ASSERT(DoubleRegister::kNumAllocatableRegisters >= | 1763 STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >= |
| 1761 Register::kNumAllocatableRegisters); | 1764 Register::kMaxNumAllocatableRegisters); |
| 1762 | 1765 |
| 1763 | 1766 |
| 1764 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { | 1767 bool LAllocator::TryAllocateFreeReg(LiveRange* current) { |
| 1765 LifetimePosition free_until_pos[DoubleRegister::kNumAllocatableRegisters]; | 1768 LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters]; |
| 1766 | 1769 |
| 1767 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { | 1770 for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; i++) { |
| 1768 free_until_pos[i] = LifetimePosition::MaxPosition(); | 1771 free_until_pos[i] = LifetimePosition::MaxPosition(); |
| 1769 } | 1772 } |
| 1770 | 1773 |
| 1771 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1774 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
| 1772 LiveRange* cur_active = active_live_ranges_.at(i); | 1775 LiveRange* cur_active = active_live_ranges_.at(i); |
| 1773 free_until_pos[cur_active->assigned_register()] = | 1776 free_until_pos[cur_active->assigned_register()] = |
| 1774 LifetimePosition::FromInstructionIndex(0); | 1777 LifetimePosition::FromInstructionIndex(0); |
| 1775 } | 1778 } |
| 1776 | 1779 |
| 1777 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { | 1780 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) { | 1849 void LAllocator::AllocateBlockedReg(LiveRange* current) { |
| 1847 UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 1850 UsePosition* register_use = current->NextRegisterPosition(current->Start()); |
| 1848 if (register_use == NULL) { | 1851 if (register_use == NULL) { |
| 1849 // There is no use in the current live range that requires a register. | 1852 // There is no use in the current live range that requires a register. |
| 1850 // We can just spill it. | 1853 // We can just spill it. |
| 1851 Spill(current); | 1854 Spill(current); |
| 1852 return; | 1855 return; |
| 1853 } | 1856 } |
| 1854 | 1857 |
| 1855 | 1858 |
| 1856 LifetimePosition use_pos[DoubleRegister::kNumAllocatableRegisters]; | 1859 LifetimePosition use_pos[DoubleRegister::kMaxNumAllocatableRegisters]; |
| 1857 LifetimePosition block_pos[DoubleRegister::kNumAllocatableRegisters]; | 1860 LifetimePosition block_pos[DoubleRegister::kMaxNumAllocatableRegisters]; |
| 1858 | 1861 |
| 1859 for (int i = 0; i < DoubleRegister::kNumAllocatableRegisters; i++) { | 1862 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { |
| 1860 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 1863 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); |
| 1861 } | 1864 } |
| 1862 | 1865 |
| 1863 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1866 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
| 1864 LiveRange* range = active_live_ranges_[i]; | 1867 LiveRange* range = active_live_ranges_[i]; |
| 1865 int cur_reg = range->assigned_register(); | 1868 int cur_reg = range->assigned_register(); |
| 1866 if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { | 1869 if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { |
| 1867 block_pos[cur_reg] = use_pos[cur_reg] = | 1870 block_pos[cur_reg] = use_pos[cur_reg] = |
| 1868 LifetimePosition::FromInstructionIndex(0); | 1871 LifetimePosition::FromInstructionIndex(0); |
| 1869 } else { | 1872 } else { |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2110 LiveRange* current = live_ranges()->at(i); | 2113 LiveRange* current = live_ranges()->at(i); |
| 2111 if (current != NULL) current->Verify(); | 2114 if (current != NULL) current->Verify(); |
| 2112 } | 2115 } |
| 2113 } | 2116 } |
| 2114 | 2117 |
| 2115 | 2118 |
| 2116 #endif | 2119 #endif |
| 2117 | 2120 |
| 2118 | 2121 |
| 2119 } } // namespace v8::internal | 2122 } } // namespace v8::internal |
| OLD | NEW |