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

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

Issue 2176173003: [Turbofan] Revert FP register aliasing support on Arm. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. Created 4 years, 4 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') | src/compiler/wasm-linkage.cc » ('j') | 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/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/compiler/linkage.h" 6 #include "src/compiler/linkage.h"
7 #include "src/compiler/register-allocator.h" 7 #include "src/compiler/register-allocator.h"
8 #include "src/string-stream.h" 8 #include "src/string-stream.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 15 matching lines...) Expand all
26 } 26 }
27 27
28 int GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) { 28 int GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
29 return kind == FP_REGISTERS ? cfg->num_double_registers() 29 return kind == FP_REGISTERS ? cfg->num_double_registers()
30 : cfg->num_general_registers(); 30 : cfg->num_general_registers();
31 } 31 }
32 32
33 33
34 int GetAllocatableRegisterCount(const RegisterConfiguration* cfg, 34 int GetAllocatableRegisterCount(const RegisterConfiguration* cfg,
35 RegisterKind kind) { 35 RegisterKind kind) {
36 return kind == FP_REGISTERS ? cfg->num_allocatable_double_registers() 36 return kind == FP_REGISTERS ? cfg->num_allocatable_aliased_double_registers()
37 : cfg->num_allocatable_general_registers(); 37 : cfg->num_allocatable_general_registers();
38 } 38 }
39 39
40 40
41 const int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg, 41 const int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg,
42 RegisterKind kind) { 42 RegisterKind kind) {
43 return kind == FP_REGISTERS ? cfg->allocatable_double_codes() 43 return kind == FP_REGISTERS ? cfg->allocatable_double_codes()
44 : cfg->allocatable_general_codes(); 44 : cfg->allocatable_general_codes();
45 } 45 }
46 46
(...skipping 18 matching lines...) Expand all
65 } 65 }
66 66
67 // TODO(dcarney): fix frame to allow frame accesses to half size location. 67 // TODO(dcarney): fix frame to allow frame accesses to half size location.
68 int GetByteWidth(MachineRepresentation rep) { 68 int GetByteWidth(MachineRepresentation rep) {
69 switch (rep) { 69 switch (rep) {
70 case MachineRepresentation::kBit: 70 case MachineRepresentation::kBit:
71 case MachineRepresentation::kWord8: 71 case MachineRepresentation::kWord8:
72 case MachineRepresentation::kWord16: 72 case MachineRepresentation::kWord16:
73 case MachineRepresentation::kWord32: 73 case MachineRepresentation::kWord32:
74 case MachineRepresentation::kTagged: 74 case MachineRepresentation::kTagged:
75 return kPointerSize;
75 case MachineRepresentation::kFloat32: 76 case MachineRepresentation::kFloat32:
77 // TODO(bbudge) Eliminate this when FP register aliasing works.
78 #if V8_TARGET_ARCH_ARM
79 return kDoubleSize;
80 #else
76 return kPointerSize; 81 return kPointerSize;
82 #endif
77 case MachineRepresentation::kWord64: 83 case MachineRepresentation::kWord64:
78 case MachineRepresentation::kFloat64: 84 case MachineRepresentation::kFloat64:
79 return 8; 85 return kDoubleSize;
80 case MachineRepresentation::kSimd128: 86 case MachineRepresentation::kSimd128:
81 return 16; 87 return kSimd128Size;
82 case MachineRepresentation::kNone: 88 case MachineRepresentation::kNone:
83 break; 89 break;
84 } 90 }
85 UNREACHABLE(); 91 UNREACHABLE();
86 return 0; 92 return 0;
87 } 93 }
88 94
89 } // namespace 95 } // namespace
90 96
91 class LiveRangeBound { 97 class LiveRangeBound {
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 code_(code), 1334 code_(code),
1329 debug_name_(debug_name), 1335 debug_name_(debug_name),
1330 config_(config), 1336 config_(config),
1331 phi_map_(allocation_zone()), 1337 phi_map_(allocation_zone()),
1332 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), 1338 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1333 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), 1339 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1334 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, 1340 live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
1335 allocation_zone()), 1341 allocation_zone()),
1336 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, 1342 fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
1337 allocation_zone()), 1343 allocation_zone()),
1338 fixed_float_live_ranges_(this->config()->num_float_registers(), nullptr,
1339 allocation_zone()),
1340 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, 1344 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
1341 allocation_zone()), 1345 allocation_zone()),
1342 fixed_simd128_live_ranges_(this->config()->num_simd128_registers(),
1343 nullptr, allocation_zone()),
1344 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()), 1346 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
1345 delayed_references_(allocation_zone()), 1347 delayed_references_(allocation_zone()),
1346 assigned_registers_(nullptr), 1348 assigned_registers_(nullptr),
1347 assigned_double_registers_(nullptr), 1349 assigned_double_registers_(nullptr),
1348 virtual_register_count_(code->VirtualRegisterCount()), 1350 virtual_register_count_(code->VirtualRegisterCount()),
1349 preassigned_slot_ranges_(zone) { 1351 preassigned_slot_ranges_(zone) {
1350 assigned_registers_ = new (code_zone()) 1352 assigned_registers_ = new (code_zone())
1351 BitVector(this->config()->num_general_registers(), code_zone()); 1353 BitVector(this->config()->num_general_registers(), code_zone());
1352 assigned_double_registers_ = new (code_zone()) 1354 assigned_double_registers_ = new (code_zone())
1353 BitVector(this->config()->num_double_registers(), code_zone()); 1355 BitVector(this->config()->num_double_registers(), code_zone());
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 DCHECK(!range->IsSplinter()); 1513 DCHECK(!range->IsSplinter());
1512 SpillRange* spill_range = 1514 SpillRange* spill_range =
1513 new (allocation_zone()) SpillRange(range, allocation_zone()); 1515 new (allocation_zone()) SpillRange(range, allocation_zone());
1514 return spill_range; 1516 return spill_range;
1515 } 1517 }
1516 1518
1517 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep, 1519 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep,
1518 int index) { 1520 int index) {
1519 switch (rep) { 1521 switch (rep) {
1520 case MachineRepresentation::kFloat32: 1522 case MachineRepresentation::kFloat32:
1523 case MachineRepresentation::kFloat64:
1521 case MachineRepresentation::kSimd128: 1524 case MachineRepresentation::kSimd128:
1522 if (kSimpleFPAliasing) {
1523 assigned_double_registers_->Add(index);
1524 } else {
1525 int alias_base_index = -1;
1526 int aliases = config()->GetAliases(
1527 rep, index, MachineRepresentation::kFloat64, &alias_base_index);
1528 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
1529 while (aliases--) {
1530 int aliased_reg = alias_base_index + aliases;
1531 assigned_double_registers_->Add(aliased_reg);
1532 }
1533 }
1534 break;
1535 case MachineRepresentation::kFloat64:
1536 assigned_double_registers_->Add(index); 1525 assigned_double_registers_->Add(index);
1537 break; 1526 break;
1538 default: 1527 default:
1539 DCHECK(!IsFloatingPoint(rep)); 1528 DCHECK(!IsFloatingPoint(rep));
1540 assigned_registers_->Add(index); 1529 assigned_registers_->Add(index);
1541 break; 1530 break;
1542 } 1531 }
1543 } 1532 }
1544 1533
1545 bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const { 1534 bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const {
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index); 1841 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
1853 range->AddUseInterval(start, end, allocation_zone()); 1842 range->AddUseInterval(start, end, allocation_zone());
1854 iterator.Advance(); 1843 iterator.Advance();
1855 } 1844 }
1856 } 1845 }
1857 1846
1858 int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) { 1847 int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) {
1859 int result = -index - 1; 1848 int result = -index - 1;
1860 switch (rep) { 1849 switch (rep) {
1861 case MachineRepresentation::kSimd128: 1850 case MachineRepresentation::kSimd128:
1862 result -= config()->num_float_registers();
1863 // Fall through.
1864 case MachineRepresentation::kFloat32: 1851 case MachineRepresentation::kFloat32:
1865 result -= config()->num_double_registers();
1866 // Fall through.
1867 case MachineRepresentation::kFloat64: 1852 case MachineRepresentation::kFloat64:
1868 result -= config()->num_general_registers(); 1853 result -= config()->num_general_registers();
1869 break; 1854 break;
1870 default: 1855 default:
1871 UNREACHABLE(); 1856 UNREACHABLE();
1872 break; 1857 break;
1873 } 1858 }
1874 return result; 1859 return result;
1875 } 1860 }
1876 1861
1877 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) { 1862 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
1878 DCHECK(index < config()->num_general_registers()); 1863 DCHECK(index < config()->num_general_registers());
1879 TopLevelLiveRange* result = data()->fixed_live_ranges()[index]; 1864 TopLevelLiveRange* result = data()->fixed_live_ranges()[index];
1880 if (result == nullptr) { 1865 if (result == nullptr) {
1881 MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); 1866 MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
1882 result = data()->NewLiveRange(FixedLiveRangeID(index), rep); 1867 result = data()->NewLiveRange(FixedLiveRangeID(index), rep);
1883 DCHECK(result->IsFixed()); 1868 DCHECK(result->IsFixed());
1884 result->set_assigned_register(index); 1869 result->set_assigned_register(index);
1885 data()->MarkAllocated(rep, index); 1870 data()->MarkAllocated(rep, index);
1886 data()->fixed_live_ranges()[index] = result; 1871 data()->fixed_live_ranges()[index] = result;
1887 } 1872 }
1888 return result; 1873 return result;
1889 } 1874 }
1890 1875
1891 TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor( 1876 TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor(
1892 int index, MachineRepresentation rep) { 1877 int index, MachineRepresentation rep) {
1893 TopLevelLiveRange* result = nullptr; 1878 TopLevelLiveRange* result = nullptr;
1894 switch (rep) { 1879 switch (rep) {
1895 case MachineRepresentation::kFloat32: 1880 case MachineRepresentation::kFloat32:
1896 DCHECK(rep == MachineRepresentation::kFloat32);
1897 DCHECK(index < config()->num_float_registers());
1898 result = data()->fixed_float_live_ranges()[index];
1899 if (result == nullptr) {
1900 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
1901 DCHECK(result->IsFixed());
1902 result->set_assigned_register(index);
1903 data()->MarkAllocated(rep, index);
1904 data()->fixed_float_live_ranges()[index] = result;
1905 }
1906 break;
1907 case MachineRepresentation::kFloat64: 1881 case MachineRepresentation::kFloat64:
1882 case MachineRepresentation::kSimd128:
1908 DCHECK(index < config()->num_double_registers()); 1883 DCHECK(index < config()->num_double_registers());
1909 result = data()->fixed_double_live_ranges()[index]; 1884 result = data()->fixed_double_live_ranges()[index];
1910 if (result == nullptr) { 1885 if (result == nullptr) {
1911 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep); 1886 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
1912 DCHECK(result->IsFixed()); 1887 DCHECK(result->IsFixed());
1913 result->set_assigned_register(index); 1888 result->set_assigned_register(index);
1914 data()->MarkAllocated(rep, index); 1889 data()->MarkAllocated(rep, index);
1915 data()->fixed_double_live_ranges()[index] = result; 1890 data()->fixed_double_live_ranges()[index] = result;
1916 } 1891 }
1917 break; 1892 break;
1918 case MachineRepresentation::kSimd128:
1919 DCHECK(index < config()->num_simd128_registers());
1920 result = data()->fixed_simd128_live_ranges()[index];
1921 if (result == nullptr) {
1922 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
1923 DCHECK(result->IsFixed());
1924 result->set_assigned_register(index);
1925 data()->MarkAllocated(rep, index);
1926 data()->fixed_simd128_live_ranges()[index] = result;
1927 }
1928 break;
1929 default: 1893 default:
1930 UNREACHABLE(); 1894 UNREACHABLE();
1931 break; 1895 break;
1932 } 1896 }
1933 return result; 1897 return result;
1934 } 1898 }
1935 1899
1936 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { 1900 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
1937 if (operand->IsUnallocated()) { 1901 if (operand->IsUnallocated()) {
1938 return data()->GetOrCreateLiveRangeFor( 1902 return data()->GetOrCreateLiveRangeFor(
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2045 // is OK because AddUseInterval will just merge it with the existing 2009 // is OK because AddUseInterval will just merge it with the existing
2046 // one at the end of the range. 2010 // one at the end of the range.
2047 int code = config()->GetAllocatableGeneralCode(i); 2011 int code = config()->GetAllocatableGeneralCode(i);
2048 TopLevelLiveRange* range = FixedLiveRangeFor(code); 2012 TopLevelLiveRange* range = FixedLiveRangeFor(code);
2049 range->AddUseInterval(curr_position, curr_position.End(), 2013 range->AddUseInterval(curr_position, curr_position.End(),
2050 allocation_zone()); 2014 allocation_zone());
2051 } 2015 }
2052 } 2016 }
2053 2017
2054 if (instr->ClobbersDoubleRegisters()) { 2018 if (instr->ClobbersDoubleRegisters()) {
2055 for (int i = 0; i < config()->num_allocatable_double_registers(); ++i) { 2019 for (int i = 0; i < config()->num_allocatable_aliased_double_registers();
2020 ++i) {
2056 // Add a UseInterval for all DoubleRegisters. See comment above for 2021 // Add a UseInterval for all DoubleRegisters. See comment above for
2057 // general registers. 2022 // general registers.
2058 int code = config()->GetAllocatableDoubleCode(i); 2023 int code = config()->GetAllocatableDoubleCode(i);
2059 TopLevelLiveRange* range = 2024 TopLevelLiveRange* range =
2060 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64); 2025 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64);
2061 range->AddUseInterval(curr_position, curr_position.End(), 2026 range->AddUseInterval(curr_position, curr_position.End(),
2062 allocation_zone()); 2027 allocation_zone());
2063 } 2028 }
2064 // Preserve fixed float registers on archs with non-simple aliasing.
2065 if (!kSimpleFPAliasing) {
2066 for (int i = 0; i < config()->num_allocatable_float_registers(); ++i) {
2067 // Add a UseInterval for all FloatRegisters. See comment above for
2068 // general registers.
2069 int code = config()->GetAllocatableFloatCode(i);
2070 TopLevelLiveRange* range =
2071 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32);
2072 range->AddUseInterval(curr_position, curr_position.End(),
2073 allocation_zone());
2074 }
2075 for (int i = 0; i < config()->num_allocatable_simd128_registers();
2076 ++i) {
2077 int code = config()->GetAllocatableSimd128Code(i);
2078 TopLevelLiveRange* range =
2079 FixedFPLiveRangeFor(code, MachineRepresentation::kSimd128);
2080 range->AddUseInterval(curr_position, curr_position.End(),
2081 allocation_zone());
2082 }
2083 }
2084 } 2029 }
2085 2030
2086 for (size_t i = 0; i < instr->InputCount(); i++) { 2031 for (size_t i = 0; i < instr->InputCount(); i++) {
2087 InstructionOperand* input = instr->InputAt(i); 2032 InstructionOperand* input = instr->InputAt(i);
2088 if (input->IsImmediate() || input->IsExplicit()) { 2033 if (input->IsImmediate() || input->IsExplicit()) {
2089 continue; // Ignore immediates and explicitly reserved registers. 2034 continue; // Ignore immediates and explicitly reserved registers.
2090 } 2035 }
2091 LifetimePosition use_pos; 2036 LifetimePosition use_pos;
2092 if (input->IsUnallocated() && 2037 if (input->IsUnallocated() &&
2093 UnallocatedOperand::cast(input)->IsUsedAtStart()) { 2038 UnallocatedOperand::cast(input)->IsUsedAtStart()) {
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
2637 } 2582 }
2638 } 2583 }
2639 SortUnhandled(); 2584 SortUnhandled();
2640 DCHECK(UnhandledIsSorted()); 2585 DCHECK(UnhandledIsSorted());
2641 2586
2642 if (mode() == GENERAL_REGISTERS) { 2587 if (mode() == GENERAL_REGISTERS) {
2643 for (TopLevelLiveRange* current : data()->fixed_live_ranges()) { 2588 for (TopLevelLiveRange* current : data()->fixed_live_ranges()) {
2644 if (current != nullptr) AddToInactive(current); 2589 if (current != nullptr) AddToInactive(current);
2645 } 2590 }
2646 } else { 2591 } else {
2647 for (TopLevelLiveRange* current : data()->fixed_float_live_ranges()) {
2648 if (current != nullptr) AddToInactive(current);
2649 }
2650 for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) { 2592 for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) {
2651 if (current != nullptr) AddToInactive(current); 2593 if (current != nullptr) AddToInactive(current);
2652 } 2594 }
2653 for (TopLevelLiveRange* current : data()->fixed_simd128_live_ranges()) {
2654 if (current != nullptr) AddToInactive(current);
2655 }
2656 } 2595 }
2657 2596
2658 while (!unhandled_live_ranges().empty()) { 2597 while (!unhandled_live_ranges().empty()) {
2659 DCHECK(UnhandledIsSorted()); 2598 DCHECK(UnhandledIsSorted());
2660 LiveRange* current = unhandled_live_ranges().back(); 2599 LiveRange* current = unhandled_live_ranges().back();
2661 unhandled_live_ranges().pop_back(); 2600 unhandled_live_ranges().pop_back();
2662 DCHECK(UnhandledIsSorted()); 2601 DCHECK(UnhandledIsSorted());
2663 LifetimePosition position = current->Start(); 2602 LifetimePosition position = current->Start();
2664 #ifdef DEBUG 2603 #ifdef DEBUG
2665 allocation_finger_ = position; 2604 allocation_finger_ = position;
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2812 2751
2813 void LinearScanAllocator::InactiveToActive(LiveRange* range) { 2752 void LinearScanAllocator::InactiveToActive(LiveRange* range) {
2814 RemoveElement(&inactive_live_ranges(), range); 2753 RemoveElement(&inactive_live_ranges(), range);
2815 active_live_ranges().push_back(range); 2754 active_live_ranges().push_back(range);
2816 TRACE("Moving live range %d:%d from inactive to active\n", 2755 TRACE("Moving live range %d:%d from inactive to active\n",
2817 range->TopLevel()->vreg(), range->relative_id()); 2756 range->TopLevel()->vreg(), range->relative_id());
2818 } 2757 }
2819 2758
2820 2759
2821 bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) { 2760 bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
2822 MachineRepresentation rep = current->representation();
2823 int num_regs = num_registers(); 2761 int num_regs = num_registers();
2824 int num_codes = num_allocatable_registers(); 2762 int num_codes = num_allocatable_registers();
2825 const int* codes = allocatable_register_codes(); 2763 const int* codes = allocatable_register_codes();
2826 if (!kSimpleFPAliasing) {
2827 if (rep == MachineRepresentation::kFloat32) {
2828 num_regs = data()->config()->num_float_registers();
2829 num_codes = data()->config()->num_allocatable_float_registers();
2830 codes = data()->config()->allocatable_float_codes();
2831 } else if (rep == MachineRepresentation::kSimd128) {
2832 num_regs = data()->config()->num_simd128_registers();
2833 num_codes = data()->config()->num_allocatable_simd128_registers();
2834 codes = data()->config()->allocatable_simd128_codes();
2835 }
2836 }
2837 2764
2838 LifetimePosition free_until_pos[RegisterConfiguration::kMaxFPRegisters]; 2765 LifetimePosition free_until_pos[RegisterConfiguration::kMaxFPRegisters];
2839 for (int i = 0; i < num_regs; i++) { 2766 for (int i = 0; i < num_regs; i++) {
2840 free_until_pos[i] = LifetimePosition::MaxPosition(); 2767 free_until_pos[i] = LifetimePosition::MaxPosition();
2841 } 2768 }
2842 2769
2843 for (LiveRange* cur_active : active_live_ranges()) { 2770 for (LiveRange* cur_active : active_live_ranges()) {
2844 int cur_reg = cur_active->assigned_register(); 2771 int cur_reg = cur_active->assigned_register();
2845 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { 2772 free_until_pos[cur_reg] = LifetimePosition::GapFromInstructionIndex(0);
2846 free_until_pos[cur_reg] = LifetimePosition::GapFromInstructionIndex(0); 2773 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg),
2847 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg), 2774 LifetimePosition::GapFromInstructionIndex(0).value());
2848 LifetimePosition::GapFromInstructionIndex(0).value());
2849 } else {
2850 int alias_base_index = -1;
2851 int aliases = data()->config()->GetAliases(
2852 cur_active->representation(), cur_reg, rep, &alias_base_index);
2853 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
2854 while (aliases--) {
2855 int aliased_reg = alias_base_index + aliases;
2856 free_until_pos[aliased_reg] =
2857 LifetimePosition::GapFromInstructionIndex(0);
2858 }
2859 }
2860 } 2775 }
2861 2776
2862 for (LiveRange* cur_inactive : inactive_live_ranges()) { 2777 for (LiveRange* cur_inactive : inactive_live_ranges()) {
2863 DCHECK(cur_inactive->End() > current->Start()); 2778 DCHECK(cur_inactive->End() > current->Start());
2864 LifetimePosition next_intersection = 2779 LifetimePosition next_intersection =
2865 cur_inactive->FirstIntersection(current); 2780 cur_inactive->FirstIntersection(current);
2866 if (!next_intersection.IsValid()) continue; 2781 if (!next_intersection.IsValid()) continue;
2867 int cur_reg = cur_inactive->assigned_register(); 2782 int cur_reg = cur_inactive->assigned_register();
2868 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { 2783 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
2869 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection); 2784 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
2870 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), 2785 Min(free_until_pos[cur_reg], next_intersection).value());
2871 Min(free_until_pos[cur_reg], next_intersection).value());
2872 } else {
2873 int alias_base_index = -1;
2874 int aliases = data()->config()->GetAliases(
2875 cur_inactive->representation(), cur_reg, rep, &alias_base_index);
2876 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
2877 while (aliases--) {
2878 int aliased_reg = alias_base_index + aliases;
2879 free_until_pos[aliased_reg] =
2880 Min(free_until_pos[aliased_reg], next_intersection);
2881 }
2882 }
2883 } 2786 }
2884 2787
2885 int hint_register; 2788 int hint_register;
2886 if (current->FirstHintPosition(&hint_register) != nullptr) { 2789 if (current->FirstHintPosition(&hint_register) != nullptr) {
2887 TRACE( 2790 TRACE(
2888 "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n", 2791 "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n",
2889 RegisterName(hint_register), free_until_pos[hint_register].value(), 2792 RegisterName(hint_register), free_until_pos[hint_register].value(),
2890 current->TopLevel()->vreg(), current->relative_id(), 2793 current->TopLevel()->vreg(), current->relative_id(),
2891 current->End().value()); 2794 current->End().value());
2892 2795
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2936 2839
2937 void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) { 2840 void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
2938 UsePosition* register_use = current->NextRegisterPosition(current->Start()); 2841 UsePosition* register_use = current->NextRegisterPosition(current->Start());
2939 if (register_use == nullptr) { 2842 if (register_use == nullptr) {
2940 // There is no use in the current live range that requires a register. 2843 // There is no use in the current live range that requires a register.
2941 // We can just spill it. 2844 // We can just spill it.
2942 Spill(current); 2845 Spill(current);
2943 return; 2846 return;
2944 } 2847 }
2945 2848
2946 MachineRepresentation rep = current->representation();
2947 int num_regs = num_registers(); 2849 int num_regs = num_registers();
2948 int num_codes = num_allocatable_registers(); 2850 int num_codes = num_allocatable_registers();
2949 const int* codes = allocatable_register_codes(); 2851 const int* codes = allocatable_register_codes();
2950 if (!kSimpleFPAliasing) {
2951 if (rep == MachineRepresentation::kFloat32) {
2952 num_regs = data()->config()->num_float_registers();
2953 num_codes = data()->config()->num_allocatable_float_registers();
2954 codes = data()->config()->allocatable_float_codes();
2955 } else if (rep == MachineRepresentation::kSimd128) {
2956 num_regs = data()->config()->num_simd128_registers();
2957 num_codes = data()->config()->num_allocatable_simd128_registers();
2958 codes = data()->config()->allocatable_simd128_codes();
2959 }
2960 }
2961 2852
2962 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters]; 2853 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters];
2963 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters]; 2854 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters];
2964 for (int i = 0; i < num_regs; i++) { 2855 for (int i = 0; i < num_regs; i++) {
2965 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); 2856 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
2966 } 2857 }
2967 2858
2968 for (LiveRange* range : active_live_ranges()) { 2859 for (LiveRange* range : active_live_ranges()) {
2969 int cur_reg = range->assigned_register(); 2860 int cur_reg = range->assigned_register();
2970 bool is_fixed_or_cant_spill = 2861 bool is_fixed_or_cant_spill =
2971 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start()); 2862 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start());
2972 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { 2863 if (is_fixed_or_cant_spill) {
2973 if (is_fixed_or_cant_spill) { 2864 block_pos[cur_reg] = use_pos[cur_reg] =
2974 block_pos[cur_reg] = use_pos[cur_reg] = 2865 LifetimePosition::GapFromInstructionIndex(0);
2975 LifetimePosition::GapFromInstructionIndex(0); 2866 } else {
2867 UsePosition* next_use =
2868 range->NextUsePositionRegisterIsBeneficial(current->Start());
2869 if (next_use == nullptr) {
2870 use_pos[cur_reg] = range->End();
2976 } else { 2871 } else {
2977 UsePosition* next_use = 2872 use_pos[cur_reg] = next_use->pos();
2978 range->NextUsePositionRegisterIsBeneficial(current->Start());
2979 if (next_use == nullptr) {
2980 use_pos[cur_reg] = range->End();
2981 } else {
2982 use_pos[cur_reg] = next_use->pos();
2983 }
2984 }
2985 } else {
2986 int alias_base_index = -1;
2987 int aliases = data()->config()->GetAliases(
2988 range->representation(), cur_reg, rep, &alias_base_index);
2989 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
2990 while (aliases--) {
2991 int aliased_reg = alias_base_index + aliases;
2992 if (is_fixed_or_cant_spill) {
2993 block_pos[aliased_reg] = use_pos[aliased_reg] =
2994 LifetimePosition::GapFromInstructionIndex(0);
2995 } else {
2996 UsePosition* next_use =
2997 range->NextUsePositionRegisterIsBeneficial(current->Start());
2998 if (next_use == nullptr) {
2999 use_pos[aliased_reg] = range->End();
3000 } else {
3001 use_pos[aliased_reg] = next_use->pos();
3002 }
3003 }
3004 } 2873 }
3005 } 2874 }
3006 } 2875 }
3007 2876
3008 for (LiveRange* range : inactive_live_ranges()) { 2877 for (LiveRange* range : inactive_live_ranges()) {
3009 DCHECK(range->End() > current->Start()); 2878 DCHECK(range->End() > current->Start());
3010 LifetimePosition next_intersection = range->FirstIntersection(current); 2879 LifetimePosition next_intersection = range->FirstIntersection(current);
3011 if (!next_intersection.IsValid()) continue; 2880 if (!next_intersection.IsValid()) continue;
3012 int cur_reg = range->assigned_register(); 2881 int cur_reg = range->assigned_register();
3013 bool is_fixed = range->TopLevel()->IsFixed(); 2882 bool is_fixed = range->TopLevel()->IsFixed();
3014 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { 2883 if (is_fixed) {
3015 if (is_fixed) { 2884 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
3016 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); 2885 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
3017 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
3018 } else {
3019 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
3020 }
3021 } else { 2886 } else {
3022 int alias_base_index = -1; 2887 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
3023 int aliases = data()->config()->GetAliases(
3024 range->representation(), cur_reg, rep, &alias_base_index);
3025 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
3026 while (aliases--) {
3027 int aliased_reg = alias_base_index + aliases;
3028 if (is_fixed) {
3029 block_pos[aliased_reg] =
3030 Min(block_pos[aliased_reg], next_intersection);
3031 use_pos[aliased_reg] =
3032 Min(block_pos[aliased_reg], use_pos[aliased_reg]);
3033 } else {
3034 use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection);
3035 }
3036 }
3037 } 2888 }
3038 } 2889 }
3039 2890
3040 int reg = codes[0]; 2891 int reg = codes[0];
3041 for (int i = 1; i < num_codes; ++i) { 2892 for (int i = 1; i < num_codes; ++i) {
3042 int code = codes[i]; 2893 int code = codes[i];
3043 if (use_pos[code] > use_pos[reg]) { 2894 if (use_pos[code] > use_pos[reg]) {
3044 reg = code; 2895 reg = code;
3045 } 2896 }
3046 } 2897 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 SplitAndSpillIntersecting(current); 2929 SplitAndSpillIntersecting(current);
3079 } 2930 }
3080 2931
3081 2932
3082 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { 2933 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
3083 DCHECK(current->HasRegisterAssigned()); 2934 DCHECK(current->HasRegisterAssigned());
3084 int reg = current->assigned_register(); 2935 int reg = current->assigned_register();
3085 LifetimePosition split_pos = current->Start(); 2936 LifetimePosition split_pos = current->Start();
3086 for (size_t i = 0; i < active_live_ranges().size(); ++i) { 2937 for (size_t i = 0; i < active_live_ranges().size(); ++i) {
3087 LiveRange* range = active_live_ranges()[i]; 2938 LiveRange* range = active_live_ranges()[i];
3088 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { 2939 if (range->assigned_register() != reg) continue;
3089 if (range->assigned_register() != reg) continue;
3090 } else {
3091 if (!data()->config()->AreAliases(current->representation(), reg,
3092 range->representation(),
3093 range->assigned_register())) {
3094 continue;
3095 }
3096 }
3097 2940
3098 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 2941 UsePosition* next_pos = range->NextRegisterPosition(current->Start());
3099 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); 2942 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
3100 if (next_pos == nullptr) { 2943 if (next_pos == nullptr) {
3101 SpillAfter(range, spill_pos); 2944 SpillAfter(range, spill_pos);
3102 } else { 2945 } else {
3103 // When spilling between spill_pos and next_pos ensure that the range 2946 // When spilling between spill_pos and next_pos ensure that the range
3104 // remains spilled at least until the start of the current live range. 2947 // remains spilled at least until the start of the current live range.
3105 // This guarantees that we will not introduce new unhandled ranges that 2948 // This guarantees that we will not introduce new unhandled ranges that
3106 // start before the current range as this violates allocation invariants 2949 // start before the current range as this violates allocation invariants
3107 // and will lead to an inconsistent state of active and inactive 2950 // and will lead to an inconsistent state of active and inactive
3108 // live-ranges: ranges are allocated in order of their start positions, 2951 // live-ranges: ranges are allocated in order of their start positions,
3109 // ranges are retired from active/inactive when the start of the 2952 // ranges are retired from active/inactive when the start of the
3110 // current live-range is larger than their end. 2953 // current live-range is larger than their end.
3111 DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(), 2954 DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(),
3112 next_pos->pos())); 2955 next_pos->pos()));
3113 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); 2956 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
3114 } 2957 }
3115 ActiveToHandled(range); 2958 ActiveToHandled(range);
3116 --i; 2959 --i;
3117 } 2960 }
3118 2961
3119 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { 2962 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
3120 LiveRange* range = inactive_live_ranges()[i]; 2963 LiveRange* range = inactive_live_ranges()[i];
3121 DCHECK(range->End() > current->Start()); 2964 DCHECK(range->End() > current->Start());
3122 if (range->TopLevel()->IsFixed()) continue; 2965 if (range->TopLevel()->IsFixed()) continue;
3123 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { 2966 if (range->assigned_register() != reg) continue;
3124 if (range->assigned_register() != reg) continue;
3125 } else {
3126 if (!data()->config()->AreAliases(current->representation(), reg,
3127 range->representation(),
3128 range->assigned_register()))
3129 continue;
3130 }
3131 2967
3132 LifetimePosition next_intersection = range->FirstIntersection(current); 2968 LifetimePosition next_intersection = range->FirstIntersection(current);
3133 if (next_intersection.IsValid()) { 2969 if (next_intersection.IsValid()) {
3134 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 2970 UsePosition* next_pos = range->NextRegisterPosition(current->Start());
3135 if (next_pos == nullptr) { 2971 if (next_pos == nullptr) {
3136 SpillAfter(range, split_pos); 2972 SpillAfter(range, split_pos);
3137 } else { 2973 } else {
3138 next_intersection = Min(next_intersection, next_pos->pos()); 2974 next_intersection = Min(next_intersection, next_pos->pos());
3139 SpillBetween(range, split_pos, next_intersection); 2975 SpillBetween(range, split_pos, next_intersection);
3140 } 2976 }
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
3783 } 3619 }
3784 } 3620 }
3785 } 3621 }
3786 } 3622 }
3787 } 3623 }
3788 3624
3789 3625
3790 } // namespace compiler 3626 } // namespace compiler
3791 } // namespace internal 3627 } // namespace internal
3792 } // namespace v8 3628 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/compiler/wasm-linkage.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698