OLD | NEW |
---|---|
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 Loading... | |
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_aliased_double_registers() | 36 return kind == FP_REGISTERS ? cfg->num_allocatable_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 20 matching lines...) Expand all Loading... | |
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::kTaggedSigned: | 74 case MachineRepresentation::kTaggedSigned: |
75 case MachineRepresentation::kTaggedPointer: | 75 case MachineRepresentation::kTaggedPointer: |
76 case MachineRepresentation::kTagged: | 76 case MachineRepresentation::kTagged: |
77 case MachineRepresentation::kFloat32: | |
77 return kPointerSize; | 78 return kPointerSize; |
78 case MachineRepresentation::kFloat32: | |
79 // TODO(bbudge) Eliminate this when FP register aliasing works. | |
80 #if V8_TARGET_ARCH_ARM | |
81 return kDoubleSize; | |
82 #else | |
83 return kPointerSize; | |
84 #endif | |
85 case MachineRepresentation::kWord64: | 79 case MachineRepresentation::kWord64: |
86 case MachineRepresentation::kFloat64: | 80 case MachineRepresentation::kFloat64: |
87 return kDoubleSize; | 81 return 8; |
Mircea Trofin
2016/10/12 21:09:26
here and below, don't we have a constant somewhere
bbudge
2016/10/12 23:07:18
Indeed. Done.
| |
88 case MachineRepresentation::kSimd128: | 82 case MachineRepresentation::kSimd128: |
89 return kSimd128Size; | 83 return 16; |
90 case MachineRepresentation::kNone: | 84 case MachineRepresentation::kNone: |
91 break; | 85 break; |
92 } | 86 } |
93 UNREACHABLE(); | 87 UNREACHABLE(); |
94 return 0; | 88 return 0; |
95 } | 89 } |
96 | 90 |
97 } // namespace | 91 } // namespace |
98 | 92 |
99 class LiveRangeBound { | 93 class LiveRangeBound { |
(...skipping 1253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1353 code_(code), | 1347 code_(code), |
1354 debug_name_(debug_name), | 1348 debug_name_(debug_name), |
1355 config_(config), | 1349 config_(config), |
1356 phi_map_(allocation_zone()), | 1350 phi_map_(allocation_zone()), |
1357 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), | 1351 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), |
1358 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), | 1352 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), |
1359 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, | 1353 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, |
1360 allocation_zone()), | 1354 allocation_zone()), |
1361 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, | 1355 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, |
1362 allocation_zone()), | 1356 allocation_zone()), |
1357 fixed_float_live_ranges_(this->config()->num_float_registers(), nullptr, | |
1358 allocation_zone()), | |
1363 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, | 1359 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, |
1364 allocation_zone()), | 1360 allocation_zone()), |
1361 fixed_simd128_live_ranges_(this->config()->num_simd128_registers(), | |
1362 nullptr, allocation_zone()), | |
1365 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()), | 1363 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()), |
1366 delayed_references_(allocation_zone()), | 1364 delayed_references_(allocation_zone()), |
1367 assigned_registers_(nullptr), | 1365 assigned_registers_(nullptr), |
1368 assigned_double_registers_(nullptr), | 1366 assigned_double_registers_(nullptr), |
1369 virtual_register_count_(code->VirtualRegisterCount()), | 1367 virtual_register_count_(code->VirtualRegisterCount()), |
1370 preassigned_slot_ranges_(zone) { | 1368 preassigned_slot_ranges_(zone) { |
1371 assigned_registers_ = new (code_zone()) | 1369 assigned_registers_ = new (code_zone()) |
1372 BitVector(this->config()->num_general_registers(), code_zone()); | 1370 BitVector(this->config()->num_general_registers(), code_zone()); |
1373 assigned_double_registers_ = new (code_zone()) | 1371 assigned_double_registers_ = new (code_zone()) |
1374 BitVector(this->config()->num_double_registers(), code_zone()); | 1372 BitVector(this->config()->num_double_registers(), code_zone()); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1532 DCHECK(!range->IsSplinter()); | 1530 DCHECK(!range->IsSplinter()); |
1533 SpillRange* spill_range = | 1531 SpillRange* spill_range = |
1534 new (allocation_zone()) SpillRange(range, allocation_zone()); | 1532 new (allocation_zone()) SpillRange(range, allocation_zone()); |
1535 return spill_range; | 1533 return spill_range; |
1536 } | 1534 } |
1537 | 1535 |
1538 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep, | 1536 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep, |
1539 int index) { | 1537 int index) { |
1540 switch (rep) { | 1538 switch (rep) { |
1541 case MachineRepresentation::kFloat32: | 1539 case MachineRepresentation::kFloat32: |
1540 case MachineRepresentation::kSimd128: | |
1541 if (kSimpleFPAliasing) { | |
1542 assigned_double_registers_->Add(index); | |
1543 } else { | |
1544 int alias_base_index = -1; | |
1545 int aliases = config()->GetAliases( | |
1546 rep, index, MachineRepresentation::kFloat64, &alias_base_index); | |
1547 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); | |
1548 while (aliases--) { | |
1549 int aliased_reg = alias_base_index + aliases; | |
1550 assigned_double_registers_->Add(aliased_reg); | |
1551 } | |
1552 } | |
1553 break; | |
1542 case MachineRepresentation::kFloat64: | 1554 case MachineRepresentation::kFloat64: |
1543 case MachineRepresentation::kSimd128: | |
1544 assigned_double_registers_->Add(index); | 1555 assigned_double_registers_->Add(index); |
1545 break; | 1556 break; |
1546 default: | 1557 default: |
1547 DCHECK(!IsFloatingPoint(rep)); | 1558 DCHECK(!IsFloatingPoint(rep)); |
1548 assigned_registers_->Add(index); | 1559 assigned_registers_->Add(index); |
1549 break; | 1560 break; |
1550 } | 1561 } |
1551 } | 1562 } |
1552 | 1563 |
1553 bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const { | 1564 bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const { |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1860 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index); | 1871 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index); |
1861 range->AddUseInterval(start, end, allocation_zone()); | 1872 range->AddUseInterval(start, end, allocation_zone()); |
1862 iterator.Advance(); | 1873 iterator.Advance(); |
1863 } | 1874 } |
1864 } | 1875 } |
1865 | 1876 |
1866 int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) { | 1877 int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) { |
1867 int result = -index - 1; | 1878 int result = -index - 1; |
1868 switch (rep) { | 1879 switch (rep) { |
1869 case MachineRepresentation::kSimd128: | 1880 case MachineRepresentation::kSimd128: |
1881 result -= config()->num_float_registers(); | |
1882 // Fall through. | |
1870 case MachineRepresentation::kFloat32: | 1883 case MachineRepresentation::kFloat32: |
1884 result -= config()->num_double_registers(); | |
1885 // Fall through. | |
1871 case MachineRepresentation::kFloat64: | 1886 case MachineRepresentation::kFloat64: |
1872 result -= config()->num_general_registers(); | 1887 result -= config()->num_general_registers(); |
1873 break; | 1888 break; |
1874 default: | 1889 default: |
1875 UNREACHABLE(); | 1890 UNREACHABLE(); |
1876 break; | 1891 break; |
1877 } | 1892 } |
1878 return result; | 1893 return result; |
1879 } | 1894 } |
1880 | 1895 |
1881 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) { | 1896 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) { |
1882 DCHECK(index < config()->num_general_registers()); | 1897 DCHECK(index < config()->num_general_registers()); |
1883 TopLevelLiveRange* result = data()->fixed_live_ranges()[index]; | 1898 TopLevelLiveRange* result = data()->fixed_live_ranges()[index]; |
1884 if (result == nullptr) { | 1899 if (result == nullptr) { |
1885 MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); | 1900 MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); |
1886 result = data()->NewLiveRange(FixedLiveRangeID(index), rep); | 1901 result = data()->NewLiveRange(FixedLiveRangeID(index), rep); |
1887 DCHECK(result->IsFixed()); | 1902 DCHECK(result->IsFixed()); |
1888 result->set_assigned_register(index); | 1903 result->set_assigned_register(index); |
1889 data()->MarkAllocated(rep, index); | 1904 data()->MarkAllocated(rep, index); |
1890 data()->fixed_live_ranges()[index] = result; | 1905 data()->fixed_live_ranges()[index] = result; |
1891 } | 1906 } |
1892 return result; | 1907 return result; |
1893 } | 1908 } |
1894 | 1909 |
1895 TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor( | 1910 TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor( |
1896 int index, MachineRepresentation rep) { | 1911 int index, MachineRepresentation rep) { |
1897 TopLevelLiveRange* result = nullptr; | 1912 int num_regs = -1; |
1913 ZoneVector<TopLevelLiveRange*>* live_ranges = nullptr; | |
1898 switch (rep) { | 1914 switch (rep) { |
1899 case MachineRepresentation::kFloat32: | 1915 case MachineRepresentation::kFloat32: |
1916 num_regs = config()->num_float_registers(); | |
1917 live_ranges = &data()->fixed_float_live_ranges(); | |
1918 break; | |
1900 case MachineRepresentation::kFloat64: | 1919 case MachineRepresentation::kFloat64: |
1920 num_regs = config()->num_double_registers(); | |
1921 live_ranges = &data()->fixed_double_live_ranges(); | |
1922 break; | |
1901 case MachineRepresentation::kSimd128: | 1923 case MachineRepresentation::kSimd128: |
1902 DCHECK(index < config()->num_double_registers()); | 1924 num_regs = config()->num_simd128_registers(); |
1903 result = data()->fixed_double_live_ranges()[index]; | 1925 live_ranges = &data()->fixed_simd128_live_ranges(); |
1904 if (result == nullptr) { | |
1905 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep); | |
1906 DCHECK(result->IsFixed()); | |
1907 result->set_assigned_register(index); | |
1908 data()->MarkAllocated(rep, index); | |
1909 data()->fixed_double_live_ranges()[index] = result; | |
1910 } | |
1911 break; | 1926 break; |
1912 default: | 1927 default: |
1913 UNREACHABLE(); | 1928 UNREACHABLE(); |
1914 break; | 1929 break; |
1915 } | 1930 } |
1931 | |
1932 DCHECK(index < num_regs); | |
1933 TopLevelLiveRange* result = (*live_ranges)[index]; | |
1934 if (result == nullptr) { | |
1935 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep); | |
1936 DCHECK(result->IsFixed()); | |
1937 result->set_assigned_register(index); | |
1938 data()->MarkAllocated(rep, index); | |
1939 (*live_ranges)[index] = result; | |
1940 } | |
1916 return result; | 1941 return result; |
1917 } | 1942 } |
1918 | 1943 |
1919 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { | 1944 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { |
1920 if (operand->IsUnallocated()) { | 1945 if (operand->IsUnallocated()) { |
1921 return data()->GetOrCreateLiveRangeFor( | 1946 return data()->GetOrCreateLiveRangeFor( |
1922 UnallocatedOperand::cast(operand)->virtual_register()); | 1947 UnallocatedOperand::cast(operand)->virtual_register()); |
1923 } else if (operand->IsConstant()) { | 1948 } else if (operand->IsConstant()) { |
1924 return data()->GetOrCreateLiveRangeFor( | 1949 return data()->GetOrCreateLiveRangeFor( |
1925 ConstantOperand::cast(operand)->virtual_register()); | 1950 ConstantOperand::cast(operand)->virtual_register()); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2028 // is OK because AddUseInterval will just merge it with the existing | 2053 // is OK because AddUseInterval will just merge it with the existing |
2029 // one at the end of the range. | 2054 // one at the end of the range. |
2030 int code = config()->GetAllocatableGeneralCode(i); | 2055 int code = config()->GetAllocatableGeneralCode(i); |
2031 TopLevelLiveRange* range = FixedLiveRangeFor(code); | 2056 TopLevelLiveRange* range = FixedLiveRangeFor(code); |
2032 range->AddUseInterval(curr_position, curr_position.End(), | 2057 range->AddUseInterval(curr_position, curr_position.End(), |
2033 allocation_zone()); | 2058 allocation_zone()); |
2034 } | 2059 } |
2035 } | 2060 } |
2036 | 2061 |
2037 if (instr->ClobbersDoubleRegisters()) { | 2062 if (instr->ClobbersDoubleRegisters()) { |
2038 for (int i = 0; i < config()->num_allocatable_aliased_double_registers(); | 2063 for (int i = 0; i < config()->num_allocatable_double_registers(); ++i) { |
2039 ++i) { | |
2040 // Add a UseInterval for all DoubleRegisters. See comment above for | 2064 // Add a UseInterval for all DoubleRegisters. See comment above for |
2041 // general registers. | 2065 // general registers. |
2042 int code = config()->GetAllocatableDoubleCode(i); | 2066 int code = config()->GetAllocatableDoubleCode(i); |
2043 TopLevelLiveRange* range = | 2067 TopLevelLiveRange* range = |
2044 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64); | 2068 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64); |
2045 range->AddUseInterval(curr_position, curr_position.End(), | 2069 range->AddUseInterval(curr_position, curr_position.End(), |
2046 allocation_zone()); | 2070 allocation_zone()); |
2047 } | 2071 } |
2072 // Preserve fixed float registers on archs with non-simple aliasing. | |
2073 if (!kSimpleFPAliasing) { | |
2074 for (int i = 0; i < config()->num_allocatable_float_registers(); ++i) { | |
2075 // Add a UseInterval for all FloatRegisters. See comment above for | |
2076 // general registers. | |
2077 int code = config()->GetAllocatableFloatCode(i); | |
2078 TopLevelLiveRange* range = | |
2079 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32); | |
2080 range->AddUseInterval(curr_position, curr_position.End(), | |
2081 allocation_zone()); | |
2082 } | |
2083 for (int i = 0; i < config()->num_allocatable_simd128_registers(); | |
2084 ++i) { | |
2085 int code = config()->GetAllocatableSimd128Code(i); | |
2086 TopLevelLiveRange* range = | |
2087 FixedFPLiveRangeFor(code, MachineRepresentation::kSimd128); | |
2088 range->AddUseInterval(curr_position, curr_position.End(), | |
2089 allocation_zone()); | |
2090 } | |
2091 } | |
2048 } | 2092 } |
2049 | 2093 |
2050 for (size_t i = 0; i < instr->InputCount(); i++) { | 2094 for (size_t i = 0; i < instr->InputCount(); i++) { |
2051 InstructionOperand* input = instr->InputAt(i); | 2095 InstructionOperand* input = instr->InputAt(i); |
2052 if (input->IsImmediate() || input->IsExplicit()) { | 2096 if (input->IsImmediate() || input->IsExplicit()) { |
2053 continue; // Ignore immediates and explicitly reserved registers. | 2097 continue; // Ignore immediates and explicitly reserved registers. |
2054 } | 2098 } |
2055 LifetimePosition use_pos; | 2099 LifetimePosition use_pos; |
2056 if (input->IsUnallocated() && | 2100 if (input->IsUnallocated() && |
2057 UnallocatedOperand::cast(input)->IsUsedAtStart()) { | 2101 UnallocatedOperand::cast(input)->IsUsedAtStart()) { |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2604 } | 2648 } |
2605 } | 2649 } |
2606 SortUnhandled(); | 2650 SortUnhandled(); |
2607 DCHECK(UnhandledIsSorted()); | 2651 DCHECK(UnhandledIsSorted()); |
2608 | 2652 |
2609 if (mode() == GENERAL_REGISTERS) { | 2653 if (mode() == GENERAL_REGISTERS) { |
2610 for (TopLevelLiveRange* current : data()->fixed_live_ranges()) { | 2654 for (TopLevelLiveRange* current : data()->fixed_live_ranges()) { |
2611 if (current != nullptr) AddToInactive(current); | 2655 if (current != nullptr) AddToInactive(current); |
2612 } | 2656 } |
2613 } else { | 2657 } else { |
2658 for (TopLevelLiveRange* current : data()->fixed_float_live_ranges()) { | |
2659 if (current != nullptr) AddToInactive(current); | |
2660 } | |
2614 for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) { | 2661 for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) { |
2615 if (current != nullptr) AddToInactive(current); | 2662 if (current != nullptr) AddToInactive(current); |
2616 } | 2663 } |
2664 for (TopLevelLiveRange* current : data()->fixed_simd128_live_ranges()) { | |
2665 if (current != nullptr) AddToInactive(current); | |
2666 } | |
2617 } | 2667 } |
2618 | 2668 |
2619 while (!unhandled_live_ranges().empty()) { | 2669 while (!unhandled_live_ranges().empty()) { |
2620 DCHECK(UnhandledIsSorted()); | 2670 DCHECK(UnhandledIsSorted()); |
2621 LiveRange* current = unhandled_live_ranges().back(); | 2671 LiveRange* current = unhandled_live_ranges().back(); |
2622 unhandled_live_ranges().pop_back(); | 2672 unhandled_live_ranges().pop_back(); |
2623 DCHECK(UnhandledIsSorted()); | 2673 DCHECK(UnhandledIsSorted()); |
2624 LifetimePosition position = current->Start(); | 2674 LifetimePosition position = current->Start(); |
2625 #ifdef DEBUG | 2675 #ifdef DEBUG |
2626 allocation_finger_ = position; | 2676 allocation_finger_ = position; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2787 | 2837 |
2788 void LinearScanAllocator::InactiveToActive(LiveRange* range) { | 2838 void LinearScanAllocator::InactiveToActive(LiveRange* range) { |
2789 RemoveElement(&inactive_live_ranges(), range); | 2839 RemoveElement(&inactive_live_ranges(), range); |
2790 active_live_ranges().push_back(range); | 2840 active_live_ranges().push_back(range); |
2791 TRACE("Moving live range %d:%d from inactive to active\n", | 2841 TRACE("Moving live range %d:%d from inactive to active\n", |
2792 range->TopLevel()->vreg(), range->relative_id()); | 2842 range->TopLevel()->vreg(), range->relative_id()); |
2793 } | 2843 } |
2794 | 2844 |
2795 void LinearScanAllocator::FindFreeRegistersForRange( | 2845 void LinearScanAllocator::FindFreeRegistersForRange( |
2796 LiveRange* range, Vector<LifetimePosition> positions) { | 2846 LiveRange* range, Vector<LifetimePosition> positions) { |
2847 MachineRepresentation rep = range->representation(); | |
2797 int num_regs = num_registers(); | 2848 int num_regs = num_registers(); |
2849 int num_codes = num_allocatable_registers(); | |
2850 const int* codes = allocatable_register_codes(); | |
2851 if (!kSimpleFPAliasing) { | |
2852 if (rep == MachineRepresentation::kFloat32) { | |
2853 num_regs = data()->config()->num_float_registers(); | |
2854 num_codes = data()->config()->num_allocatable_float_registers(); | |
2855 codes = data()->config()->allocatable_float_codes(); | |
Mircea Trofin
2016/10/12 21:09:26
would it make sense to move this logic to num_regi
bbudge
2016/10/12 23:07:17
I'd like to avoid the procedure call for non-ARM a
| |
2856 } else if (rep == MachineRepresentation::kSimd128) { | |
2857 num_regs = data()->config()->num_simd128_registers(); | |
2858 num_codes = data()->config()->num_allocatable_simd128_registers(); | |
2859 codes = data()->config()->allocatable_simd128_codes(); | |
2860 } | |
2861 } | |
2798 DCHECK_GE(positions.length(), num_regs); | 2862 DCHECK_GE(positions.length(), num_regs); |
2799 | 2863 |
2800 for (int i = 0; i < num_regs; i++) { | 2864 for (int i = 0; i < num_regs; i++) { |
2801 positions[i] = LifetimePosition::MaxPosition(); | 2865 positions[i] = LifetimePosition::MaxPosition(); |
2802 } | 2866 } |
2803 | 2867 |
2804 for (LiveRange* cur_active : active_live_ranges()) { | 2868 for (LiveRange* cur_active : active_live_ranges()) { |
2805 int cur_reg = cur_active->assigned_register(); | 2869 int cur_reg = cur_active->assigned_register(); |
2806 positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0); | 2870 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
2807 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg), | 2871 positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0); |
2808 LifetimePosition::GapFromInstructionIndex(0).value()); | 2872 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg), |
2873 LifetimePosition::GapFromInstructionIndex(0).value()); | |
2874 } else { | |
2875 int alias_base_index = -1; | |
2876 int aliases = data()->config()->GetAliases( | |
2877 cur_active->representation(), cur_reg, rep, &alias_base_index); | |
2878 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); | |
2879 while (aliases--) { | |
2880 int aliased_reg = alias_base_index + aliases; | |
2881 positions[aliased_reg] = LifetimePosition::GapFromInstructionIndex(0); | |
2882 } | |
2883 } | |
2809 } | 2884 } |
2810 | 2885 |
2811 for (LiveRange* cur_inactive : inactive_live_ranges()) { | 2886 for (LiveRange* cur_inactive : inactive_live_ranges()) { |
2812 DCHECK(cur_inactive->End() > range->Start()); | 2887 DCHECK(cur_inactive->End() > range->Start()); |
2813 LifetimePosition next_intersection = cur_inactive->FirstIntersection(range); | 2888 LifetimePosition next_intersection = cur_inactive->FirstIntersection(range); |
2814 if (!next_intersection.IsValid()) continue; | 2889 if (!next_intersection.IsValid()) continue; |
2815 int cur_reg = cur_inactive->assigned_register(); | 2890 int cur_reg = cur_inactive->assigned_register(); |
2816 positions[cur_reg] = Min(positions[cur_reg], next_intersection); | 2891 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
2817 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), | 2892 positions[cur_reg] = Min(positions[cur_reg], next_intersection); |
2818 Min(positions[cur_reg], next_intersection).value()); | 2893 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), |
2894 Min(positions[cur_reg], next_intersection).value()); | |
2895 } else { | |
2896 int alias_base_index = -1; | |
2897 int aliases = data()->config()->GetAliases( | |
2898 cur_inactive->representation(), cur_reg, rep, &alias_base_index); | |
2899 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); | |
2900 while (aliases--) { | |
2901 int aliased_reg = alias_base_index + aliases; | |
2902 positions[aliased_reg] = Min(positions[aliased_reg], next_intersection); | |
2903 } | |
2904 } | |
2819 } | 2905 } |
2820 } | 2906 } |
2821 | 2907 |
2822 // High-level register allocation summary: | 2908 // High-level register allocation summary: |
2823 // | 2909 // |
2824 // For regular, or hot (i.e. not splinter) ranges, we attempt to first | 2910 // For regular, or hot (i.e. not splinter) ranges, we attempt to first |
2825 // allocate first the preferred (hint) register. If that is not possible, | 2911 // allocate first the preferred (hint) register. If that is not possible, |
2826 // we find a register that's free, and allocate that. If that's not possible, | 2912 // we find a register that's free, and allocate that. If that's not possible, |
2827 // we search for a register to steal from a range that was allocated. The | 2913 // we search for a register to steal from a range that was allocated. The |
2828 // goal is to optimize for throughput by avoiding register-to-memory | 2914 // goal is to optimize for throughput by avoiding register-to-memory |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2889 current->relative_id()); | 2975 current->relative_id()); |
2890 SetLiveRangeAssignedRegister(current, hint_register); | 2976 SetLiveRangeAssignedRegister(current, hint_register); |
2891 return true; | 2977 return true; |
2892 } | 2978 } |
2893 } | 2979 } |
2894 return false; | 2980 return false; |
2895 } | 2981 } |
2896 | 2982 |
2897 bool LinearScanAllocator::TryAllocateFreeReg( | 2983 bool LinearScanAllocator::TryAllocateFreeReg( |
2898 LiveRange* current, const Vector<LifetimePosition>& free_until_pos) { | 2984 LiveRange* current, const Vector<LifetimePosition>& free_until_pos) { |
2985 MachineRepresentation rep = current->representation(); | |
2899 int num_codes = num_allocatable_registers(); | 2986 int num_codes = num_allocatable_registers(); |
2900 const int* codes = allocatable_register_codes(); | 2987 const int* codes = allocatable_register_codes(); |
2988 if (!kSimpleFPAliasing) { | |
2989 if (rep == MachineRepresentation::kFloat32) { | |
2990 num_codes = data()->config()->num_allocatable_float_registers(); | |
2991 codes = data()->config()->allocatable_float_codes(); | |
2992 } else if (rep == MachineRepresentation::kSimd128) { | |
2993 num_codes = data()->config()->num_allocatable_simd128_registers(); | |
2994 codes = data()->config()->allocatable_simd128_codes(); | |
Mircea Trofin
2016/10/12 21:09:26
see factoring comment above about the num_allocata
bbudge
2016/10/12 23:07:18
Done.
| |
2995 } | |
2996 } | |
2901 DCHECK_GE(free_until_pos.length(), num_codes); | 2997 DCHECK_GE(free_until_pos.length(), num_codes); |
2902 | 2998 |
2903 // Find the register which stays free for the longest time. | 2999 // Find the register which stays free for the longest time. |
2904 int reg = codes[0]; | 3000 int reg = codes[0]; |
2905 for (int i = 1; i < num_codes; ++i) { | 3001 for (int i = 1; i < num_codes; ++i) { |
2906 int code = codes[i]; | 3002 int code = codes[i]; |
2907 if (free_until_pos[code] > free_until_pos[reg]) { | 3003 if (free_until_pos[code] > free_until_pos[reg]) { |
2908 reg = code; | 3004 reg = code; |
2909 } | 3005 } |
2910 } | 3006 } |
(...skipping 24 matching lines...) Expand all Loading... | |
2935 | 3031 |
2936 void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) { | 3032 void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) { |
2937 UsePosition* register_use = current->NextRegisterPosition(current->Start()); | 3033 UsePosition* register_use = current->NextRegisterPosition(current->Start()); |
2938 if (register_use == nullptr) { | 3034 if (register_use == nullptr) { |
2939 // There is no use in the current live range that requires a register. | 3035 // There is no use in the current live range that requires a register. |
2940 // We can just spill it. | 3036 // We can just spill it. |
2941 Spill(current); | 3037 Spill(current); |
2942 return; | 3038 return; |
2943 } | 3039 } |
2944 | 3040 |
3041 MachineRepresentation rep = current->representation(); | |
2945 int num_regs = num_registers(); | 3042 int num_regs = num_registers(); |
2946 int num_codes = num_allocatable_registers(); | 3043 int num_codes = num_allocatable_registers(); |
2947 const int* codes = allocatable_register_codes(); | 3044 const int* codes = allocatable_register_codes(); |
3045 if (!kSimpleFPAliasing) { | |
3046 if (rep == MachineRepresentation::kFloat32) { | |
3047 num_regs = data()->config()->num_float_registers(); | |
3048 num_codes = data()->config()->num_allocatable_float_registers(); | |
3049 codes = data()->config()->allocatable_float_codes(); | |
3050 } else if (rep == MachineRepresentation::kSimd128) { | |
3051 num_regs = data()->config()->num_simd128_registers(); | |
3052 num_codes = data()->config()->num_allocatable_simd128_registers(); | |
3053 codes = data()->config()->allocatable_simd128_codes(); | |
Mircea Trofin
2016/10/12 21:09:26
factoring comment above
bbudge
2016/10/12 23:07:17
Done.
| |
3054 } | |
3055 } | |
2948 | 3056 |
2949 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters]; | 3057 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters]; |
2950 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters]; | 3058 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters]; |
2951 for (int i = 0; i < num_regs; i++) { | 3059 for (int i = 0; i < num_regs; i++) { |
2952 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 3060 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); |
2953 } | 3061 } |
2954 | 3062 |
2955 for (LiveRange* range : active_live_ranges()) { | 3063 for (LiveRange* range : active_live_ranges()) { |
2956 int cur_reg = range->assigned_register(); | 3064 int cur_reg = range->assigned_register(); |
2957 bool is_fixed_or_cant_spill = | 3065 bool is_fixed_or_cant_spill = |
2958 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start()); | 3066 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start()); |
2959 if (is_fixed_or_cant_spill) { | 3067 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
2960 block_pos[cur_reg] = use_pos[cur_reg] = | 3068 if (is_fixed_or_cant_spill) { |
2961 LifetimePosition::GapFromInstructionIndex(0); | 3069 block_pos[cur_reg] = use_pos[cur_reg] = |
3070 LifetimePosition::GapFromInstructionIndex(0); | |
3071 } else { | |
3072 UsePosition* next_use = | |
3073 range->NextUsePositionRegisterIsBeneficial(current->Start()); | |
3074 if (next_use == nullptr) { | |
3075 use_pos[cur_reg] = range->End(); | |
Mircea Trofin
2016/10/12 21:09:26
this logic around next_use appears below, too. Cou
bbudge
2016/10/12 23:07:17
I added a LiveRange;:NextLifetimePositionRegisterI
| |
3076 } else { | |
3077 use_pos[cur_reg] = next_use->pos(); | |
3078 } | |
3079 } | |
2962 } else { | 3080 } else { |
2963 UsePosition* next_use = | 3081 int alias_base_index = -1; |
2964 range->NextUsePositionRegisterIsBeneficial(current->Start()); | 3082 int aliases = data()->config()->GetAliases( |
2965 if (next_use == nullptr) { | 3083 range->representation(), cur_reg, rep, &alias_base_index); |
2966 use_pos[cur_reg] = range->End(); | 3084 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); |
2967 } else { | 3085 while (aliases--) { |
2968 use_pos[cur_reg] = next_use->pos(); | 3086 int aliased_reg = alias_base_index + aliases; |
3087 if (is_fixed_or_cant_spill) { | |
3088 block_pos[aliased_reg] = use_pos[aliased_reg] = | |
3089 LifetimePosition::GapFromInstructionIndex(0); | |
3090 } else { | |
3091 UsePosition* next_use = | |
3092 range->NextUsePositionRegisterIsBeneficial(current->Start()); | |
3093 if (next_use == nullptr) { | |
3094 use_pos[aliased_reg] = range->End(); | |
3095 } else { | |
3096 use_pos[aliased_reg] = next_use->pos(); | |
3097 } | |
3098 } | |
2969 } | 3099 } |
2970 } | 3100 } |
2971 } | 3101 } |
2972 | 3102 |
2973 for (LiveRange* range : inactive_live_ranges()) { | 3103 for (LiveRange* range : inactive_live_ranges()) { |
2974 DCHECK(range->End() > current->Start()); | 3104 DCHECK(range->End() > current->Start()); |
2975 LifetimePosition next_intersection = range->FirstIntersection(current); | 3105 LifetimePosition next_intersection = range->FirstIntersection(current); |
2976 if (!next_intersection.IsValid()) continue; | 3106 if (!next_intersection.IsValid()) continue; |
2977 int cur_reg = range->assigned_register(); | 3107 int cur_reg = range->assigned_register(); |
2978 bool is_fixed = range->TopLevel()->IsFixed(); | 3108 bool is_fixed = range->TopLevel()->IsFixed(); |
2979 if (is_fixed) { | 3109 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
2980 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); | 3110 if (is_fixed) { |
2981 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); | 3111 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); |
3112 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); | |
3113 } else { | |
3114 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); | |
3115 } | |
2982 } else { | 3116 } else { |
2983 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); | 3117 int alias_base_index = -1; |
3118 int aliases = data()->config()->GetAliases( | |
3119 range->representation(), cur_reg, rep, &alias_base_index); | |
3120 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); | |
3121 while (aliases--) { | |
3122 int aliased_reg = alias_base_index + aliases; | |
3123 if (is_fixed) { | |
3124 block_pos[aliased_reg] = | |
3125 Min(block_pos[aliased_reg], next_intersection); | |
3126 use_pos[aliased_reg] = | |
3127 Min(block_pos[aliased_reg], use_pos[aliased_reg]); | |
3128 } else { | |
3129 use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection); | |
3130 } | |
3131 } | |
2984 } | 3132 } |
2985 } | 3133 } |
2986 | 3134 |
2987 int reg = codes[0]; | 3135 int reg = codes[0]; |
2988 for (int i = 1; i < num_codes; ++i) { | 3136 for (int i = 1; i < num_codes; ++i) { |
2989 int code = codes[i]; | 3137 int code = codes[i]; |
2990 if (use_pos[code] > use_pos[reg]) { | 3138 if (use_pos[code] > use_pos[reg]) { |
2991 reg = code; | 3139 reg = code; |
2992 } | 3140 } |
2993 } | 3141 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3025 SplitAndSpillIntersecting(current); | 3173 SplitAndSpillIntersecting(current); |
3026 } | 3174 } |
3027 | 3175 |
3028 | 3176 |
3029 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { | 3177 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { |
3030 DCHECK(current->HasRegisterAssigned()); | 3178 DCHECK(current->HasRegisterAssigned()); |
3031 int reg = current->assigned_register(); | 3179 int reg = current->assigned_register(); |
3032 LifetimePosition split_pos = current->Start(); | 3180 LifetimePosition split_pos = current->Start(); |
3033 for (size_t i = 0; i < active_live_ranges().size(); ++i) { | 3181 for (size_t i = 0; i < active_live_ranges().size(); ++i) { |
3034 LiveRange* range = active_live_ranges()[i]; | 3182 LiveRange* range = active_live_ranges()[i]; |
3035 if (range->assigned_register() != reg) continue; | 3183 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
3184 if (range->assigned_register() != reg) continue; | |
3185 } else { | |
3186 if (!data()->config()->AreAliases(current->representation(), reg, | |
3187 range->representation(), | |
3188 range->assigned_register())) { | |
3189 continue; | |
3190 } | |
3191 } | |
3036 | 3192 |
3037 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); | 3193 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); |
3038 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); | 3194 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); |
3039 if (next_pos == nullptr) { | 3195 if (next_pos == nullptr) { |
3040 SpillAfter(range, spill_pos); | 3196 SpillAfter(range, spill_pos); |
3041 } else { | 3197 } else { |
3042 // When spilling between spill_pos and next_pos ensure that the range | 3198 // When spilling between spill_pos and next_pos ensure that the range |
3043 // remains spilled at least until the start of the current live range. | 3199 // remains spilled at least until the start of the current live range. |
3044 // This guarantees that we will not introduce new unhandled ranges that | 3200 // This guarantees that we will not introduce new unhandled ranges that |
3045 // start before the current range as this violates allocation invariants | 3201 // start before the current range as this violates allocation invariants |
3046 // and will lead to an inconsistent state of active and inactive | 3202 // and will lead to an inconsistent state of active and inactive |
3047 // live-ranges: ranges are allocated in order of their start positions, | 3203 // live-ranges: ranges are allocated in order of their start positions, |
3048 // ranges are retired from active/inactive when the start of the | 3204 // ranges are retired from active/inactive when the start of the |
3049 // current live-range is larger than their end. | 3205 // current live-range is larger than their end. |
3050 DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(), | 3206 DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(), |
3051 next_pos->pos())); | 3207 next_pos->pos())); |
3052 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); | 3208 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); |
3053 } | 3209 } |
3054 ActiveToHandled(range); | 3210 ActiveToHandled(range); |
3055 --i; | 3211 --i; |
3056 } | 3212 } |
3057 | 3213 |
3058 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { | 3214 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { |
3059 LiveRange* range = inactive_live_ranges()[i]; | 3215 LiveRange* range = inactive_live_ranges()[i]; |
3060 DCHECK(range->End() > current->Start()); | 3216 DCHECK(range->End() > current->Start()); |
3061 if (range->TopLevel()->IsFixed()) continue; | 3217 if (range->TopLevel()->IsFixed()) continue; |
3062 if (range->assigned_register() != reg) continue; | 3218 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
3219 if (range->assigned_register() != reg) continue; | |
3220 } else { | |
3221 if (!data()->config()->AreAliases(current->representation(), reg, | |
3222 range->representation(), | |
3223 range->assigned_register())) | |
3224 continue; | |
3225 } | |
3063 | 3226 |
3064 LifetimePosition next_intersection = range->FirstIntersection(current); | 3227 LifetimePosition next_intersection = range->FirstIntersection(current); |
3065 if (next_intersection.IsValid()) { | 3228 if (next_intersection.IsValid()) { |
3066 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); | 3229 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); |
3067 if (next_pos == nullptr) { | 3230 if (next_pos == nullptr) { |
3068 SpillAfter(range, split_pos); | 3231 SpillAfter(range, split_pos); |
3069 } else { | 3232 } else { |
3070 next_intersection = Min(next_intersection, next_pos->pos()); | 3233 next_intersection = Min(next_intersection, next_pos->pos()); |
3071 SpillBetween(range, split_pos, next_intersection); | 3234 SpillBetween(range, split_pos, next_intersection); |
3072 } | 3235 } |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3543 DCHECK(!code() | 3706 DCHECK(!code() |
3544 ->InstructionAt(pred->last_instruction_index()) | 3707 ->InstructionAt(pred->last_instruction_index()) |
3545 ->HasReferenceMap()); | 3708 ->HasReferenceMap()); |
3546 gap_index = pred->last_instruction_index(); | 3709 gap_index = pred->last_instruction_index(); |
3547 position = Instruction::END; | 3710 position = Instruction::END; |
3548 } | 3711 } |
3549 data()->AddGapMove(gap_index, position, pred_op, cur_op); | 3712 data()->AddGapMove(gap_index, position, pred_op, cur_op); |
3550 return gap_index; | 3713 return gap_index; |
3551 } | 3714 } |
3552 | 3715 |
3553 | |
3554 void LiveRangeConnector::ConnectRanges(Zone* local_zone) { | 3716 void LiveRangeConnector::ConnectRanges(Zone* local_zone) { |
3555 DelayedInsertionMap delayed_insertion_map(local_zone); | 3717 DelayedInsertionMap delayed_insertion_map(local_zone); |
3556 for (TopLevelLiveRange* top_range : data()->live_ranges()) { | 3718 for (TopLevelLiveRange* top_range : data()->live_ranges()) { |
3557 if (top_range == nullptr) continue; | 3719 if (top_range == nullptr) continue; |
3558 bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks(); | 3720 bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks(); |
3559 LiveRange* first_range = top_range; | 3721 LiveRange* first_range = top_range; |
3560 for (LiveRange *second_range = first_range->next(); second_range != nullptr; | 3722 for (LiveRange *second_range = first_range->next(); second_range != nullptr; |
3561 first_range = second_range, second_range = second_range->next()) { | 3723 first_range = second_range, second_range = second_range->next()) { |
3562 LifetimePosition pos = second_range->Start(); | 3724 LifetimePosition pos = second_range->Start(); |
3563 // Add gap move if the two live ranges touch and there is no block | 3725 // Add gap move if the two live ranges touch and there is no block |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3631 } | 3793 } |
3632 if (done) break; | 3794 if (done) break; |
3633 // Reset state. | 3795 // Reset state. |
3634 to_eliminate.clear(); | 3796 to_eliminate.clear(); |
3635 to_insert.clear(); | 3797 to_insert.clear(); |
3636 moves = it->first.first; | 3798 moves = it->first.first; |
3637 } | 3799 } |
3638 // Gather all MoveOperands for a single ParallelMove. | 3800 // Gather all MoveOperands for a single ParallelMove. |
3639 MoveOperands* move = | 3801 MoveOperands* move = |
3640 new (code_zone()) MoveOperands(it->first.second, it->second); | 3802 new (code_zone()) MoveOperands(it->first.second, it->second); |
3641 MoveOperands* eliminate = moves->PrepareInsertAfter(move); | 3803 moves->PrepareInsertAfter(move, &to_eliminate); |
3642 to_insert.push_back(move); | 3804 to_insert.push_back(move); |
3643 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | |
3644 } | 3805 } |
3645 } | 3806 } |
3646 | 3807 |
3647 | 3808 |
3648 void LiveRangeConnector::CommitSpillsInDeferredBlocks( | 3809 void LiveRangeConnector::CommitSpillsInDeferredBlocks( |
3649 TopLevelLiveRange* range, LiveRangeBoundArray* array, Zone* temp_zone) { | 3810 TopLevelLiveRange* range, LiveRangeBoundArray* array, Zone* temp_zone) { |
3650 DCHECK(range->IsSpilledOnlyInDeferredBlocks()); | 3811 DCHECK(range->IsSpilledOnlyInDeferredBlocks()); |
3651 DCHECK(!range->spilled()); | 3812 DCHECK(!range->spilled()); |
3652 | 3813 |
3653 InstructionSequence* code = data()->code(); | 3814 InstructionSequence* code = data()->code(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3715 } | 3876 } |
3716 } | 3877 } |
3717 } | 3878 } |
3718 } | 3879 } |
3719 } | 3880 } |
3720 | 3881 |
3721 | 3882 |
3722 } // namespace compiler | 3883 } // namespace compiler |
3723 } // namespace internal | 3884 } // namespace internal |
3724 } // namespace v8 | 3885 } // namespace v8 |
OLD | NEW |