| 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 kDoubleSize; |
| 88 case MachineRepresentation::kSimd128: | 82 case MachineRepresentation::kSimd128: |
| 89 return kSimd128Size; | 83 return kSimd128Size; |
| 90 case MachineRepresentation::kNone: | 84 case MachineRepresentation::kNone: |
| 91 break; | 85 break; |
| 92 } | 86 } |
| 93 UNREACHABLE(); | 87 UNREACHABLE(); |
| 94 return 0; | 88 return 0; |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 | 485 |
| 492 UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial( | 486 UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial( |
| 493 LifetimePosition start) const { | 487 LifetimePosition start) const { |
| 494 UsePosition* pos = NextUsePosition(start); | 488 UsePosition* pos = NextUsePosition(start); |
| 495 while (pos != nullptr && !pos->RegisterIsBeneficial()) { | 489 while (pos != nullptr && !pos->RegisterIsBeneficial()) { |
| 496 pos = pos->next(); | 490 pos = pos->next(); |
| 497 } | 491 } |
| 498 return pos; | 492 return pos; |
| 499 } | 493 } |
| 500 | 494 |
| 495 LifetimePosition LiveRange::NextLifetimePositionRegisterIsBeneficial( |
| 496 const LifetimePosition& start) const { |
| 497 UsePosition* next_use = NextUsePositionRegisterIsBeneficial(start); |
| 498 if (next_use == nullptr) return End(); |
| 499 return next_use->pos(); |
| 500 } |
| 501 | 501 |
| 502 UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial( | 502 UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial( |
| 503 LifetimePosition start) const { | 503 LifetimePosition start) const { |
| 504 UsePosition* pos = first_pos(); | 504 UsePosition* pos = first_pos(); |
| 505 UsePosition* prev = nullptr; | 505 UsePosition* prev = nullptr; |
| 506 while (pos != nullptr && pos->pos() < start) { | 506 while (pos != nullptr && pos->pos() < start) { |
| 507 if (pos->RegisterIsBeneficial()) prev = pos; | 507 if (pos->RegisterIsBeneficial()) prev = pos; |
| 508 pos = pos->next(); | 508 pos = pos->next(); |
| 509 } | 509 } |
| 510 return prev; | 510 return prev; |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 code_(code), | 1353 code_(code), |
| 1354 debug_name_(debug_name), | 1354 debug_name_(debug_name), |
| 1355 config_(config), | 1355 config_(config), |
| 1356 phi_map_(allocation_zone()), | 1356 phi_map_(allocation_zone()), |
| 1357 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), | 1357 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), |
| 1358 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), | 1358 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), |
| 1359 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, | 1359 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, |
| 1360 allocation_zone()), | 1360 allocation_zone()), |
| 1361 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, | 1361 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, |
| 1362 allocation_zone()), | 1362 allocation_zone()), |
| 1363 fixed_float_live_ranges_(this->config()->num_float_registers(), nullptr, |
| 1364 allocation_zone()), |
| 1363 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, | 1365 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, |
| 1364 allocation_zone()), | 1366 allocation_zone()), |
| 1367 fixed_simd128_live_ranges_(this->config()->num_simd128_registers(), |
| 1368 nullptr, allocation_zone()), |
| 1365 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()), | 1369 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()), |
| 1366 delayed_references_(allocation_zone()), | 1370 delayed_references_(allocation_zone()), |
| 1367 assigned_registers_(nullptr), | 1371 assigned_registers_(nullptr), |
| 1368 assigned_double_registers_(nullptr), | 1372 assigned_double_registers_(nullptr), |
| 1369 virtual_register_count_(code->VirtualRegisterCount()), | 1373 virtual_register_count_(code->VirtualRegisterCount()), |
| 1370 preassigned_slot_ranges_(zone) { | 1374 preassigned_slot_ranges_(zone) { |
| 1371 assigned_registers_ = new (code_zone()) | 1375 assigned_registers_ = new (code_zone()) |
| 1372 BitVector(this->config()->num_general_registers(), code_zone()); | 1376 BitVector(this->config()->num_general_registers(), code_zone()); |
| 1373 assigned_double_registers_ = new (code_zone()) | 1377 assigned_double_registers_ = new (code_zone()) |
| 1374 BitVector(this->config()->num_double_registers(), code_zone()); | 1378 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()); | 1536 DCHECK(!range->IsSplinter()); |
| 1533 SpillRange* spill_range = | 1537 SpillRange* spill_range = |
| 1534 new (allocation_zone()) SpillRange(range, allocation_zone()); | 1538 new (allocation_zone()) SpillRange(range, allocation_zone()); |
| 1535 return spill_range; | 1539 return spill_range; |
| 1536 } | 1540 } |
| 1537 | 1541 |
| 1538 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep, | 1542 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep, |
| 1539 int index) { | 1543 int index) { |
| 1540 switch (rep) { | 1544 switch (rep) { |
| 1541 case MachineRepresentation::kFloat32: | 1545 case MachineRepresentation::kFloat32: |
| 1546 case MachineRepresentation::kSimd128: |
| 1547 if (kSimpleFPAliasing) { |
| 1548 assigned_double_registers_->Add(index); |
| 1549 } else { |
| 1550 int alias_base_index = -1; |
| 1551 int aliases = config()->GetAliases( |
| 1552 rep, index, MachineRepresentation::kFloat64, &alias_base_index); |
| 1553 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); |
| 1554 while (aliases--) { |
| 1555 int aliased_reg = alias_base_index + aliases; |
| 1556 assigned_double_registers_->Add(aliased_reg); |
| 1557 } |
| 1558 } |
| 1559 break; |
| 1542 case MachineRepresentation::kFloat64: | 1560 case MachineRepresentation::kFloat64: |
| 1543 case MachineRepresentation::kSimd128: | |
| 1544 assigned_double_registers_->Add(index); | 1561 assigned_double_registers_->Add(index); |
| 1545 break; | 1562 break; |
| 1546 default: | 1563 default: |
| 1547 DCHECK(!IsFloatingPoint(rep)); | 1564 DCHECK(!IsFloatingPoint(rep)); |
| 1548 assigned_registers_->Add(index); | 1565 assigned_registers_->Add(index); |
| 1549 break; | 1566 break; |
| 1550 } | 1567 } |
| 1551 } | 1568 } |
| 1552 | 1569 |
| 1553 bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const { | 1570 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); | 1877 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index); |
| 1861 range->AddUseInterval(start, end, allocation_zone()); | 1878 range->AddUseInterval(start, end, allocation_zone()); |
| 1862 iterator.Advance(); | 1879 iterator.Advance(); |
| 1863 } | 1880 } |
| 1864 } | 1881 } |
| 1865 | 1882 |
| 1866 int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) { | 1883 int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) { |
| 1867 int result = -index - 1; | 1884 int result = -index - 1; |
| 1868 switch (rep) { | 1885 switch (rep) { |
| 1869 case MachineRepresentation::kSimd128: | 1886 case MachineRepresentation::kSimd128: |
| 1887 result -= config()->num_float_registers(); |
| 1888 // Fall through. |
| 1870 case MachineRepresentation::kFloat32: | 1889 case MachineRepresentation::kFloat32: |
| 1890 result -= config()->num_double_registers(); |
| 1891 // Fall through. |
| 1871 case MachineRepresentation::kFloat64: | 1892 case MachineRepresentation::kFloat64: |
| 1872 result -= config()->num_general_registers(); | 1893 result -= config()->num_general_registers(); |
| 1873 break; | 1894 break; |
| 1874 default: | 1895 default: |
| 1875 UNREACHABLE(); | 1896 UNREACHABLE(); |
| 1876 break; | 1897 break; |
| 1877 } | 1898 } |
| 1878 return result; | 1899 return result; |
| 1879 } | 1900 } |
| 1880 | 1901 |
| 1881 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) { | 1902 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) { |
| 1882 DCHECK(index < config()->num_general_registers()); | 1903 DCHECK(index < config()->num_general_registers()); |
| 1883 TopLevelLiveRange* result = data()->fixed_live_ranges()[index]; | 1904 TopLevelLiveRange* result = data()->fixed_live_ranges()[index]; |
| 1884 if (result == nullptr) { | 1905 if (result == nullptr) { |
| 1885 MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); | 1906 MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); |
| 1886 result = data()->NewLiveRange(FixedLiveRangeID(index), rep); | 1907 result = data()->NewLiveRange(FixedLiveRangeID(index), rep); |
| 1887 DCHECK(result->IsFixed()); | 1908 DCHECK(result->IsFixed()); |
| 1888 result->set_assigned_register(index); | 1909 result->set_assigned_register(index); |
| 1889 data()->MarkAllocated(rep, index); | 1910 data()->MarkAllocated(rep, index); |
| 1890 data()->fixed_live_ranges()[index] = result; | 1911 data()->fixed_live_ranges()[index] = result; |
| 1891 } | 1912 } |
| 1892 return result; | 1913 return result; |
| 1893 } | 1914 } |
| 1894 | 1915 |
| 1895 TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor( | 1916 TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor( |
| 1896 int index, MachineRepresentation rep) { | 1917 int index, MachineRepresentation rep) { |
| 1897 TopLevelLiveRange* result = nullptr; | 1918 int num_regs = -1; |
| 1919 ZoneVector<TopLevelLiveRange*>* live_ranges = nullptr; |
| 1898 switch (rep) { | 1920 switch (rep) { |
| 1899 case MachineRepresentation::kFloat32: | 1921 case MachineRepresentation::kFloat32: |
| 1922 num_regs = config()->num_float_registers(); |
| 1923 live_ranges = &data()->fixed_float_live_ranges(); |
| 1924 break; |
| 1900 case MachineRepresentation::kFloat64: | 1925 case MachineRepresentation::kFloat64: |
| 1926 num_regs = config()->num_double_registers(); |
| 1927 live_ranges = &data()->fixed_double_live_ranges(); |
| 1928 break; |
| 1901 case MachineRepresentation::kSimd128: | 1929 case MachineRepresentation::kSimd128: |
| 1902 DCHECK(index < config()->num_double_registers()); | 1930 num_regs = config()->num_simd128_registers(); |
| 1903 result = data()->fixed_double_live_ranges()[index]; | 1931 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; | 1932 break; |
| 1912 default: | 1933 default: |
| 1913 UNREACHABLE(); | 1934 UNREACHABLE(); |
| 1914 break; | 1935 break; |
| 1915 } | 1936 } |
| 1937 |
| 1938 DCHECK(index < num_regs); |
| 1939 TopLevelLiveRange* result = (*live_ranges)[index]; |
| 1940 if (result == nullptr) { |
| 1941 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep); |
| 1942 DCHECK(result->IsFixed()); |
| 1943 result->set_assigned_register(index); |
| 1944 data()->MarkAllocated(rep, index); |
| 1945 (*live_ranges)[index] = result; |
| 1946 } |
| 1916 return result; | 1947 return result; |
| 1917 } | 1948 } |
| 1918 | 1949 |
| 1919 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { | 1950 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { |
| 1920 if (operand->IsUnallocated()) { | 1951 if (operand->IsUnallocated()) { |
| 1921 return data()->GetOrCreateLiveRangeFor( | 1952 return data()->GetOrCreateLiveRangeFor( |
| 1922 UnallocatedOperand::cast(operand)->virtual_register()); | 1953 UnallocatedOperand::cast(operand)->virtual_register()); |
| 1923 } else if (operand->IsConstant()) { | 1954 } else if (operand->IsConstant()) { |
| 1924 return data()->GetOrCreateLiveRangeFor( | 1955 return data()->GetOrCreateLiveRangeFor( |
| 1925 ConstantOperand::cast(operand)->virtual_register()); | 1956 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 | 2059 // is OK because AddUseInterval will just merge it with the existing |
| 2029 // one at the end of the range. | 2060 // one at the end of the range. |
| 2030 int code = config()->GetAllocatableGeneralCode(i); | 2061 int code = config()->GetAllocatableGeneralCode(i); |
| 2031 TopLevelLiveRange* range = FixedLiveRangeFor(code); | 2062 TopLevelLiveRange* range = FixedLiveRangeFor(code); |
| 2032 range->AddUseInterval(curr_position, curr_position.End(), | 2063 range->AddUseInterval(curr_position, curr_position.End(), |
| 2033 allocation_zone()); | 2064 allocation_zone()); |
| 2034 } | 2065 } |
| 2035 } | 2066 } |
| 2036 | 2067 |
| 2037 if (instr->ClobbersDoubleRegisters()) { | 2068 if (instr->ClobbersDoubleRegisters()) { |
| 2038 for (int i = 0; i < config()->num_allocatable_aliased_double_registers(); | 2069 for (int i = 0; i < config()->num_allocatable_double_registers(); ++i) { |
| 2039 ++i) { | |
| 2040 // Add a UseInterval for all DoubleRegisters. See comment above for | 2070 // Add a UseInterval for all DoubleRegisters. See comment above for |
| 2041 // general registers. | 2071 // general registers. |
| 2042 int code = config()->GetAllocatableDoubleCode(i); | 2072 int code = config()->GetAllocatableDoubleCode(i); |
| 2043 TopLevelLiveRange* range = | 2073 TopLevelLiveRange* range = |
| 2044 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64); | 2074 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64); |
| 2045 range->AddUseInterval(curr_position, curr_position.End(), | 2075 range->AddUseInterval(curr_position, curr_position.End(), |
| 2046 allocation_zone()); | 2076 allocation_zone()); |
| 2047 } | 2077 } |
| 2078 // Clobber fixed float registers on archs with non-simple aliasing. |
| 2079 if (!kSimpleFPAliasing) { |
| 2080 for (int i = 0; i < config()->num_allocatable_float_registers(); ++i) { |
| 2081 // Add a UseInterval for all FloatRegisters. See comment above for |
| 2082 // general registers. |
| 2083 int code = config()->GetAllocatableFloatCode(i); |
| 2084 TopLevelLiveRange* range = |
| 2085 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32); |
| 2086 range->AddUseInterval(curr_position, curr_position.End(), |
| 2087 allocation_zone()); |
| 2088 } |
| 2089 for (int i = 0; i < config()->num_allocatable_simd128_registers(); |
| 2090 ++i) { |
| 2091 int code = config()->GetAllocatableSimd128Code(i); |
| 2092 TopLevelLiveRange* range = |
| 2093 FixedFPLiveRangeFor(code, MachineRepresentation::kSimd128); |
| 2094 range->AddUseInterval(curr_position, curr_position.End(), |
| 2095 allocation_zone()); |
| 2096 } |
| 2097 } |
| 2048 } | 2098 } |
| 2049 | 2099 |
| 2050 for (size_t i = 0; i < instr->InputCount(); i++) { | 2100 for (size_t i = 0; i < instr->InputCount(); i++) { |
| 2051 InstructionOperand* input = instr->InputAt(i); | 2101 InstructionOperand* input = instr->InputAt(i); |
| 2052 if (input->IsImmediate() || input->IsExplicit()) { | 2102 if (input->IsImmediate() || input->IsExplicit()) { |
| 2053 continue; // Ignore immediates and explicitly reserved registers. | 2103 continue; // Ignore immediates and explicitly reserved registers. |
| 2054 } | 2104 } |
| 2055 LifetimePosition use_pos; | 2105 LifetimePosition use_pos; |
| 2056 if (input->IsUnallocated() && | 2106 if (input->IsUnallocated() && |
| 2057 UnallocatedOperand::cast(input)->IsUsedAtStart()) { | 2107 UnallocatedOperand::cast(input)->IsUsedAtStart()) { |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2683 } | 2733 } |
| 2684 } | 2734 } |
| 2685 SortUnhandled(); | 2735 SortUnhandled(); |
| 2686 DCHECK(UnhandledIsSorted()); | 2736 DCHECK(UnhandledIsSorted()); |
| 2687 | 2737 |
| 2688 if (mode() == GENERAL_REGISTERS) { | 2738 if (mode() == GENERAL_REGISTERS) { |
| 2689 for (TopLevelLiveRange* current : data()->fixed_live_ranges()) { | 2739 for (TopLevelLiveRange* current : data()->fixed_live_ranges()) { |
| 2690 if (current != nullptr) AddToInactive(current); | 2740 if (current != nullptr) AddToInactive(current); |
| 2691 } | 2741 } |
| 2692 } else { | 2742 } else { |
| 2743 for (TopLevelLiveRange* current : data()->fixed_float_live_ranges()) { |
| 2744 if (current != nullptr) AddToInactive(current); |
| 2745 } |
| 2693 for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) { | 2746 for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) { |
| 2694 if (current != nullptr) AddToInactive(current); | 2747 if (current != nullptr) AddToInactive(current); |
| 2695 } | 2748 } |
| 2749 for (TopLevelLiveRange* current : data()->fixed_simd128_live_ranges()) { |
| 2750 if (current != nullptr) AddToInactive(current); |
| 2751 } |
| 2696 } | 2752 } |
| 2697 | 2753 |
| 2698 while (!unhandled_live_ranges().empty()) { | 2754 while (!unhandled_live_ranges().empty()) { |
| 2699 DCHECK(UnhandledIsSorted()); | 2755 DCHECK(UnhandledIsSorted()); |
| 2700 LiveRange* current = unhandled_live_ranges().back(); | 2756 LiveRange* current = unhandled_live_ranges().back(); |
| 2701 unhandled_live_ranges().pop_back(); | 2757 unhandled_live_ranges().pop_back(); |
| 2702 DCHECK(UnhandledIsSorted()); | 2758 DCHECK(UnhandledIsSorted()); |
| 2703 LifetimePosition position = current->Start(); | 2759 LifetimePosition position = current->Start(); |
| 2704 #ifdef DEBUG | 2760 #ifdef DEBUG |
| 2705 allocation_finger_ = position; | 2761 allocation_finger_ = position; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2866 } | 2922 } |
| 2867 | 2923 |
| 2868 | 2924 |
| 2869 void LinearScanAllocator::InactiveToActive(LiveRange* range) { | 2925 void LinearScanAllocator::InactiveToActive(LiveRange* range) { |
| 2870 RemoveElement(&inactive_live_ranges(), range); | 2926 RemoveElement(&inactive_live_ranges(), range); |
| 2871 active_live_ranges().push_back(range); | 2927 active_live_ranges().push_back(range); |
| 2872 TRACE("Moving live range %d:%d from inactive to active\n", | 2928 TRACE("Moving live range %d:%d from inactive to active\n", |
| 2873 range->TopLevel()->vreg(), range->relative_id()); | 2929 range->TopLevel()->vreg(), range->relative_id()); |
| 2874 } | 2930 } |
| 2875 | 2931 |
| 2932 void LinearScanAllocator::GetFPRegisterSet(MachineRepresentation rep, |
| 2933 int* num_regs, int* num_codes, |
| 2934 const int** codes) const { |
| 2935 DCHECK(!kSimpleFPAliasing); |
| 2936 if (rep == MachineRepresentation::kFloat32) { |
| 2937 *num_regs = data()->config()->num_float_registers(); |
| 2938 *num_codes = data()->config()->num_allocatable_float_registers(); |
| 2939 *codes = data()->config()->allocatable_float_codes(); |
| 2940 } else if (rep == MachineRepresentation::kSimd128) { |
| 2941 *num_regs = data()->config()->num_simd128_registers(); |
| 2942 *num_codes = data()->config()->num_allocatable_simd128_registers(); |
| 2943 *codes = data()->config()->allocatable_simd128_codes(); |
| 2944 } else { |
| 2945 UNREACHABLE(); |
| 2946 } |
| 2947 } |
| 2948 |
| 2876 void LinearScanAllocator::FindFreeRegistersForRange( | 2949 void LinearScanAllocator::FindFreeRegistersForRange( |
| 2877 LiveRange* range, Vector<LifetimePosition> positions) { | 2950 LiveRange* range, Vector<LifetimePosition> positions) { |
| 2878 int num_regs = num_registers(); | 2951 int num_regs = num_registers(); |
| 2952 int num_codes = num_allocatable_registers(); |
| 2953 const int* codes = allocatable_register_codes(); |
| 2954 MachineRepresentation rep = range->representation(); |
| 2955 if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 || |
| 2956 rep == MachineRepresentation::kSimd128)) |
| 2957 GetFPRegisterSet(rep, &num_regs, &num_codes, &codes); |
| 2879 DCHECK_GE(positions.length(), num_regs); | 2958 DCHECK_GE(positions.length(), num_regs); |
| 2880 | 2959 |
| 2881 for (int i = 0; i < num_regs; i++) { | 2960 for (int i = 0; i < num_regs; i++) { |
| 2882 positions[i] = LifetimePosition::MaxPosition(); | 2961 positions[i] = LifetimePosition::MaxPosition(); |
| 2883 } | 2962 } |
| 2884 | 2963 |
| 2885 for (LiveRange* cur_active : active_live_ranges()) { | 2964 for (LiveRange* cur_active : active_live_ranges()) { |
| 2886 int cur_reg = cur_active->assigned_register(); | 2965 int cur_reg = cur_active->assigned_register(); |
| 2887 positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0); | 2966 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 2888 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg), | 2967 positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0); |
| 2889 LifetimePosition::GapFromInstructionIndex(0).value()); | 2968 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg), |
| 2969 LifetimePosition::GapFromInstructionIndex(0).value()); |
| 2970 } else { |
| 2971 int alias_base_index = -1; |
| 2972 int aliases = data()->config()->GetAliases( |
| 2973 cur_active->representation(), cur_reg, rep, &alias_base_index); |
| 2974 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); |
| 2975 while (aliases--) { |
| 2976 int aliased_reg = alias_base_index + aliases; |
| 2977 positions[aliased_reg] = LifetimePosition::GapFromInstructionIndex(0); |
| 2978 } |
| 2979 } |
| 2890 } | 2980 } |
| 2891 | 2981 |
| 2892 for (LiveRange* cur_inactive : inactive_live_ranges()) { | 2982 for (LiveRange* cur_inactive : inactive_live_ranges()) { |
| 2893 DCHECK(cur_inactive->End() > range->Start()); | 2983 DCHECK(cur_inactive->End() > range->Start()); |
| 2894 LifetimePosition next_intersection = cur_inactive->FirstIntersection(range); | 2984 LifetimePosition next_intersection = cur_inactive->FirstIntersection(range); |
| 2895 if (!next_intersection.IsValid()) continue; | 2985 if (!next_intersection.IsValid()) continue; |
| 2896 int cur_reg = cur_inactive->assigned_register(); | 2986 int cur_reg = cur_inactive->assigned_register(); |
| 2897 positions[cur_reg] = Min(positions[cur_reg], next_intersection); | 2987 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 2898 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), | 2988 positions[cur_reg] = Min(positions[cur_reg], next_intersection); |
| 2899 Min(positions[cur_reg], next_intersection).value()); | 2989 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), |
| 2990 Min(positions[cur_reg], next_intersection).value()); |
| 2991 } else { |
| 2992 int alias_base_index = -1; |
| 2993 int aliases = data()->config()->GetAliases( |
| 2994 cur_inactive->representation(), cur_reg, rep, &alias_base_index); |
| 2995 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); |
| 2996 while (aliases--) { |
| 2997 int aliased_reg = alias_base_index + aliases; |
| 2998 positions[aliased_reg] = Min(positions[aliased_reg], next_intersection); |
| 2999 } |
| 3000 } |
| 2900 } | 3001 } |
| 2901 } | 3002 } |
| 2902 | 3003 |
| 2903 // High-level register allocation summary: | 3004 // High-level register allocation summary: |
| 2904 // | 3005 // |
| 2905 // For regular, or hot (i.e. not splinter) ranges, we attempt to first | 3006 // For regular, or hot (i.e. not splinter) ranges, we attempt to first |
| 2906 // allocate first the preferred (hint) register. If that is not possible, | 3007 // allocate first the preferred (hint) register. If that is not possible, |
| 2907 // we find a register that's free, and allocate that. If that's not possible, | 3008 // we find a register that's free, and allocate that. If that's not possible, |
| 2908 // we search for a register to steal from a range that was allocated. The | 3009 // we search for a register to steal from a range that was allocated. The |
| 2909 // goal is to optimize for throughput by avoiding register-to-memory | 3010 // goal is to optimize for throughput by avoiding register-to-memory |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2970 current->relative_id()); | 3071 current->relative_id()); |
| 2971 SetLiveRangeAssignedRegister(current, hint_register); | 3072 SetLiveRangeAssignedRegister(current, hint_register); |
| 2972 return true; | 3073 return true; |
| 2973 } | 3074 } |
| 2974 } | 3075 } |
| 2975 return false; | 3076 return false; |
| 2976 } | 3077 } |
| 2977 | 3078 |
| 2978 bool LinearScanAllocator::TryAllocateFreeReg( | 3079 bool LinearScanAllocator::TryAllocateFreeReg( |
| 2979 LiveRange* current, const Vector<LifetimePosition>& free_until_pos) { | 3080 LiveRange* current, const Vector<LifetimePosition>& free_until_pos) { |
| 3081 int num_regs = 0; // used only for the call to GetFPRegisterSet. |
| 2980 int num_codes = num_allocatable_registers(); | 3082 int num_codes = num_allocatable_registers(); |
| 2981 const int* codes = allocatable_register_codes(); | 3083 const int* codes = allocatable_register_codes(); |
| 3084 MachineRepresentation rep = current->representation(); |
| 3085 if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 || |
| 3086 rep == MachineRepresentation::kSimd128)) |
| 3087 GetFPRegisterSet(rep, &num_regs, &num_codes, &codes); |
| 3088 |
| 2982 DCHECK_GE(free_until_pos.length(), num_codes); | 3089 DCHECK_GE(free_until_pos.length(), num_codes); |
| 2983 | 3090 |
| 2984 // Find the register which stays free for the longest time. | 3091 // Find the register which stays free for the longest time. |
| 2985 int reg = codes[0]; | 3092 int reg = codes[0]; |
| 2986 for (int i = 1; i < num_codes; ++i) { | 3093 for (int i = 1; i < num_codes; ++i) { |
| 2987 int code = codes[i]; | 3094 int code = codes[i]; |
| 2988 if (free_until_pos[code] > free_until_pos[reg]) { | 3095 if (free_until_pos[code] > free_until_pos[reg]) { |
| 2989 reg = code; | 3096 reg = code; |
| 2990 } | 3097 } |
| 2991 } | 3098 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3019 if (register_use == nullptr) { | 3126 if (register_use == nullptr) { |
| 3020 // There is no use in the current live range that requires a register. | 3127 // There is no use in the current live range that requires a register. |
| 3021 // We can just spill it. | 3128 // We can just spill it. |
| 3022 Spill(current); | 3129 Spill(current); |
| 3023 return; | 3130 return; |
| 3024 } | 3131 } |
| 3025 | 3132 |
| 3026 int num_regs = num_registers(); | 3133 int num_regs = num_registers(); |
| 3027 int num_codes = num_allocatable_registers(); | 3134 int num_codes = num_allocatable_registers(); |
| 3028 const int* codes = allocatable_register_codes(); | 3135 const int* codes = allocatable_register_codes(); |
| 3136 MachineRepresentation rep = current->representation(); |
| 3137 if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 || |
| 3138 rep == MachineRepresentation::kSimd128)) |
| 3139 GetFPRegisterSet(rep, &num_regs, &num_codes, &codes); |
| 3029 | 3140 |
| 3030 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters]; | 3141 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters]; |
| 3031 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters]; | 3142 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters]; |
| 3032 for (int i = 0; i < num_regs; i++) { | 3143 for (int i = 0; i < num_regs; i++) { |
| 3033 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 3144 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); |
| 3034 } | 3145 } |
| 3035 | 3146 |
| 3036 for (LiveRange* range : active_live_ranges()) { | 3147 for (LiveRange* range : active_live_ranges()) { |
| 3037 int cur_reg = range->assigned_register(); | 3148 int cur_reg = range->assigned_register(); |
| 3038 bool is_fixed_or_cant_spill = | 3149 bool is_fixed_or_cant_spill = |
| 3039 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start()); | 3150 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start()); |
| 3040 if (is_fixed_or_cant_spill) { | 3151 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 3041 block_pos[cur_reg] = use_pos[cur_reg] = | 3152 if (is_fixed_or_cant_spill) { |
| 3042 LifetimePosition::GapFromInstructionIndex(0); | 3153 block_pos[cur_reg] = use_pos[cur_reg] = |
| 3154 LifetimePosition::GapFromInstructionIndex(0); |
| 3155 } else { |
| 3156 use_pos[cur_reg] = |
| 3157 range->NextLifetimePositionRegisterIsBeneficial(current->Start()); |
| 3158 } |
| 3043 } else { | 3159 } else { |
| 3044 UsePosition* next_use = | 3160 int alias_base_index = -1; |
| 3045 range->NextUsePositionRegisterIsBeneficial(current->Start()); | 3161 int aliases = data()->config()->GetAliases( |
| 3046 if (next_use == nullptr) { | 3162 range->representation(), cur_reg, rep, &alias_base_index); |
| 3047 use_pos[cur_reg] = range->End(); | 3163 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); |
| 3048 } else { | 3164 while (aliases--) { |
| 3049 use_pos[cur_reg] = next_use->pos(); | 3165 int aliased_reg = alias_base_index + aliases; |
| 3166 if (is_fixed_or_cant_spill) { |
| 3167 block_pos[aliased_reg] = use_pos[aliased_reg] = |
| 3168 LifetimePosition::GapFromInstructionIndex(0); |
| 3169 } else { |
| 3170 use_pos[aliased_reg] = |
| 3171 range->NextLifetimePositionRegisterIsBeneficial(current->Start()); |
| 3172 } |
| 3050 } | 3173 } |
| 3051 } | 3174 } |
| 3052 } | 3175 } |
| 3053 | 3176 |
| 3054 for (LiveRange* range : inactive_live_ranges()) { | 3177 for (LiveRange* range : inactive_live_ranges()) { |
| 3055 DCHECK(range->End() > current->Start()); | 3178 DCHECK(range->End() > current->Start()); |
| 3056 LifetimePosition next_intersection = range->FirstIntersection(current); | 3179 LifetimePosition next_intersection = range->FirstIntersection(current); |
| 3057 if (!next_intersection.IsValid()) continue; | 3180 if (!next_intersection.IsValid()) continue; |
| 3058 int cur_reg = range->assigned_register(); | 3181 int cur_reg = range->assigned_register(); |
| 3059 bool is_fixed = range->TopLevel()->IsFixed(); | 3182 bool is_fixed = range->TopLevel()->IsFixed(); |
| 3060 if (is_fixed) { | 3183 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 3061 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); | 3184 if (is_fixed) { |
| 3062 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); | 3185 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); |
| 3186 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); |
| 3187 } else { |
| 3188 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); |
| 3189 } |
| 3063 } else { | 3190 } else { |
| 3064 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); | 3191 int alias_base_index = -1; |
| 3192 int aliases = data()->config()->GetAliases( |
| 3193 range->representation(), cur_reg, rep, &alias_base_index); |
| 3194 DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1)); |
| 3195 while (aliases--) { |
| 3196 int aliased_reg = alias_base_index + aliases; |
| 3197 if (is_fixed) { |
| 3198 block_pos[aliased_reg] = |
| 3199 Min(block_pos[aliased_reg], next_intersection); |
| 3200 use_pos[aliased_reg] = |
| 3201 Min(block_pos[aliased_reg], use_pos[aliased_reg]); |
| 3202 } else { |
| 3203 use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection); |
| 3204 } |
| 3205 } |
| 3065 } | 3206 } |
| 3066 } | 3207 } |
| 3067 | 3208 |
| 3068 int reg = codes[0]; | 3209 int reg = codes[0]; |
| 3069 for (int i = 1; i < num_codes; ++i) { | 3210 for (int i = 1; i < num_codes; ++i) { |
| 3070 int code = codes[i]; | 3211 int code = codes[i]; |
| 3071 if (use_pos[code] > use_pos[reg]) { | 3212 if (use_pos[code] > use_pos[reg]) { |
| 3072 reg = code; | 3213 reg = code; |
| 3073 } | 3214 } |
| 3074 } | 3215 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3106 SplitAndSpillIntersecting(current); | 3247 SplitAndSpillIntersecting(current); |
| 3107 } | 3248 } |
| 3108 | 3249 |
| 3109 | 3250 |
| 3110 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { | 3251 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { |
| 3111 DCHECK(current->HasRegisterAssigned()); | 3252 DCHECK(current->HasRegisterAssigned()); |
| 3112 int reg = current->assigned_register(); | 3253 int reg = current->assigned_register(); |
| 3113 LifetimePosition split_pos = current->Start(); | 3254 LifetimePosition split_pos = current->Start(); |
| 3114 for (size_t i = 0; i < active_live_ranges().size(); ++i) { | 3255 for (size_t i = 0; i < active_live_ranges().size(); ++i) { |
| 3115 LiveRange* range = active_live_ranges()[i]; | 3256 LiveRange* range = active_live_ranges()[i]; |
| 3116 if (range->assigned_register() != reg) continue; | 3257 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 3258 if (range->assigned_register() != reg) continue; |
| 3259 } else { |
| 3260 if (!data()->config()->AreAliases(current->representation(), reg, |
| 3261 range->representation(), |
| 3262 range->assigned_register())) { |
| 3263 continue; |
| 3264 } |
| 3265 } |
| 3117 | 3266 |
| 3118 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); | 3267 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); |
| 3119 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); | 3268 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); |
| 3120 if (next_pos == nullptr) { | 3269 if (next_pos == nullptr) { |
| 3121 SpillAfter(range, spill_pos); | 3270 SpillAfter(range, spill_pos); |
| 3122 } else { | 3271 } else { |
| 3123 // When spilling between spill_pos and next_pos ensure that the range | 3272 // When spilling between spill_pos and next_pos ensure that the range |
| 3124 // remains spilled at least until the start of the current live range. | 3273 // remains spilled at least until the start of the current live range. |
| 3125 // This guarantees that we will not introduce new unhandled ranges that | 3274 // This guarantees that we will not introduce new unhandled ranges that |
| 3126 // start before the current range as this violates allocation invariants | 3275 // start before the current range as this violates allocation invariants |
| 3127 // and will lead to an inconsistent state of active and inactive | 3276 // and will lead to an inconsistent state of active and inactive |
| 3128 // live-ranges: ranges are allocated in order of their start positions, | 3277 // live-ranges: ranges are allocated in order of their start positions, |
| 3129 // ranges are retired from active/inactive when the start of the | 3278 // ranges are retired from active/inactive when the start of the |
| 3130 // current live-range is larger than their end. | 3279 // current live-range is larger than their end. |
| 3131 DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(), | 3280 DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(), |
| 3132 next_pos->pos())); | 3281 next_pos->pos())); |
| 3133 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); | 3282 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); |
| 3134 } | 3283 } |
| 3135 ActiveToHandled(range); | 3284 ActiveToHandled(range); |
| 3136 --i; | 3285 --i; |
| 3137 } | 3286 } |
| 3138 | 3287 |
| 3139 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { | 3288 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { |
| 3140 LiveRange* range = inactive_live_ranges()[i]; | 3289 LiveRange* range = inactive_live_ranges()[i]; |
| 3141 DCHECK(range->End() > current->Start()); | 3290 DCHECK(range->End() > current->Start()); |
| 3142 if (range->TopLevel()->IsFixed()) continue; | 3291 if (range->TopLevel()->IsFixed()) continue; |
| 3143 if (range->assigned_register() != reg) continue; | 3292 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 3293 if (range->assigned_register() != reg) continue; |
| 3294 } else { |
| 3295 if (!data()->config()->AreAliases(current->representation(), reg, |
| 3296 range->representation(), |
| 3297 range->assigned_register())) |
| 3298 continue; |
| 3299 } |
| 3144 | 3300 |
| 3145 LifetimePosition next_intersection = range->FirstIntersection(current); | 3301 LifetimePosition next_intersection = range->FirstIntersection(current); |
| 3146 if (next_intersection.IsValid()) { | 3302 if (next_intersection.IsValid()) { |
| 3147 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); | 3303 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); |
| 3148 if (next_pos == nullptr) { | 3304 if (next_pos == nullptr) { |
| 3149 SpillAfter(range, split_pos); | 3305 SpillAfter(range, split_pos); |
| 3150 } else { | 3306 } else { |
| 3151 next_intersection = Min(next_intersection, next_pos->pos()); | 3307 next_intersection = Min(next_intersection, next_pos->pos()); |
| 3152 SpillBetween(range, split_pos, next_intersection); | 3308 SpillBetween(range, split_pos, next_intersection); |
| 3153 } | 3309 } |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3624 DCHECK(!code() | 3780 DCHECK(!code() |
| 3625 ->InstructionAt(pred->last_instruction_index()) | 3781 ->InstructionAt(pred->last_instruction_index()) |
| 3626 ->HasReferenceMap()); | 3782 ->HasReferenceMap()); |
| 3627 gap_index = pred->last_instruction_index(); | 3783 gap_index = pred->last_instruction_index(); |
| 3628 position = Instruction::END; | 3784 position = Instruction::END; |
| 3629 } | 3785 } |
| 3630 data()->AddGapMove(gap_index, position, pred_op, cur_op); | 3786 data()->AddGapMove(gap_index, position, pred_op, cur_op); |
| 3631 return gap_index; | 3787 return gap_index; |
| 3632 } | 3788 } |
| 3633 | 3789 |
| 3634 | |
| 3635 void LiveRangeConnector::ConnectRanges(Zone* local_zone) { | 3790 void LiveRangeConnector::ConnectRanges(Zone* local_zone) { |
| 3636 DelayedInsertionMap delayed_insertion_map(local_zone); | 3791 DelayedInsertionMap delayed_insertion_map(local_zone); |
| 3637 for (TopLevelLiveRange* top_range : data()->live_ranges()) { | 3792 for (TopLevelLiveRange* top_range : data()->live_ranges()) { |
| 3638 if (top_range == nullptr) continue; | 3793 if (top_range == nullptr) continue; |
| 3639 bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks(); | 3794 bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks(); |
| 3640 LiveRange* first_range = top_range; | 3795 LiveRange* first_range = top_range; |
| 3641 for (LiveRange *second_range = first_range->next(); second_range != nullptr; | 3796 for (LiveRange *second_range = first_range->next(); second_range != nullptr; |
| 3642 first_range = second_range, second_range = second_range->next()) { | 3797 first_range = second_range, second_range = second_range->next()) { |
| 3643 LifetimePosition pos = second_range->Start(); | 3798 LifetimePosition pos = second_range->Start(); |
| 3644 // Add gap move if the two live ranges touch and there is no block | 3799 // 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... |
| 3712 } | 3867 } |
| 3713 if (done) break; | 3868 if (done) break; |
| 3714 // Reset state. | 3869 // Reset state. |
| 3715 to_eliminate.clear(); | 3870 to_eliminate.clear(); |
| 3716 to_insert.clear(); | 3871 to_insert.clear(); |
| 3717 moves = it->first.first; | 3872 moves = it->first.first; |
| 3718 } | 3873 } |
| 3719 // Gather all MoveOperands for a single ParallelMove. | 3874 // Gather all MoveOperands for a single ParallelMove. |
| 3720 MoveOperands* move = | 3875 MoveOperands* move = |
| 3721 new (code_zone()) MoveOperands(it->first.second, it->second); | 3876 new (code_zone()) MoveOperands(it->first.second, it->second); |
| 3722 MoveOperands* eliminate = moves->PrepareInsertAfter(move); | 3877 moves->PrepareInsertAfter(move, &to_eliminate); |
| 3723 to_insert.push_back(move); | 3878 to_insert.push_back(move); |
| 3724 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | |
| 3725 } | 3879 } |
| 3726 } | 3880 } |
| 3727 | 3881 |
| 3728 | 3882 |
| 3729 void LiveRangeConnector::CommitSpillsInDeferredBlocks( | 3883 void LiveRangeConnector::CommitSpillsInDeferredBlocks( |
| 3730 TopLevelLiveRange* range, LiveRangeBoundArray* array, Zone* temp_zone) { | 3884 TopLevelLiveRange* range, LiveRangeBoundArray* array, Zone* temp_zone) { |
| 3731 DCHECK(range->IsSpilledOnlyInDeferredBlocks()); | 3885 DCHECK(range->IsSpilledOnlyInDeferredBlocks()); |
| 3732 DCHECK(!range->spilled()); | 3886 DCHECK(!range->spilled()); |
| 3733 | 3887 |
| 3734 InstructionSequence* code = data()->code(); | 3888 InstructionSequence* code = data()->code(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3796 } | 3950 } |
| 3797 } | 3951 } |
| 3798 } | 3952 } |
| 3799 } | 3953 } |
| 3800 } | 3954 } |
| 3801 | 3955 |
| 3802 | 3956 |
| 3803 } // namespace compiler | 3957 } // namespace compiler |
| 3804 } // namespace internal | 3958 } // namespace internal |
| 3805 } // namespace v8 | 3959 } // namespace v8 |
| OLD | NEW |