| 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,
|
|
|