Index: src/compiler/register-allocator.cc |
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc |
index 840c13b1a779aacef537cdd85e94949feaed8a9f..9fcb51d5adf852fd0aaab2065ab8eac94c422aca 100644 |
--- a/src/compiler/register-allocator.cc |
+++ b/src/compiler/register-allocator.cc |
@@ -27,11 +27,26 @@ void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) { |
int GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) { |
- return kind == DOUBLE_REGISTERS ? cfg->num_aliased_double_registers() |
+ return kind == DOUBLE_REGISTERS ? cfg->num_double_registers() |
: cfg->num_general_registers(); |
} |
+int GetAllocatableRegisterCount(const RegisterConfiguration* cfg, |
+ RegisterKind kind) { |
+ return kind == DOUBLE_REGISTERS |
+ ? cfg->num_allocatable_aliased_double_registers() |
+ : cfg->num_allocatable_general_registers(); |
+} |
+ |
+ |
+const int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg, |
+ RegisterKind kind) { |
+ return kind == DOUBLE_REGISTERS ? cfg->allocatable_double_codes() |
+ : cfg->allocatable_general_codes(); |
+} |
+ |
+ |
const InstructionBlock* GetContainingLoop(const InstructionSequence* sequence, |
const InstructionBlock* block) { |
auto index = block->loop_header(); |
@@ -52,11 +67,11 @@ Instruction* GetLastInstruction(InstructionSequence* code, |
} |
-bool IsOutputRegisterOf(Instruction* instr, int index) { |
+bool IsOutputRegisterOf(Instruction* instr, Register reg) { |
for (size_t i = 0; i < instr->OutputCount(); i++) { |
auto output = instr->OutputAt(i); |
if (output->IsRegister() && |
- RegisterOperand::cast(output)->index() == index) { |
+ RegisterOperand::cast(output)->GetRegister().is(reg)) { |
return true; |
} |
} |
@@ -64,11 +79,11 @@ bool IsOutputRegisterOf(Instruction* instr, int index) { |
} |
-bool IsOutputDoubleRegisterOf(Instruction* instr, int index) { |
+bool IsOutputDoubleRegisterOf(Instruction* instr, DoubleRegister reg) { |
for (size_t i = 0; i < instr->OutputCount(); i++) { |
auto output = instr->OutputAt(i); |
if (output->IsDoubleRegister() && |
- DoubleRegisterOperand::cast(output)->index() == index) { |
+ DoubleRegisterOperand::cast(output)->GetDoubleRegister().is(reg)) { |
return true; |
} |
} |
@@ -129,7 +144,7 @@ bool UsePosition::HasHint() const { |
} |
-bool UsePosition::HintRegister(int* register_index) const { |
+bool UsePosition::HintRegister(int* register_code) const { |
if (hint_ == nullptr) return false; |
switch (HintTypeField::decode(flags_)) { |
case UsePositionHintType::kNone: |
@@ -139,20 +154,25 @@ bool UsePosition::HintRegister(int* register_index) const { |
auto use_pos = reinterpret_cast<UsePosition*>(hint_); |
int assigned_register = AssignedRegisterField::decode(use_pos->flags_); |
if (assigned_register == kUnassignedRegister) return false; |
- *register_index = assigned_register; |
+ *register_code = assigned_register; |
return true; |
} |
case UsePositionHintType::kOperand: { |
auto operand = reinterpret_cast<InstructionOperand*>(hint_); |
- int assigned_register = AllocatedOperand::cast(operand)->index(); |
- *register_index = assigned_register; |
+ int assigned_register = |
+ operand->IsRegister() |
+ ? RegisterOperand::cast(operand)->GetRegister().code() |
+ : DoubleRegisterOperand::cast(operand) |
+ ->GetDoubleRegister() |
+ .code(); |
+ *register_code = assigned_register; |
return true; |
} |
case UsePositionHintType::kPhi: { |
auto phi = reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_); |
int assigned_register = phi->assigned_register(); |
if (assigned_register == kUnassignedRegister) return false; |
- *register_index = assigned_register; |
+ *register_code = assigned_register; |
return true; |
} |
} |
@@ -1213,6 +1233,10 @@ RegisterAllocationData::RegisterAllocationData( |
debug_name_(debug_name), |
config_(config), |
phi_map_(allocation_zone()), |
+ allocatable_codes_(this->config()->num_general_registers(), -1, |
+ allocation_zone()), |
+ allocatable_double_codes_(this->config()->num_double_registers(), -1, |
+ allocation_zone()), |
live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), |
live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()), |
live_ranges_(code->VirtualRegisterCount() * 2, nullptr, |
@@ -1233,7 +1257,7 @@ RegisterAllocationData::RegisterAllocationData( |
assigned_registers_ = new (code_zone()) |
BitVector(this->config()->num_general_registers(), code_zone()); |
assigned_double_registers_ = new (code_zone()) |
- BitVector(this->config()->num_aliased_double_registers(), code_zone()); |
+ BitVector(this->config()->num_double_registers(), code_zone()); |
this->frame()->SetAllocatedRegisters(assigned_registers_); |
this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_); |
} |
@@ -1772,7 +1796,7 @@ TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) { |
TopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) { |
- DCHECK(index < config()->num_aliased_double_registers()); |
+ DCHECK(index < config()->num_double_registers()); |
auto result = data()->fixed_double_live_ranges()[index]; |
if (result == nullptr) { |
result = data()->NewLiveRange(FixedDoubleLiveRangeID(index), kRepFloat64); |
@@ -1793,10 +1817,11 @@ TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { |
return data()->GetOrCreateLiveRangeFor( |
ConstantOperand::cast(operand)->virtual_register()); |
} else if (operand->IsRegister()) { |
- return FixedLiveRangeFor(RegisterOperand::cast(operand)->index()); |
+ return FixedLiveRangeFor( |
+ RegisterOperand::cast(operand)->GetRegister().code()); |
} else if (operand->IsDoubleRegister()) { |
return FixedDoubleLiveRangeFor( |
- DoubleRegisterOperand::cast(operand)->index()); |
+ DoubleRegisterOperand::cast(operand)->GetDoubleRegister().code()); |
} else { |
return nullptr; |
} |
@@ -1886,9 +1911,10 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block, |
} |
if (instr->ClobbersRegisters()) { |
- for (int i = 0; i < config()->num_general_registers(); ++i) { |
- if (!IsOutputRegisterOf(instr, i)) { |
- auto range = FixedLiveRangeFor(i); |
+ for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) { |
+ int code = config()->GetAllocatableGeneralCode(i); |
+ if (!IsOutputRegisterOf(instr, Register::from_code(code))) { |
+ auto range = FixedLiveRangeFor(code); |
range->AddUseInterval(curr_position, curr_position.End(), |
allocation_zone()); |
} |
@@ -1896,9 +1922,11 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block, |
} |
if (instr->ClobbersDoubleRegisters()) { |
- for (int i = 0; i < config()->num_aliased_double_registers(); ++i) { |
- if (!IsOutputDoubleRegisterOf(instr, i)) { |
- auto range = FixedDoubleLiveRangeFor(i); |
+ for (int i = 0; i < config()->num_allocatable_aliased_double_registers(); |
+ ++i) { |
+ int code = config()->GetAllocatableDoubleCode(i); |
+ if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) { |
+ auto range = FixedDoubleLiveRangeFor(code); |
range->AddUseInterval(curr_position, curr_position.End(), |
allocation_zone()); |
} |
@@ -2144,7 +2172,11 @@ RegisterAllocator::RegisterAllocator(RegisterAllocationData* data, |
RegisterKind kind) |
: data_(data), |
mode_(kind), |
- num_registers_(GetRegisterCount(data->config(), kind)) {} |
+ num_registers_(GetRegisterCount(data->config(), kind)), |
+ num_allocatable_registers_( |
+ GetAllocatableRegisterCount(data->config(), kind)), |
+ allocatable_register_codes_( |
+ GetAllocatableRegisterCodes(data->config(), kind)) {} |
LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range, |
@@ -2267,11 +2299,11 @@ const ZoneVector<TopLevelLiveRange*>& RegisterAllocator::GetFixedRegisters() |
} |
-const char* RegisterAllocator::RegisterName(int allocation_index) const { |
+const char* RegisterAllocator::RegisterName(int register_code) const { |
if (mode() == GENERAL_REGISTERS) { |
- return data()->config()->general_register_name(allocation_index); |
+ return data()->config()->GetGeneralRegisterName(register_code); |
} else { |
- return data()->config()->double_register_name(allocation_index); |
+ return data()->config()->GetDoubleRegisterName(register_code); |
} |
} |
@@ -2510,6 +2542,9 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) { |
for (auto cur_active : active_live_ranges()) { |
free_until_pos[cur_active->assigned_register()] = |
LifetimePosition::GapFromInstructionIndex(0); |
+ TRACE("Register %s is free until pos %d (1)\n", |
+ RegisterName(cur_active->assigned_register()), |
+ LifetimePosition::GapFromInstructionIndex(0).value()); |
} |
for (auto cur_inactive : inactive_live_ranges()) { |
@@ -2518,6 +2553,8 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) { |
if (!next_intersection.IsValid()) continue; |
int cur_reg = cur_inactive->assigned_register(); |
free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection); |
+ TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), |
+ Min(free_until_pos[cur_reg], next_intersection).value()); |
} |
int hint_register; |
@@ -2539,10 +2576,11 @@ bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) { |
} |
// Find the register which stays free for the longest time. |
- int reg = 0; |
- for (int i = 1; i < num_registers(); ++i) { |
- if (free_until_pos[i] > free_until_pos[reg]) { |
- reg = i; |
+ int reg = allocatable_register_code(0); |
+ for (int i = 1; i < num_allocatable_registers(); ++i) { |
+ int code = allocatable_register_code(i); |
+ if (free_until_pos[code] > free_until_pos[reg]) { |
+ reg = code; |
} |
} |
@@ -2617,10 +2655,11 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) { |
} |
} |
- int reg = 0; |
- for (int i = 1; i < num_registers(); ++i) { |
- if (use_pos[i] > use_pos[reg]) { |
- reg = i; |
+ int reg = allocatable_register_code(0); |
+ for (int i = 1; i < num_allocatable_registers(); ++i) { |
+ int code = allocatable_register_code(i); |
+ if (use_pos[code] > use_pos[reg]) { |
+ reg = code; |
} |
} |