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

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

Powered by Google App Engine
This is Rietveld 408576698