Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: src/compiler/register-allocator.cc

Issue 1081053002: [turbofan] cleanup PointerMap (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: renames Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/compiler/linkage.h" 5 #include "src/compiler/linkage.h"
6 #include "src/compiler/register-allocator.h" 6 #include "src/compiler/register-allocator.h"
7 #include "src/string-stream.h" 7 #include "src/string-stream.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 } else if (operand->HasFixedDoubleRegisterPolicy()) { 715 } else if (operand->HasFixedDoubleRegisterPolicy()) {
716 allocated = AllocatedOperand(AllocatedOperand::DOUBLE_REGISTER, 716 allocated = AllocatedOperand(AllocatedOperand::DOUBLE_REGISTER,
717 operand->fixed_register_index()); 717 operand->fixed_register_index());
718 } else { 718 } else {
719 UNREACHABLE(); 719 UNREACHABLE();
720 } 720 }
721 InstructionOperand::ReplaceWith(operand, &allocated); 721 InstructionOperand::ReplaceWith(operand, &allocated);
722 if (is_tagged) { 722 if (is_tagged) {
723 TRACE("Fixed reg is tagged at %d\n", pos); 723 TRACE("Fixed reg is tagged at %d\n", pos);
724 auto instr = InstructionAt(pos); 724 auto instr = InstructionAt(pos);
725 if (instr->HasPointerMap()) { 725 if (instr->HasReferenceMap()) {
726 instr->pointer_map()->RecordPointer(operand, code_zone()); 726 instr->reference_map()->RecordReference(*operand);
727 } 727 }
728 } 728 }
729 return operand; 729 return operand;
730 } 730 }
731 731
732 732
733 LiveRange* RegisterAllocator::NewLiveRange(int index) { 733 LiveRange* RegisterAllocator::NewLiveRange(int index) {
734 // The LiveRange object itself can go in the local zone, but the 734 // The LiveRange object itself can go in the local zone, but the
735 // InstructionOperand needs to go in the code zone, since it may survive 735 // InstructionOperand needs to go in the code zone, since it may survive
736 // register allocation. 736 // register allocation.
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1219 if (!second_output->HasSameAsInputPolicy()) continue; 1219 if (!second_output->HasSameAsInputPolicy()) continue;
1220 DCHECK(i == 0); // Only valid for first output. 1220 DCHECK(i == 0); // Only valid for first output.
1221 UnallocatedOperand* cur_input = 1221 UnallocatedOperand* cur_input =
1222 UnallocatedOperand::cast(second->InputAt(0)); 1222 UnallocatedOperand::cast(second->InputAt(0));
1223 int output_vreg = second_output->virtual_register(); 1223 int output_vreg = second_output->virtual_register();
1224 int input_vreg = cur_input->virtual_register(); 1224 int input_vreg = cur_input->virtual_register();
1225 auto input_copy = cur_input->CopyUnconstrained(code_zone()); 1225 auto input_copy = cur_input->CopyUnconstrained(code_zone());
1226 cur_input->set_virtual_register(second_output->virtual_register()); 1226 cur_input->set_virtual_register(second_output->virtual_register());
1227 AddGapMove(instr_index, Instruction::END, input_copy, cur_input); 1227 AddGapMove(instr_index, Instruction::END, input_copy, cur_input);
1228 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { 1228 if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) {
1229 if (second->HasPointerMap()) { 1229 if (second->HasReferenceMap()) {
1230 second->pointer_map()->RecordPointer(input_copy, code_zone()); 1230 second->reference_map()->RecordReference(*input_copy);
1231 } 1231 }
1232 } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) { 1232 } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) {
1233 // The input is assumed to immediately have a tagged representation, 1233 // The input is assumed to immediately have a tagged representation,
1234 // before the pointer map can be used. I.e. the pointer map at the 1234 // before the pointer map can be used. I.e. the pointer map at the
1235 // instruction will include the output operand (whose value at the 1235 // instruction will include the output operand (whose value at the
1236 // beginning of the instruction is equal to the input operand). If 1236 // beginning of the instruction is equal to the input operand). If
1237 // this is not desired, then the pointer map at this instruction needs 1237 // this is not desired, then the pointer map at this instruction needs
1238 // to be adjusted manually. 1238 // to be adjusted manually.
1239 } 1239 }
1240 } 1240 }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 auto res = 1404 auto res =
1405 phi_map_.insert(std::make_pair(phi_vreg, PhiMapValue(phi, block))); 1405 phi_map_.insert(std::make_pair(phi_vreg, PhiMapValue(phi, block)));
1406 DCHECK(res.second); 1406 DCHECK(res.second);
1407 USE(res); 1407 USE(res);
1408 auto& output = phi->output(); 1408 auto& output = phi->output();
1409 for (size_t i = 0; i < phi->operands().size(); ++i) { 1409 for (size_t i = 0; i < phi->operands().size(); ++i) {
1410 InstructionBlock* cur_block = 1410 InstructionBlock* cur_block =
1411 code()->InstructionBlockAt(block->predecessors()[i]); 1411 code()->InstructionBlockAt(block->predecessors()[i]);
1412 AddGapMove(cur_block->last_instruction_index(), Instruction::END, 1412 AddGapMove(cur_block->last_instruction_index(), Instruction::END,
1413 &phi->inputs()[i], &output); 1413 &phi->inputs()[i], &output);
1414 DCHECK( 1414 DCHECK(!InstructionAt(cur_block->last_instruction_index())
1415 !InstructionAt(cur_block->last_instruction_index())->HasPointerMap()); 1415 ->HasReferenceMap());
1416 } 1416 }
1417 auto live_range = LiveRangeFor(phi_vreg); 1417 auto live_range = LiveRangeFor(phi_vreg);
1418 int gap_index = block->first_instruction_index(); 1418 int gap_index = block->first_instruction_index();
1419 live_range->SpillAtDefinition(local_zone(), gap_index, &output); 1419 live_range->SpillAtDefinition(local_zone(), gap_index, &output);
1420 live_range->SetSpillStartIndex(gap_index); 1420 live_range->SetSpillStartIndex(gap_index);
1421 // We use the phi-ness of some nodes in some later heuristics. 1421 // We use the phi-ness of some nodes in some later heuristics.
1422 live_range->set_is_phi(true); 1422 live_range->set_is_phi(true);
1423 live_range->set_is_non_loop_phi(!block->IsLoopHeader()); 1423 live_range->set_is_non_loop_phi(!block->IsLoopHeader());
1424 } 1424 }
1425 } 1425 }
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 const InstructionBlock* pred, 1693 const InstructionBlock* pred,
1694 InstructionOperand* pred_op) { 1694 InstructionOperand* pred_op) {
1695 if (pred_op->Equals(cur_op)) return; 1695 if (pred_op->Equals(cur_op)) return;
1696 int gap_index; 1696 int gap_index;
1697 Instruction::GapPosition position; 1697 Instruction::GapPosition position;
1698 if (block->PredecessorCount() == 1) { 1698 if (block->PredecessorCount() == 1) {
1699 gap_index = block->first_instruction_index(); 1699 gap_index = block->first_instruction_index();
1700 position = Instruction::START; 1700 position = Instruction::START;
1701 } else { 1701 } else {
1702 DCHECK(pred->SuccessorCount() == 1); 1702 DCHECK(pred->SuccessorCount() == 1);
1703 DCHECK(!InstructionAt(pred->last_instruction_index())->HasPointerMap()); 1703 DCHECK(!InstructionAt(pred->last_instruction_index())->HasReferenceMap());
1704 gap_index = pred->last_instruction_index(); 1704 gap_index = pred->last_instruction_index();
1705 position = Instruction::END; 1705 position = Instruction::END;
1706 } 1706 }
1707 AddGapMove(gap_index, position, pred_op, cur_op); 1707 AddGapMove(gap_index, position, pred_op, cur_op);
1708 } 1708 }
1709 1709
1710 1710
1711 void RegisterAllocator::BuildLiveRanges() { 1711 void RegisterAllocator::BuildLiveRanges() {
1712 // Process the blocks in reverse order. 1712 // Process the blocks in reverse order.
1713 for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0; 1713 for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1815 PrintF(" (function: %s)\n", debug_name()); 1815 PrintF(" (function: %s)\n", debug_name());
1816 } 1816 }
1817 iterator.Advance(); 1817 iterator.Advance();
1818 } 1818 }
1819 return found; 1819 return found;
1820 } 1820 }
1821 1821
1822 1822
1823 bool RegisterAllocator::SafePointsAreInOrder() const { 1823 bool RegisterAllocator::SafePointsAreInOrder() const {
1824 int safe_point = 0; 1824 int safe_point = 0;
1825 for (auto map : *code()->pointer_maps()) { 1825 for (auto map : *code()->reference_maps()) {
1826 if (safe_point > map->instruction_position()) return false; 1826 if (safe_point > map->instruction_position()) return false;
1827 safe_point = map->instruction_position(); 1827 safe_point = map->instruction_position();
1828 } 1828 }
1829 return true; 1829 return true;
1830 } 1830 }
1831 1831
1832 1832
1833 void RegisterAllocator::PopulatePointerMaps() { 1833 void RegisterAllocator::PopulateReferenceMaps() {
1834 DCHECK(SafePointsAreInOrder()); 1834 DCHECK(SafePointsAreInOrder());
1835 1835
1836 // Iterate over all safe point positions and record a pointer 1836 // Iterate over all safe point positions and record a pointer
1837 // for all spilled live ranges at this point. 1837 // for all spilled live ranges at this point.
1838 int last_range_start = 0; 1838 int last_range_start = 0;
1839 auto pointer_maps = code()->pointer_maps(); 1839 auto reference_maps = code()->reference_maps();
1840 PointerMapDeque::const_iterator first_it = pointer_maps->begin(); 1840 ReferenceMapDeque::const_iterator first_it = reference_maps->begin();
1841 for (LiveRange* range : live_ranges()) { 1841 for (LiveRange* range : live_ranges()) {
1842 if (range == nullptr) continue; 1842 if (range == nullptr) continue;
1843 // Iterate over the first parts of multi-part live ranges. 1843 // Iterate over the first parts of multi-part live ranges.
1844 if (range->IsChild()) continue; 1844 if (range->IsChild()) continue;
1845 // Skip non-reference values. 1845 // Skip non-reference values.
1846 if (!HasTaggedValue(range->id())) continue; 1846 if (!HasTaggedValue(range->id())) continue;
1847 // Skip empty live ranges. 1847 // Skip empty live ranges.
1848 if (range->IsEmpty()) continue; 1848 if (range->IsEmpty()) continue;
1849 1849
1850 // Find the extent of the range and its children. 1850 // Find the extent of the range and its children.
1851 int start = range->Start().ToInstructionIndex(); 1851 int start = range->Start().ToInstructionIndex();
1852 int end = 0; 1852 int end = 0;
1853 for (auto cur = range; cur != nullptr; cur = cur->next()) { 1853 for (auto cur = range; cur != nullptr; cur = cur->next()) {
1854 auto this_end = cur->End(); 1854 auto this_end = cur->End();
1855 if (this_end.ToInstructionIndex() > end) 1855 if (this_end.ToInstructionIndex() > end)
1856 end = this_end.ToInstructionIndex(); 1856 end = this_end.ToInstructionIndex();
1857 DCHECK(cur->Start().ToInstructionIndex() >= start); 1857 DCHECK(cur->Start().ToInstructionIndex() >= start);
1858 } 1858 }
1859 1859
1860 // Most of the ranges are in order, but not all. Keep an eye on when they 1860 // Most of the ranges are in order, but not all. Keep an eye on when they
1861 // step backwards and reset the first_it so we don't miss any safe points. 1861 // step backwards and reset the first_it so we don't miss any safe points.
1862 if (start < last_range_start) first_it = pointer_maps->begin(); 1862 if (start < last_range_start) first_it = reference_maps->begin();
1863 last_range_start = start; 1863 last_range_start = start;
1864 1864
1865 // Step across all the safe points that are before the start of this range, 1865 // Step across all the safe points that are before the start of this range,
1866 // recording how far we step in order to save doing this for the next range. 1866 // recording how far we step in order to save doing this for the next range.
1867 for (; first_it != pointer_maps->end(); ++first_it) { 1867 for (; first_it != reference_maps->end(); ++first_it) {
1868 auto map = *first_it; 1868 auto map = *first_it;
1869 if (map->instruction_position() >= start) break; 1869 if (map->instruction_position() >= start) break;
1870 } 1870 }
1871 1871
1872 // Step through the safe points to see whether they are in the range. 1872 // Step through the safe points to see whether they are in the range.
1873 for (auto it = first_it; it != pointer_maps->end(); ++it) { 1873 for (auto it = first_it; it != reference_maps->end(); ++it) {
1874 auto map = *it; 1874 auto map = *it;
1875 int safe_point = map->instruction_position(); 1875 int safe_point = map->instruction_position();
1876 1876
1877 // The safe points are sorted so we can stop searching here. 1877 // The safe points are sorted so we can stop searching here.
1878 if (safe_point - 1 > end) break; 1878 if (safe_point - 1 > end) break;
1879 1879
1880 // Advance to the next active range that covers the current 1880 // Advance to the next active range that covers the current
1881 // safe point position. 1881 // safe point position.
1882 auto safe_point_pos = 1882 auto safe_point_pos =
1883 LifetimePosition::InstructionFromInstructionIndex(safe_point); 1883 LifetimePosition::InstructionFromInstructionIndex(safe_point);
1884 auto cur = range; 1884 auto cur = range;
1885 while (cur != nullptr && !cur->Covers(safe_point_pos)) { 1885 while (cur != nullptr && !cur->Covers(safe_point_pos)) {
1886 cur = cur->next(); 1886 cur = cur->next();
1887 } 1887 }
1888 if (cur == nullptr) continue; 1888 if (cur == nullptr) continue;
1889 1889
1890 // Check if the live range is spilled and the safe point is after 1890 // Check if the live range is spilled and the safe point is after
1891 // the spill position. 1891 // the spill position.
1892 if (range->HasSpillOperand() && 1892 if (range->HasSpillOperand() &&
1893 safe_point >= range->spill_start_index() && 1893 safe_point >= range->spill_start_index() &&
1894 !range->GetSpillOperand()->IsConstant()) { 1894 !range->GetSpillOperand()->IsConstant()) {
1895 TRACE("Pointer for range %d (spilled at %d) at safe point %d\n", 1895 TRACE("Pointer for range %d (spilled at %d) at safe point %d\n",
1896 range->id(), range->spill_start_index(), safe_point); 1896 range->id(), range->spill_start_index(), safe_point);
1897 map->RecordPointer(range->GetSpillOperand(), code_zone()); 1897 map->RecordReference(*range->GetSpillOperand());
1898 } 1898 }
1899 1899
1900 if (!cur->IsSpilled()) { 1900 if (!cur->IsSpilled()) {
1901 TRACE( 1901 TRACE(
1902 "Pointer in register for range %d (start at %d) " 1902 "Pointer in register for range %d (start at %d) "
1903 "at safe point %d\n", 1903 "at safe point %d\n",
1904 cur->id(), cur->Start().Value(), safe_point); 1904 cur->id(), cur->Start().Value(), safe_point);
1905 InstructionOperand* operand = cur->GetAssignedOperand(operand_cache()); 1905 auto operand = cur->GetAssignedOperand();
1906 DCHECK(!operand->IsStackSlot()); 1906 DCHECK(!operand.IsStackSlot());
1907 map->RecordPointer(operand, code_zone()); 1907 map->RecordReference(operand);
1908 } 1908 }
1909 } 1909 }
1910 } 1910 }
1911 } 1911 }
1912 1912
1913 1913
1914 void RegisterAllocator::AllocateGeneralRegisters() { 1914 void RegisterAllocator::AllocateGeneralRegisters() {
1915 num_registers_ = config()->num_general_registers(); 1915 num_registers_ = config()->num_general_registers();
1916 mode_ = GENERAL_REGISTERS; 1916 mode_ = GENERAL_REGISTERS;
1917 AllocateRegisters(); 1917 AllocateRegisters();
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
2533 } else { 2533 } else {
2534 DCHECK(range->Kind() == GENERAL_REGISTERS); 2534 DCHECK(range->Kind() == GENERAL_REGISTERS);
2535 assigned_registers_->Add(reg); 2535 assigned_registers_->Add(reg);
2536 } 2536 }
2537 range->set_assigned_register(reg, operand_cache()); 2537 range->set_assigned_register(reg, operand_cache());
2538 } 2538 }
2539 2539
2540 } // namespace compiler 2540 } // namespace compiler
2541 } // namespace internal 2541 } // namespace internal
2542 } // namespace v8 2542 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698