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

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

Issue 2086653003: [Turbofan] Add the concept of aliasing to RegisterConfiguration. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix inactive live range population. Created 4 years, 6 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
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_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 10 matching lines...) Expand all
57 LifetimePosition pos) { 57 LifetimePosition pos) {
58 return code->GetInstructionBlock(pos.ToInstructionIndex()); 58 return code->GetInstructionBlock(pos.ToInstructionIndex());
59 } 59 }
60 60
61 61
62 Instruction* GetLastInstruction(InstructionSequence* code, 62 Instruction* GetLastInstruction(InstructionSequence* code,
63 const InstructionBlock* block) { 63 const InstructionBlock* block) {
64 return code->InstructionAt(block->last_instruction_index()); 64 return code->InstructionAt(block->last_instruction_index());
65 } 65 }
66 66
67 67 bool IsOutputRegisterOf(Instruction* instr, int code) {
68 bool IsOutputRegisterOf(Instruction* instr, Register reg) {
69 for (size_t i = 0; i < instr->OutputCount(); i++) { 68 for (size_t i = 0; i < instr->OutputCount(); i++) {
70 InstructionOperand* output = instr->OutputAt(i); 69 InstructionOperand* output = instr->OutputAt(i);
71 if (output->IsRegister() && 70 if (output->IsRegister() &&
72 LocationOperand::cast(output)->GetRegister().is(reg)) { 71 LocationOperand::cast(output)->register_code() == code) {
73 return true; 72 return true;
74 } 73 }
75 } 74 }
76 return false; 75 return false;
77 } 76 }
78 77
79 78 bool IsOutputFPRegisterOf(Instruction* instr, MachineRepresentation rep,
80 bool IsOutputDoubleRegisterOf(Instruction* instr, DoubleRegister reg) { 79 int code) {
81 for (size_t i = 0; i < instr->OutputCount(); i++) { 80 for (size_t i = 0; i < instr->OutputCount(); i++) {
82 InstructionOperand* output = instr->OutputAt(i); 81 InstructionOperand* output = instr->OutputAt(i);
83 if (output->IsFPRegister() && 82 if (output->IsFPRegister()) {
84 LocationOperand::cast(output)->GetDoubleRegister().is(reg)) { 83 const LocationOperand* op = LocationOperand::cast(output);
85 return true; 84 const RegisterConfiguration* config =
85 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
86 if (config->fp_aliasing_kind() != RegisterConfiguration::COMBINE) {
87 if (op->register_code() == code) return true;
88 } else {
89 if (config->AreAliases(op->representation(), op->register_code(), rep,
90 code)) {
91 return true;
92 }
93 }
86 } 94 }
87 } 95 }
88 return false; 96 return false;
89 } 97 }
90 98
91 99
92 // TODO(dcarney): fix frame to allow frame accesses to half size location. 100 // TODO(dcarney): fix frame to allow frame accesses to half size location.
93 int GetByteWidth(MachineRepresentation rep) { 101 int GetByteWidth(MachineRepresentation rep) {
94 switch (rep) { 102 switch (rep) {
95 case MachineRepresentation::kBit: 103 case MachineRepresentation::kBit:
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 node = new_node; 1255 node = new_node;
1248 src = src->next(); 1256 src = src->next();
1249 } 1257 }
1250 } 1258 }
1251 use_interval_ = result; 1259 use_interval_ = result;
1252 live_ranges().push_back(parent); 1260 live_ranges().push_back(parent);
1253 end_position_ = node->end(); 1261 end_position_ = node->end();
1254 parent->SetSpillRange(this); 1262 parent->SetSpillRange(this);
1255 } 1263 }
1256 1264
1257
1258 int SpillRange::ByteWidth() const {
1259 return GetByteWidth(live_ranges_[0]->representation());
1260 }
1261
1262
1263 bool SpillRange::IsIntersectingWith(SpillRange* other) const { 1265 bool SpillRange::IsIntersectingWith(SpillRange* other) const {
1264 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || 1266 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
1265 this->End() <= other->use_interval_->start() || 1267 this->End() <= other->use_interval_->start() ||
1266 other->End() <= this->use_interval_->start()) { 1268 other->End() <= this->use_interval_->start()) {
1267 return false; 1269 return false;
1268 } 1270 }
1269 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); 1271 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
1270 } 1272 }
1271 1273
1272 1274
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 } 1357 }
1356 1358
1357 1359
1358 void RegisterAllocationData::PhiMapValue::CommitAssignment( 1360 void RegisterAllocationData::PhiMapValue::CommitAssignment(
1359 const InstructionOperand& assigned) { 1361 const InstructionOperand& assigned) {
1360 for (InstructionOperand* operand : incoming_operands_) { 1362 for (InstructionOperand* operand : incoming_operands_) {
1361 InstructionOperand::ReplaceWith(operand, &assigned); 1363 InstructionOperand::ReplaceWith(operand, &assigned);
1362 } 1364 }
1363 } 1365 }
1364 1366
1365
1366 RegisterAllocationData::RegisterAllocationData( 1367 RegisterAllocationData::RegisterAllocationData(
1367 const RegisterConfiguration* config, Zone* zone, Frame* frame, 1368 const RegisterConfiguration* config, Zone* zone, Frame* frame,
1368 InstructionSequence* code, const char* debug_name) 1369 InstructionSequence* code, const char* debug_name)
1369 : allocation_zone_(zone), 1370 : allocation_zone_(zone),
1370 frame_(frame), 1371 frame_(frame),
1371 code_(code), 1372 code_(code),
1372 debug_name_(debug_name), 1373 debug_name_(debug_name),
1373 config_(config), 1374 config_(config),
1374 phi_map_(allocation_zone()), 1375 phi_map_(allocation_zone()),
1375 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), 1376 live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1376 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), 1377 live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1377 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, 1378 live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
1378 allocation_zone()), 1379 allocation_zone()),
1379 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, 1380 fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
1380 allocation_zone()), 1381 allocation_zone()),
1382 fixed_float_live_ranges_(this->config()->num_float_registers(), nullptr,
1383 allocation_zone()),
1381 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, 1384 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
1382 allocation_zone()), 1385 allocation_zone()),
1383 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()), 1386 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
1384 delayed_references_(allocation_zone()), 1387 delayed_references_(allocation_zone()),
1385 assigned_registers_(nullptr), 1388 assigned_registers_(nullptr),
1386 assigned_double_registers_(nullptr), 1389 assigned_double_registers_(nullptr),
1387 virtual_register_count_(code->VirtualRegisterCount()), 1390 virtual_register_count_(code->VirtualRegisterCount()),
1388 preassigned_slot_ranges_(zone) { 1391 preassigned_slot_ranges_(zone) {
1389 assigned_registers_ = new (code_zone()) 1392 assigned_registers_ = new (code_zone())
1390 BitVector(this->config()->num_general_registers(), code_zone()); 1393 BitVector(this->config()->num_general_registers(), code_zone());
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 1549
1547 SpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange( 1550 SpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange(
1548 TopLevelLiveRange* range) { 1551 TopLevelLiveRange* range) {
1549 DCHECK(!range->HasSpillOperand()); 1552 DCHECK(!range->HasSpillOperand());
1550 DCHECK(!range->IsSplinter()); 1553 DCHECK(!range->IsSplinter());
1551 SpillRange* spill_range = 1554 SpillRange* spill_range =
1552 new (allocation_zone()) SpillRange(range, allocation_zone()); 1555 new (allocation_zone()) SpillRange(range, allocation_zone());
1553 return spill_range; 1556 return spill_range;
1554 } 1557 }
1555 1558
1556 1559 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep,
1557 void RegisterAllocationData::MarkAllocated(RegisterKind kind, int index) { 1560 int index) {
1558 if (kind == FP_REGISTERS) { 1561 switch (rep) {
1559 assigned_double_registers_->Add(index); 1562 case MachineRepresentation::kFloat32:
1560 } else { 1563 if (config()->fp_aliasing_kind() == RegisterConfiguration::COMBINE) {
1561 DCHECK(kind == GENERAL_REGISTERS); 1564 int alias_base_index;
1562 assigned_registers_->Add(index); 1565 int aliases = config()->GetAliases(
1566 rep, index, MachineRepresentation::kFloat64, &alias_base_index);
1567 while (aliases--) {
1568 int aliased_reg = alias_base_index + aliases;
1569 assigned_double_registers_->Add(aliased_reg);
1570 }
1571 }
1572 break;
1573 case MachineRepresentation::kFloat64:
1574 assigned_double_registers_->Add(index);
1575 break;
1576 default:
1577 DCHECK(!IsFloatingPoint(rep));
1578 assigned_registers_->Add(index);
1579 break;
1563 } 1580 }
1564 } 1581 }
1565 1582
1566
1567 bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const { 1583 bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const {
1568 return pos.IsFullStart() && 1584 return pos.IsFullStart() &&
1569 code()->GetInstructionBlock(pos.ToInstructionIndex())->code_start() == 1585 code()->GetInstructionBlock(pos.ToInstructionIndex())->code_start() ==
1570 pos.ToInstructionIndex(); 1586 pos.ToInstructionIndex();
1571 } 1587 }
1572 1588
1573 1589
1574 ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data) 1590 ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
1575 : data_(data) {} 1591 : data_(data) {}
1576 1592
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 .NextStart(); 1886 .NextStart();
1871 BitVector::Iterator iterator(live_out); 1887 BitVector::Iterator iterator(live_out);
1872 while (!iterator.Done()) { 1888 while (!iterator.Done()) {
1873 int operand_index = iterator.Current(); 1889 int operand_index = iterator.Current();
1874 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index); 1890 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
1875 range->AddUseInterval(start, end, allocation_zone()); 1891 range->AddUseInterval(start, end, allocation_zone());
1876 iterator.Advance(); 1892 iterator.Advance();
1877 } 1893 }
1878 } 1894 }
1879 1895
1880 1896 int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) {
1881 int LiveRangeBuilder::FixedDoubleLiveRangeID(int index) { 1897 switch (rep) {
1882 return -index - 1 - config()->num_general_registers(); 1898 case MachineRepresentation::kFloat32:
1899 return -index - 1 - config()->num_general_registers();
1900 case MachineRepresentation::kFloat64:
1901 return -index - 1 - config()->num_general_registers() -
1902 config()->num_float_registers();
1903 default:
1904 break;
1905 }
1906 UNREACHABLE();
1907 return 0;
1883 } 1908 }
1884 1909
1885
1886 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) { 1910 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
1887 DCHECK(index < config()->num_general_registers()); 1911 DCHECK(index < config()->num_general_registers());
1888 TopLevelLiveRange* result = data()->fixed_live_ranges()[index]; 1912 TopLevelLiveRange* result = data()->fixed_live_ranges()[index];
1889 if (result == nullptr) { 1913 if (result == nullptr) {
1890 result = data()->NewLiveRange(FixedLiveRangeID(index), 1914 MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
1891 InstructionSequence::DefaultRepresentation()); 1915 result = data()->NewLiveRange(FixedLiveRangeID(index), rep);
1892 DCHECK(result->IsFixed()); 1916 DCHECK(result->IsFixed());
1893 result->set_assigned_register(index); 1917 result->set_assigned_register(index);
1894 data()->MarkAllocated(GENERAL_REGISTERS, index); 1918 data()->MarkAllocated(rep, index);
1895 data()->fixed_live_ranges()[index] = result; 1919 data()->fixed_live_ranges()[index] = result;
1896 } 1920 }
1897 return result; 1921 return result;
1898 } 1922 }
1899 1923
1900 1924 TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor(
1901 TopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) { 1925 int index, MachineRepresentation rep) {
1902 DCHECK(index < config()->num_double_registers()); 1926 TopLevelLiveRange* result = nullptr;
1903 TopLevelLiveRange* result = data()->fixed_double_live_ranges()[index]; 1927 if (rep == MachineRepresentation::kFloat64) {
1904 if (result == nullptr) { 1928 DCHECK(index < config()->num_double_registers());
1905 result = data()->NewLiveRange(FixedDoubleLiveRangeID(index), 1929 result = data()->fixed_double_live_ranges()[index];
1906 MachineRepresentation::kFloat64); 1930 if (result == nullptr) {
1907 DCHECK(result->IsFixed()); 1931 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
1908 result->set_assigned_register(index); 1932 DCHECK(result->IsFixed());
1909 data()->MarkAllocated(FP_REGISTERS, index); 1933 result->set_assigned_register(index);
1910 data()->fixed_double_live_ranges()[index] = result; 1934 data()->MarkAllocated(rep, index);
1935 data()->fixed_double_live_ranges()[index] = result;
1936 }
1937 } else {
1938 DCHECK(rep == MachineRepresentation::kFloat32);
1939 DCHECK(index < config()->num_float_registers());
1940 result = data()->fixed_float_live_ranges()[index];
1941 if (result == nullptr) {
1942 result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
1943 DCHECK(result->IsFixed());
1944 result->set_assigned_register(index);
1945 data()->MarkAllocated(rep, index);
1946 data()->fixed_float_live_ranges()[index] = result;
1947 }
1911 } 1948 }
1912 return result; 1949 return result;
1913 } 1950 }
1914 1951
1915
1916 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { 1952 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
1917 if (operand->IsUnallocated()) { 1953 if (operand->IsUnallocated()) {
1918 return data()->GetOrCreateLiveRangeFor( 1954 return data()->GetOrCreateLiveRangeFor(
1919 UnallocatedOperand::cast(operand)->virtual_register()); 1955 UnallocatedOperand::cast(operand)->virtual_register());
1920 } else if (operand->IsConstant()) { 1956 } else if (operand->IsConstant()) {
1921 return data()->GetOrCreateLiveRangeFor( 1957 return data()->GetOrCreateLiveRangeFor(
1922 ConstantOperand::cast(operand)->virtual_register()); 1958 ConstantOperand::cast(operand)->virtual_register());
1923 } else if (operand->IsRegister()) { 1959 } else if (operand->IsRegister()) {
1924 return FixedLiveRangeFor( 1960 return FixedLiveRangeFor(
1925 LocationOperand::cast(operand)->GetRegister().code()); 1961 LocationOperand::cast(operand)->GetRegister().code());
1926 } else if (operand->IsFPRegister()) { 1962 } else if (operand->IsFPRegister()) {
1927 return FixedDoubleLiveRangeFor( 1963 LocationOperand* op = LocationOperand::cast(operand);
1928 LocationOperand::cast(operand)->GetDoubleRegister().code()); 1964 return FixedFPLiveRangeFor(op->register_code(), op->representation());
1929 } else { 1965 } else {
1930 return nullptr; 1966 return nullptr;
1931 } 1967 }
1932 } 1968 }
1933 1969
1934 1970
1935 UsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos, 1971 UsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos,
1936 InstructionOperand* operand, 1972 InstructionOperand* operand,
1937 void* hint, 1973 void* hint,
1938 UsePositionHintType hint_type) { 1974 UsePositionHintType hint_type) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2014 // the first instruction in the handler? 2050 // the first instruction in the handler?
2015 Define(LifetimePosition::GapFromInstructionIndex(index), output); 2051 Define(LifetimePosition::GapFromInstructionIndex(index), output);
2016 } else { 2052 } else {
2017 Define(curr_position, output); 2053 Define(curr_position, output);
2018 } 2054 }
2019 } 2055 }
2020 2056
2021 if (instr->ClobbersRegisters()) { 2057 if (instr->ClobbersRegisters()) {
2022 for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) { 2058 for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) {
2023 int code = config()->GetAllocatableGeneralCode(i); 2059 int code = config()->GetAllocatableGeneralCode(i);
2024 if (!IsOutputRegisterOf(instr, Register::from_code(code))) { 2060 if (!IsOutputRegisterOf(instr, code)) {
2025 TopLevelLiveRange* range = FixedLiveRangeFor(code); 2061 TopLevelLiveRange* range = FixedLiveRangeFor(code);
2026 range->AddUseInterval(curr_position, curr_position.End(), 2062 range->AddUseInterval(curr_position, curr_position.End(),
2027 allocation_zone()); 2063 allocation_zone());
2028 } 2064 }
2029 } 2065 }
2030 } 2066 }
2031 2067
2032 if (instr->ClobbersDoubleRegisters()) { 2068 if (instr->ClobbersDoubleRegisters()) {
2033 for (int i = 0; i < config()->num_allocatable_aliased_double_registers(); 2069 for (int i = 0; i < config()->num_allocatable_double_registers(); ++i) {
2034 ++i) {
2035 int code = config()->GetAllocatableDoubleCode(i); 2070 int code = config()->GetAllocatableDoubleCode(i);
2036 if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) { 2071 if (!IsOutputFPRegisterOf(instr, MachineRepresentation::kFloat64,
2037 TopLevelLiveRange* range = FixedDoubleLiveRangeFor(code); 2072 code)) {
2073 TopLevelLiveRange* range =
2074 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64);
2038 range->AddUseInterval(curr_position, curr_position.End(), 2075 range->AddUseInterval(curr_position, curr_position.End(),
2039 allocation_zone()); 2076 allocation_zone());
2040 } 2077 }
2078 }
bbudge 2016/06/21 23:09:35 Mircea, I still think I need use positions for fix
Mircea Trofin 2016/06/22 06:07:34 Wouldn't the virtual register that the output gets
bbudge 2016/06/22 20:16:04 In RegisterAllocatorVerifier::VerifyGapMoves, allo
2079 for (int i = 0; i < config()->num_allocatable_float_registers(); ++i) {
2080 int code = config()->GetAllocatableFloatCode(i);
2081 if (!IsOutputFPRegisterOf(instr, MachineRepresentation::kFloat32,
2082 code)) {
2083 TopLevelLiveRange* range =
2084 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32);
2085 range->AddUseInterval(curr_position, curr_position.End(),
2086 allocation_zone());
2087 }
2041 } 2088 }
2042 } 2089 }
2043 2090
2044 for (size_t i = 0; i < instr->InputCount(); i++) { 2091 for (size_t i = 0; i < instr->InputCount(); i++) {
2045 InstructionOperand* input = instr->InputAt(i); 2092 InstructionOperand* input = instr->InputAt(i);
2046 if (input->IsImmediate() || input->IsExplicit()) { 2093 if (input->IsImmediate() || input->IsExplicit()) {
2047 continue; // Ignore immediates and explicitly reserved registers. 2094 continue; // Ignore immediates and explicitly reserved registers.
2048 } 2095 }
2049 LifetimePosition use_pos; 2096 LifetimePosition use_pos;
2050 if (input->IsUnallocated() && 2097 if (input->IsUnallocated() &&
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
2374 } 2421 }
2375 2422
2376 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data, 2423 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
2377 RegisterKind kind) 2424 RegisterKind kind)
2378 : data_(data), 2425 : data_(data),
2379 mode_(kind), 2426 mode_(kind),
2380 num_registers_(GetRegisterCount(data->config(), kind)), 2427 num_registers_(GetRegisterCount(data->config(), kind)),
2381 num_allocatable_registers_( 2428 num_allocatable_registers_(
2382 GetAllocatableRegisterCount(data->config(), kind)), 2429 GetAllocatableRegisterCount(data->config(), kind)),
2383 allocatable_register_codes_( 2430 allocatable_register_codes_(
2384 GetAllocatableRegisterCodes(data->config(), kind)) {} 2431 GetAllocatableRegisterCodes(data->config(), kind)),
2385 2432 no_combining_(kind != FP_REGISTERS ||
2433 data->config()->fp_aliasing_kind() !=
2434 RegisterConfiguration::COMBINE) {}
2386 2435
2387 LifetimePosition RegisterAllocator::GetSplitPositionForInstruction( 2436 LifetimePosition RegisterAllocator::GetSplitPositionForInstruction(
2388 const LiveRange* range, int instruction_index) { 2437 const LiveRange* range, int instruction_index) {
2389 LifetimePosition ret = LifetimePosition::Invalid(); 2438 LifetimePosition ret = LifetimePosition::Invalid();
2390 2439
2391 ret = LifetimePosition::GapFromInstructionIndex(instruction_index); 2440 ret = LifetimePosition::GapFromInstructionIndex(instruction_index);
2392 if (range->Start() >= ret || ret >= range->End()) { 2441 if (range->Start() >= ret || ret >= range->End()) {
2393 return LifetimePosition::Invalid(); 2442 return LifetimePosition::Invalid();
2394 } 2443 }
2395 return ret; 2444 return ret;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2545 DCHECK(!range->spilled()); 2594 DCHECK(!range->spilled());
2546 TopLevelLiveRange* first = range->TopLevel(); 2595 TopLevelLiveRange* first = range->TopLevel();
2547 TRACE("Spilling live range %d:%d\n", first->vreg(), range->relative_id()); 2596 TRACE("Spilling live range %d:%d\n", first->vreg(), range->relative_id());
2548 2597
2549 if (first->HasNoSpillType()) { 2598 if (first->HasNoSpillType()) {
2550 data()->AssignSpillRangeToLiveRange(first); 2599 data()->AssignSpillRangeToLiveRange(first);
2551 } 2600 }
2552 range->Spill(); 2601 range->Spill();
2553 } 2602 }
2554 2603
2555
2556 const ZoneVector<TopLevelLiveRange*>& RegisterAllocator::GetFixedRegisters()
2557 const {
2558 return mode() == FP_REGISTERS ? data()->fixed_double_live_ranges()
2559 : data()->fixed_live_ranges();
2560 }
2561
2562
2563 const char* RegisterAllocator::RegisterName(int register_code) const { 2604 const char* RegisterAllocator::RegisterName(int register_code) const {
2564 if (mode() == GENERAL_REGISTERS) { 2605 if (mode() == GENERAL_REGISTERS) {
2565 return data()->config()->GetGeneralRegisterName(register_code); 2606 return data()->config()->GetGeneralRegisterName(register_code);
2566 } else { 2607 } else {
2567 return data()->config()->GetDoubleRegisterName(register_code); 2608 return data()->config()->GetDoubleRegisterName(register_code);
2568 } 2609 }
2569 } 2610 }
2570 2611
2571 2612
2572 LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data, 2613 LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
(...skipping 26 matching lines...) Expand all
2599 for (LiveRange* to_add = range; to_add != nullptr; 2640 for (LiveRange* to_add = range; to_add != nullptr;
2600 to_add = to_add->next()) { 2641 to_add = to_add->next()) {
2601 if (!to_add->spilled()) { 2642 if (!to_add->spilled()) {
2602 AddToUnhandledUnsorted(to_add); 2643 AddToUnhandledUnsorted(to_add);
2603 } 2644 }
2604 } 2645 }
2605 } 2646 }
2606 SortUnhandled(); 2647 SortUnhandled();
2607 DCHECK(UnhandledIsSorted()); 2648 DCHECK(UnhandledIsSorted());
2608 2649
2609 auto& fixed_ranges = GetFixedRegisters(); 2650 if (mode() == GENERAL_REGISTERS) {
2610 for (TopLevelLiveRange* current : fixed_ranges) { 2651 for (TopLevelLiveRange* current : data()->fixed_live_ranges()) {
2611 if (current != nullptr) { 2652 if (current != nullptr) AddToInactive(current);
2612 DCHECK_EQ(mode(), current->kind()); 2653 }
2613 AddToInactive(current); 2654 } else {
2655 for (TopLevelLiveRange* current : data()->fixed_float_live_ranges()) {
2656 if (current != nullptr) AddToInactive(current);
2657 }
2658 for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) {
2659 if (current != nullptr) AddToInactive(current);
2614 } 2660 }
2615 } 2661 }
2616 2662
2617 while (!unhandled_live_ranges().empty()) { 2663 while (!unhandled_live_ranges().empty()) {
2618 DCHECK(UnhandledIsSorted()); 2664 DCHECK(UnhandledIsSorted());
2619 LiveRange* current = unhandled_live_ranges().back(); 2665 LiveRange* current = unhandled_live_ranges().back();
2620 unhandled_live_ranges().pop_back(); 2666 unhandled_live_ranges().pop_back();
2621 DCHECK(UnhandledIsSorted()); 2667 DCHECK(UnhandledIsSorted());
2622 LifetimePosition position = current->Start(); 2668 LifetimePosition position = current->Start();
2623 #ifdef DEBUG 2669 #ifdef DEBUG
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2657 if (!result) AllocateBlockedReg(current); 2703 if (!result) AllocateBlockedReg(current);
2658 if (current->HasRegisterAssigned()) { 2704 if (current->HasRegisterAssigned()) {
2659 AddToActive(current); 2705 AddToActive(current);
2660 } 2706 }
2661 } 2707 }
2662 } 2708 }
2663 2709
2664 2710
2665 void LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range, 2711 void LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
2666 int reg) { 2712 int reg) {
2667 data()->MarkAllocated(range->kind(), reg); 2713 data()->MarkAllocated(range->representation(), reg);
2668 range->set_assigned_register(reg); 2714 range->set_assigned_register(reg);
2669 range->SetUseHints(reg); 2715 range->SetUseHints(reg);
2670 if (range->IsTopLevel() && range->TopLevel()->is_phi()) { 2716 if (range->IsTopLevel() && range->TopLevel()->is_phi()) {
2671 data()->GetPhiMapValueFor(range->TopLevel())->set_assigned_register(reg); 2717 data()->GetPhiMapValueFor(range->TopLevel())->set_assigned_register(reg);
2672 } 2718 }
2673 } 2719 }
2674 2720
2675 2721
2676 void LinearScanAllocator::AddToActive(LiveRange* range) { 2722 void LinearScanAllocator::AddToActive(LiveRange* range) {
2677 TRACE("Add live range %d:%d to active\n", range->TopLevel()->vreg(), 2723 TRACE("Add live range %d:%d to active\n", range->TopLevel()->vreg(),
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2771 2817
2772 void LinearScanAllocator::InactiveToActive(LiveRange* range) { 2818 void LinearScanAllocator::InactiveToActive(LiveRange* range) {
2773 RemoveElement(&inactive_live_ranges(), range); 2819 RemoveElement(&inactive_live_ranges(), range);
2774 active_live_ranges().push_back(range); 2820 active_live_ranges().push_back(range);
2775 TRACE("Moving live range %d:%d from inactive to active\n", 2821 TRACE("Moving live range %d:%d from inactive to active\n",
2776 range->TopLevel()->vreg(), range->relative_id()); 2822 range->TopLevel()->vreg(), range->relative_id());
2777 } 2823 }
2778 2824
2779 2825
2780 bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) { 2826 bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
2827 int num_regs = num_registers();
2828 int num_codes = num_allocatable_registers();
2829 const int* codes = allocatable_register_codes();
2830 if (!no_combining() &&
2831 (current->representation() == MachineRepresentation::kFloat32)) {
2832 num_regs = data()->config()->num_float_registers();
2833 num_codes = data()->config()->num_allocatable_float_registers();
2834 codes = data()->config()->allocatable_float_codes();
2835 }
2781 LifetimePosition free_until_pos[RegisterConfiguration::kMaxFPRegisters]; 2836 LifetimePosition free_until_pos[RegisterConfiguration::kMaxFPRegisters];
2782 2837 for (int i = 0; i < num_regs; i++) {
2783 for (int i = 0; i < num_registers(); i++) {
2784 free_until_pos[i] = LifetimePosition::MaxPosition(); 2838 free_until_pos[i] = LifetimePosition::MaxPosition();
2785 } 2839 }
2786 2840
2787 for (LiveRange* cur_active : active_live_ranges()) { 2841 for (LiveRange* cur_active : active_live_ranges()) {
2788 free_until_pos[cur_active->assigned_register()] = 2842 int cur_reg = cur_active->assigned_register();
2789 LifetimePosition::GapFromInstructionIndex(0); 2843 if (no_combining()) {
2790 TRACE("Register %s is free until pos %d (1)\n", 2844 free_until_pos[cur_reg] = LifetimePosition::GapFromInstructionIndex(0);
2791 RegisterName(cur_active->assigned_register()), 2845 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg),
2792 LifetimePosition::GapFromInstructionIndex(0).value()); 2846 LifetimePosition::GapFromInstructionIndex(0).value());
2847 } else {
2848 int alias_base_index;
2849 int aliases = data()->config()->GetAliases(
2850 cur_active->representation(), cur_reg, current->representation(),
2851 &alias_base_index);
2852 while (aliases--) {
2853 int aliased_reg = alias_base_index + aliases;
2854 free_until_pos[aliased_reg] =
2855 LifetimePosition::GapFromInstructionIndex(0);
2856 }
2857 }
2793 } 2858 }
2794 2859
2795 for (LiveRange* cur_inactive : inactive_live_ranges()) { 2860 for (LiveRange* cur_inactive : inactive_live_ranges()) {
2796 DCHECK(cur_inactive->End() > current->Start()); 2861 DCHECK(cur_inactive->End() > current->Start());
2797 LifetimePosition next_intersection = 2862 LifetimePosition next_intersection =
2798 cur_inactive->FirstIntersection(current); 2863 cur_inactive->FirstIntersection(current);
2799 if (!next_intersection.IsValid()) continue; 2864 if (!next_intersection.IsValid()) continue;
2800 int cur_reg = cur_inactive->assigned_register(); 2865 int cur_reg = cur_inactive->assigned_register();
2801 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection); 2866 if (no_combining()) {
2802 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), 2867 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
2803 Min(free_until_pos[cur_reg], next_intersection).value()); 2868 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
2869 Min(free_until_pos[cur_reg], next_intersection).value());
2870 } else {
2871 int alias_base_index;
2872 int aliases = data()->config()->GetAliases(
2873 cur_inactive->representation(), cur_reg, current->representation(),
2874 &alias_base_index);
2875 while (aliases--) {
2876 int aliased_reg = alias_base_index + aliases;
2877 free_until_pos[aliased_reg] =
2878 Min(free_until_pos[aliased_reg], next_intersection);
2879 }
2880 }
2804 } 2881 }
2805 2882
2806 int hint_register; 2883 int hint_register;
2807 if (current->FirstHintPosition(&hint_register) != nullptr) { 2884 if (current->FirstHintPosition(&hint_register) != nullptr) {
2808 TRACE( 2885 TRACE(
2809 "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n", 2886 "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n",
2810 RegisterName(hint_register), free_until_pos[hint_register].value(), 2887 RegisterName(hint_register), free_until_pos[hint_register].value(),
2811 current->TopLevel()->vreg(), current->relative_id(), 2888 current->TopLevel()->vreg(), current->relative_id(),
2812 current->End().value()); 2889 current->End().value());
2813 2890
2814 // The desired register is free until the end of the current live range. 2891 // The desired register is free until the end of the current live range.
2815 if (free_until_pos[hint_register] >= current->End()) { 2892 if (free_until_pos[hint_register] >= current->End()) {
2816 TRACE("Assigning preferred reg %s to live range %d:%d\n", 2893 TRACE("Assigning preferred reg %s to live range %d:%d\n",
2817 RegisterName(hint_register), current->TopLevel()->vreg(), 2894 RegisterName(hint_register), current->TopLevel()->vreg(),
2818 current->relative_id()); 2895 current->relative_id());
2819 SetLiveRangeAssignedRegister(current, hint_register); 2896 SetLiveRangeAssignedRegister(current, hint_register);
2820 return true; 2897 return true;
2821 } 2898 }
2822 } 2899 }
2823 2900
2824 // Find the register which stays free for the longest time. 2901 // Find the register which stays free for the longest time.
2825 int reg = allocatable_register_code(0); 2902 int reg = codes[0];
2826 for (int i = 1; i < num_allocatable_registers(); ++i) { 2903 for (int i = 1; i < num_codes; ++i) {
2827 int code = allocatable_register_code(i); 2904 int code = codes[i];
2828 if (free_until_pos[code] > free_until_pos[reg]) { 2905 if (free_until_pos[code] > free_until_pos[reg]) {
2829 reg = code; 2906 reg = code;
2830 } 2907 }
2831 } 2908 }
2832 2909
2833 LifetimePosition pos = free_until_pos[reg]; 2910 LifetimePosition pos = free_until_pos[reg];
2834 2911
2835 if (pos <= current->Start()) { 2912 if (pos <= current->Start()) {
2836 // All registers are blocked. 2913 // All registers are blocked.
2837 return false; 2914 return false;
2838 } 2915 }
2839 2916
2840 if (pos < current->End()) { 2917 if (pos < current->End()) {
2841 // Register reg is available at the range start but becomes blocked before 2918 // Register reg is available at the range start but becomes blocked before
2842 // the range end. Split current at position where it becomes blocked. 2919 // the range end. Split current at position where it becomes blocked.
2843 LiveRange* tail = SplitRangeAt(current, pos); 2920 LiveRange* tail = SplitRangeAt(current, pos);
2844 AddToUnhandledSorted(tail); 2921 AddToUnhandledSorted(tail);
2845 } 2922 }
2846 2923
2847 // Register reg is available at the range start and is free until 2924 // Register reg is available at the range start and is free until the range
2848 // the range end. 2925 // end.
2849 DCHECK(pos >= current->End()); 2926 DCHECK(pos >= current->End());
2850 TRACE("Assigning free reg %s to live range %d:%d\n", RegisterName(reg), 2927 TRACE("Assigning free reg %s to live range %d:%d\n", RegisterName(reg),
2851 current->TopLevel()->vreg(), current->relative_id()); 2928 current->TopLevel()->vreg(), current->relative_id());
2852 SetLiveRangeAssignedRegister(current, reg); 2929 SetLiveRangeAssignedRegister(current, reg);
2853 2930
2854 return true; 2931 return true;
2855 } 2932 }
2856 2933
2857 2934
2858 void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) { 2935 void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
2859 UsePosition* register_use = current->NextRegisterPosition(current->Start()); 2936 UsePosition* register_use = current->NextRegisterPosition(current->Start());
2860 if (register_use == nullptr) { 2937 if (register_use == nullptr) {
2861 // There is no use in the current live range that requires a register. 2938 // There is no use in the current live range that requires a register.
2862 // We can just spill it. 2939 // We can just spill it.
2863 Spill(current); 2940 Spill(current);
2864 return; 2941 return;
2865 } 2942 }
2866 2943
2944 int num_regs = num_registers();
2945 int num_codes = num_allocatable_registers();
2946 const int* codes = allocatable_register_codes();
2947 if (!no_combining() &&
2948 (current->representation() == MachineRepresentation::kFloat32)) {
2949 num_regs = data()->config()->num_float_registers();
2950 num_codes = data()->config()->num_allocatable_float_registers();
2951 codes = data()->config()->allocatable_float_codes();
2952 }
2953
2867 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters]; 2954 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters];
2868 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters]; 2955 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters];
2869 2956 for (int i = 0; i < num_regs; i++) {
2870 for (int i = 0; i < num_registers(); i++) {
2871 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); 2957 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
2872 } 2958 }
2873 2959
2874 for (LiveRange* range : active_live_ranges()) { 2960 for (LiveRange* range : active_live_ranges()) {
2875 int cur_reg = range->assigned_register(); 2961 int cur_reg = range->assigned_register();
2876 if (range->TopLevel()->IsFixed() || 2962 bool is_fixed_or_cant_spill =
2877 !range->CanBeSpilled(current->Start())) { 2963 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start());
2878 block_pos[cur_reg] = use_pos[cur_reg] = 2964 if (no_combining()) {
2879 LifetimePosition::GapFromInstructionIndex(0); 2965 if (is_fixed_or_cant_spill) {
2966 block_pos[cur_reg] = use_pos[cur_reg] =
2967 LifetimePosition::GapFromInstructionIndex(0);
2968 } else {
2969 UsePosition* next_use =
2970 range->NextUsePositionRegisterIsBeneficial(current->Start());
2971 if (next_use == nullptr) {
2972 use_pos[cur_reg] = range->End();
2973 } else {
2974 use_pos[cur_reg] = next_use->pos();
2975 }
2976 }
2880 } else { 2977 } else {
2881 UsePosition* next_use = 2978 int alias_base_index;
Mircea Trofin 2016/06/22 06:07:34 Could you initialize this?
bbudge 2016/06/22 20:16:04 Done (at all call sites - there are 6)
2882 range->NextUsePositionRegisterIsBeneficial(current->Start()); 2979 int aliases = data()->config()->GetAliases(
2883 if (next_use == nullptr) { 2980 range->representation(), cur_reg, current->representation(),
2884 use_pos[cur_reg] = range->End(); 2981 &alias_base_index);
2885 } else { 2982 while (aliases--) {
2886 use_pos[cur_reg] = next_use->pos(); 2983 int aliased_reg = alias_base_index + aliases;
2984 if (is_fixed_or_cant_spill) {
2985 block_pos[aliased_reg] = use_pos[aliased_reg] =
2986 LifetimePosition::GapFromInstructionIndex(0);
2987 } else {
2988 UsePosition* next_use =
2989 range->NextUsePositionRegisterIsBeneficial(current->Start());
2990 if (next_use == nullptr) {
2991 use_pos[aliased_reg] = range->End();
2992 } else {
2993 use_pos[aliased_reg] = next_use->pos();
2994 }
2995 }
2887 } 2996 }
2888 } 2997 }
2889 } 2998 }
2890 2999
2891 for (LiveRange* range : inactive_live_ranges()) { 3000 for (LiveRange* range : inactive_live_ranges()) {
2892 DCHECK(range->End() > current->Start()); 3001 DCHECK(range->End() > current->Start());
2893 LifetimePosition next_intersection = range->FirstIntersection(current); 3002 LifetimePosition next_intersection = range->FirstIntersection(current);
2894 if (!next_intersection.IsValid()) continue; 3003 if (!next_intersection.IsValid()) continue;
2895 int cur_reg = range->assigned_register(); 3004 int cur_reg = range->assigned_register();
2896 if (range->TopLevel()->IsFixed()) { 3005 bool is_fixed = range->TopLevel()->IsFixed();
2897 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); 3006 if (no_combining()) {
2898 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); 3007 if (is_fixed) {
3008 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
3009 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
3010 } else {
3011 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
3012 }
2899 } else { 3013 } else {
2900 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); 3014 int alias_base_index;
Mircea Trofin 2016/06/22 06:07:34 please initialize
bbudge 2016/06/22 20:16:04 Done.
3015 int aliases = data()->config()->GetAliases(
3016 range->representation(), cur_reg, current->representation(),
3017 &alias_base_index);
3018 while (aliases--) {
3019 int aliased_reg = alias_base_index + aliases;
3020 if (is_fixed) {
3021 block_pos[aliased_reg] =
3022 Min(block_pos[aliased_reg], next_intersection);
3023 use_pos[aliased_reg] =
3024 Min(block_pos[aliased_reg], use_pos[aliased_reg]);
3025 } else {
3026 use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection);
3027 }
3028 }
2901 } 3029 }
2902 } 3030 }
2903 3031
2904 int reg = allocatable_register_code(0); 3032 int reg = codes[0];
2905 for (int i = 1; i < num_allocatable_registers(); ++i) { 3033 for (int i = 1; i < num_codes; ++i) {
2906 int code = allocatable_register_code(i); 3034 int code = codes[i];
2907 if (use_pos[code] > use_pos[reg]) { 3035 if (use_pos[code] > use_pos[reg]) {
2908 reg = code; 3036 reg = code;
2909 } 3037 }
2910 } 3038 }
2911 3039
2912 LifetimePosition pos = use_pos[reg]; 3040 LifetimePosition pos = use_pos[reg];
2913 3041
2914 if (pos < register_use->pos()) { 3042 if (pos < register_use->pos()) {
2915 if (LifetimePosition::ExistsGapPositionBetween(current->Start(), 3043 if (LifetimePosition::ExistsGapPositionBetween(current->Start(),
2916 register_use->pos())) { 3044 register_use->pos())) {
(...skipping 25 matching lines...) Expand all
2942 SplitAndSpillIntersecting(current); 3070 SplitAndSpillIntersecting(current);
2943 } 3071 }
2944 3072
2945 3073
2946 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { 3074 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
2947 DCHECK(current->HasRegisterAssigned()); 3075 DCHECK(current->HasRegisterAssigned());
2948 int reg = current->assigned_register(); 3076 int reg = current->assigned_register();
2949 LifetimePosition split_pos = current->Start(); 3077 LifetimePosition split_pos = current->Start();
2950 for (size_t i = 0; i < active_live_ranges().size(); ++i) { 3078 for (size_t i = 0; i < active_live_ranges().size(); ++i) {
2951 LiveRange* range = active_live_ranges()[i]; 3079 LiveRange* range = active_live_ranges()[i];
2952 if (range->assigned_register() == reg) { 3080 if (no_combining()) {
2953 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 3081 if (range->assigned_register() != reg) continue;
2954 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); 3082 } else {
2955 if (next_pos == nullptr) { 3083 if (!data()->config()->AreAliases(current->representation(), reg,
2956 SpillAfter(range, spill_pos); 3084 range->representation(),
2957 } else { 3085 range->assigned_register())) {
2958 // When spilling between spill_pos and next_pos ensure that the range 3086 continue;
2959 // remains spilled at least until the start of the current live range.
2960 // This guarantees that we will not introduce new unhandled ranges that
2961 // start before the current range as this violates allocation invariant
2962 // and will lead to an inconsistent state of active and inactive
2963 // live-ranges: ranges are allocated in order of their start positions,
2964 // ranges are retired from active/inactive when the start of the
2965 // current live-range is larger than their end.
2966 DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(),
2967 next_pos->pos()));
2968 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
2969 } 3087 }
2970 ActiveToHandled(range);
2971 --i;
2972 } 3088 }
3089
3090 UsePosition* next_pos = range->NextRegisterPosition(current->Start());
3091 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
3092 if (next_pos == nullptr) {
3093 SpillAfter(range, spill_pos);
3094 } else {
3095 // When spilling between spill_pos and next_pos ensure that the range
3096 // remains spilled at least until the start of the current live range.
3097 // This guarantees that we will not introduce new unhandled ranges that
3098 // start before the current range as this violates allocation invariants
3099 // and will lead to an inconsistent state of active and inactive
3100 // live-ranges: ranges are allocated in order of their start positions,
3101 // ranges are retired from active/inactive when the start of the
3102 // current live-range is larger than their end.
3103 DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(),
3104 next_pos->pos()));
3105 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
3106 }
3107 ActiveToHandled(range);
3108 --i;
2973 } 3109 }
2974 3110
2975 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { 3111 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
2976 LiveRange* range = inactive_live_ranges()[i]; 3112 LiveRange* range = inactive_live_ranges()[i];
2977 DCHECK(range->End() > current->Start()); 3113 DCHECK(range->End() > current->Start());
2978 if (range->assigned_register() == reg && !range->TopLevel()->IsFixed()) { 3114 if (range->TopLevel()->IsFixed()) continue;
2979 LifetimePosition next_intersection = range->FirstIntersection(current); 3115 if (no_combining()) {
2980 if (next_intersection.IsValid()) { 3116 if (range->assigned_register() != reg) continue;
2981 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 3117 } else {
2982 if (next_pos == nullptr) { 3118 if (!data()->config()->AreAliases(current->representation(), reg,
2983 SpillAfter(range, split_pos); 3119 range->representation(),
2984 } else { 3120 range->assigned_register()))
2985 next_intersection = Min(next_intersection, next_pos->pos()); 3121 continue;
2986 SpillBetween(range, split_pos, next_intersection); 3122 }
2987 } 3123
2988 InactiveToHandled(range); 3124 LifetimePosition next_intersection = range->FirstIntersection(current);
2989 --i; 3125 if (next_intersection.IsValid()) {
3126 UsePosition* next_pos = range->NextRegisterPosition(current->Start());
3127 if (next_pos == nullptr) {
3128 SpillAfter(range, split_pos);
3129 } else {
3130 next_intersection = Min(next_intersection, next_pos->pos());
3131 SpillBetween(range, split_pos, next_intersection);
2990 } 3132 }
3133 InactiveToHandled(range);
3134 --i;
2991 } 3135 }
2992 } 3136 }
2993 } 3137 }
2994 3138
2995 3139
2996 bool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) { 3140 bool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) {
2997 if (!range->is_phi()) return false; 3141 if (!range->is_phi()) return false;
2998 3142
2999 DCHECK(!range->HasSpillOperand()); 3143 DCHECK(!range->HasSpillOperand());
3000 RegisterAllocationData::PhiMapValue* phi_map_value = 3144 RegisterAllocationData::PhiMapValue* phi_map_value =
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3160 if (other != nullptr && !other->IsEmpty()) { 3304 if (other != nullptr && !other->IsEmpty()) {
3161 range->TryMerge(other); 3305 range->TryMerge(other);
3162 } 3306 }
3163 } 3307 }
3164 } 3308 }
3165 // Allocate slots for the merged spill ranges. 3309 // Allocate slots for the merged spill ranges.
3166 for (SpillRange* range : spill_ranges) { 3310 for (SpillRange* range : spill_ranges) {
3167 if (range == nullptr || range->IsEmpty()) continue; 3311 if (range == nullptr || range->IsEmpty()) continue;
3168 // Allocate a new operand referring to the spill slot. 3312 // Allocate a new operand referring to the spill slot.
3169 if (!range->HasSlot()) { 3313 if (!range->HasSlot()) {
3170 int byte_width = range->ByteWidth(); 3314 int index = data()->frame()->AllocateSpillSlot(range->byte_width());
3171 int index = data()->frame()->AllocateSpillSlot(byte_width);
3172 range->set_assigned_slot(index); 3315 range->set_assigned_slot(index);
3173 } 3316 }
3174 } 3317 }
3175 } 3318 }
3176 3319
3177 3320
3178 void OperandAssigner::CommitAssignment() { 3321 void OperandAssigner::CommitAssignment() {
3179 for (TopLevelLiveRange* top_range : data()->live_ranges()) { 3322 for (TopLevelLiveRange* top_range : data()->live_ranges()) {
3180 if (top_range == nullptr || top_range->IsEmpty()) continue; 3323 if (top_range == nullptr || top_range->IsEmpty()) continue;
3181 InstructionOperand spill_operand; 3324 InstructionOperand spill_operand;
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
3632 } 3775 }
3633 } 3776 }
3634 } 3777 }
3635 } 3778 }
3636 } 3779 }
3637 3780
3638 3781
3639 } // namespace compiler 3782 } // namespace compiler
3640 } // namespace internal 3783 } // namespace internal
3641 } // namespace v8 3784 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698