Index: src/compiler/register-allocator.cc |
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc |
index 5740f902d5f3b66f07d1416568dadb2d1174d5c5..0ed479fa992f44b8687d1c1781571004f2226a30 100644 |
--- a/src/compiler/register-allocator.cc |
+++ b/src/compiler/register-allocator.cc |
@@ -19,6 +19,11 @@ namespace compiler { |
namespace { |
+static const int kFloatRepBit = |
+ 1 << static_cast<int>(MachineRepresentation::kFloat32); |
+static const int kSimd128RepBit = |
+ 1 << static_cast<int>(MachineRepresentation::kSimd128); |
+ |
void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) { |
auto it = std::find(v->begin(), v->end(), range); |
DCHECK(it != v->end()); |
@@ -2022,6 +2027,13 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block, |
int block_start = block->first_instruction_index(); |
LifetimePosition block_start_position = |
LifetimePosition::GapFromInstructionIndex(block_start); |
+ bool fixed_float_live_ranges = false; |
+ bool fixed_simd128_live_ranges = false; |
+ if (!kSimpleFPAliasing) { |
+ int mask = data()->code()->representation_mask(); |
+ fixed_float_live_ranges = (mask & kFloatRepBit) != 0; |
+ fixed_simd128_live_ranges = (mask & kSimd128RepBit) != 0; |
+ } |
for (int index = block->last_instruction_index(); index >= block_start; |
index--) { |
@@ -2081,22 +2093,27 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block, |
} |
// Clobber fixed float registers on archs with non-simple aliasing. |
if (!kSimpleFPAliasing) { |
- for (int i = 0; i < config()->num_allocatable_float_registers(); ++i) { |
- // Add a UseInterval for all FloatRegisters. See comment above for |
- // general registers. |
- int code = config()->GetAllocatableFloatCode(i); |
- TopLevelLiveRange* range = |
- FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32); |
- range->AddUseInterval(curr_position, curr_position.End(), |
- allocation_zone()); |
+ if (fixed_float_live_ranges) { |
+ for (int i = 0; i < config()->num_allocatable_float_registers(); |
+ ++i) { |
+ // Add a UseInterval for all FloatRegisters. See comment above for |
+ // general registers. |
+ int code = config()->GetAllocatableFloatCode(i); |
+ TopLevelLiveRange* range = |
+ FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32); |
+ range->AddUseInterval(curr_position, curr_position.End(), |
+ allocation_zone()); |
+ } |
} |
- for (int i = 0; i < config()->num_allocatable_simd128_registers(); |
- ++i) { |
- int code = config()->GetAllocatableSimd128Code(i); |
- TopLevelLiveRange* range = |
- FixedFPLiveRangeFor(code, MachineRepresentation::kSimd128); |
- range->AddUseInterval(curr_position, curr_position.End(), |
- allocation_zone()); |
+ if (fixed_simd128_live_ranges) { |
+ for (int i = 0; i < config()->num_allocatable_simd128_registers(); |
+ ++i) { |
+ int code = config()->GetAllocatableSimd128Code(i); |
+ TopLevelLiveRange* range = |
+ FixedFPLiveRangeFor(code, MachineRepresentation::kSimd128); |
+ range->AddUseInterval(curr_position, curr_position.End(), |
+ allocation_zone()); |
+ } |
} |
} |
} |
@@ -2210,7 +2227,6 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block, |
} |
} |
- |
void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block, |
BitVector* live) { |
for (PhiInstruction* phi : block->phis()) { |
@@ -2520,7 +2536,13 @@ RegisterAllocator::RegisterAllocator(RegisterAllocationData* data, |
num_allocatable_registers_( |
GetAllocatableRegisterCount(data->config(), kind)), |
allocatable_register_codes_( |
- GetAllocatableRegisterCodes(data->config(), kind)) {} |
+ GetAllocatableRegisterCodes(data->config(), kind)), |
+ check_fp_aliasing_(false) { |
+ if (!kSimpleFPAliasing && kind == FP_REGISTERS) { |
+ check_fp_aliasing_ = (data->code()->representation_mask() & |
+ (kFloatRepBit | kSimd128RepBit)) != 0; |
+ } |
+} |
LifetimePosition RegisterAllocator::GetSplitPositionForInstruction( |
const LiveRange* range, int instruction_index) { |
@@ -2747,7 +2769,7 @@ void LinearScanAllocator::AllocateRegisters() { |
for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) { |
if (current != nullptr) AddToInactive(current); |
} |
- if (!kSimpleFPAliasing) { |
+ if (!kSimpleFPAliasing && check_fp_aliasing()) { |
for (TopLevelLiveRange* current : data()->fixed_float_live_ranges()) { |
if (current != nullptr) AddToInactive(current); |
} |
@@ -2969,7 +2991,7 @@ void LinearScanAllocator::FindFreeRegistersForRange( |
for (LiveRange* cur_active : active_live_ranges()) { |
int cur_reg = cur_active->assigned_register(); |
- if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
+ if (kSimpleFPAliasing || !check_fp_aliasing()) { |
positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0); |
TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg), |
LifetimePosition::GapFromInstructionIndex(0).value()); |
@@ -2990,7 +3012,7 @@ void LinearScanAllocator::FindFreeRegistersForRange( |
LifetimePosition next_intersection = cur_inactive->FirstIntersection(range); |
if (!next_intersection.IsValid()) continue; |
int cur_reg = cur_inactive->assigned_register(); |
- if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
+ if (kSimpleFPAliasing || !check_fp_aliasing()) { |
positions[cur_reg] = Min(positions[cur_reg], next_intersection); |
TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), |
Min(positions[cur_reg], next_intersection).value()); |
@@ -3154,7 +3176,7 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) { |
int cur_reg = range->assigned_register(); |
bool is_fixed_or_cant_spill = |
range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start()); |
- if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
+ if (kSimpleFPAliasing || !check_fp_aliasing()) { |
if (is_fixed_or_cant_spill) { |
block_pos[cur_reg] = use_pos[cur_reg] = |
LifetimePosition::GapFromInstructionIndex(0); |
@@ -3186,7 +3208,7 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) { |
if (!next_intersection.IsValid()) continue; |
int cur_reg = range->assigned_register(); |
bool is_fixed = range->TopLevel()->IsFixed(); |
- if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
+ if (kSimpleFPAliasing || !check_fp_aliasing()) { |
if (is_fixed) { |
block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); |
use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); |
@@ -3260,7 +3282,7 @@ void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { |
LifetimePosition split_pos = current->Start(); |
for (size_t i = 0; i < active_live_ranges().size(); ++i) { |
LiveRange* range = active_live_ranges()[i]; |
- if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
+ if (kSimpleFPAliasing || !check_fp_aliasing()) { |
if (range->assigned_register() != reg) continue; |
} else { |
if (!data()->config()->AreAliases(current->representation(), reg, |
@@ -3295,7 +3317,7 @@ void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { |
LiveRange* range = inactive_live_ranges()[i]; |
DCHECK(range->End() > current->Start()); |
if (range->TopLevel()->IsFixed()) continue; |
- if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
+ if (kSimpleFPAliasing || !check_fp_aliasing()) { |
if (range->assigned_register() != reg) continue; |
} else { |
if (!data()->config()->AreAliases(current->representation(), reg, |