Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 } | 74 } |
| 75 return false; | 75 return false; |
| 76 } | 76 } |
| 77 | 77 |
| 78 bool IsOutputFPRegisterOf(Instruction* instr, MachineRepresentation rep, | 78 bool IsOutputFPRegisterOf(Instruction* instr, MachineRepresentation rep, |
| 79 int code) { | 79 int code) { |
| 80 for (size_t i = 0; i < instr->OutputCount(); i++) { | 80 for (size_t i = 0; i < instr->OutputCount(); i++) { |
| 81 InstructionOperand* output = instr->OutputAt(i); | 81 InstructionOperand* output = instr->OutputAt(i); |
| 82 if (output->IsFPRegister()) { | 82 if (output->IsFPRegister()) { |
| 83 const LocationOperand* op = LocationOperand::cast(output); | 83 const LocationOperand* op = LocationOperand::cast(output); |
| 84 const RegisterConfiguration* config = | 84 if (kSimpleFPAliasing) { |
| 85 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); | |
| 86 if (config->fp_aliasing_kind() != RegisterConfiguration::COMBINE) { | |
| 87 if (op->register_code() == code) return true; | 85 if (op->register_code() == code) return true; |
| 88 } else { | 86 } else { |
| 89 if (config->AreAliases(op->representation(), op->register_code(), rep, | 87 if (RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN) |
| 90 code)) { | 88 ->AreAliases(op->representation(), op->register_code(), rep, |
| 89 code)) { | |
| 91 return true; | 90 return true; |
| 92 } | 91 } |
| 93 } | 92 } |
| 94 } | 93 } |
| 95 } | 94 } |
| 96 return false; | 95 return false; |
| 97 } | 96 } |
| 98 | 97 |
| 99 | 98 |
| 100 // TODO(dcarney): fix frame to allow frame accesses to half size location. | 99 // TODO(dcarney): fix frame to allow frame accesses to half size location. |
| (...skipping 1448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1549 DCHECK(!range->IsSplinter()); | 1548 DCHECK(!range->IsSplinter()); |
| 1550 SpillRange* spill_range = | 1549 SpillRange* spill_range = |
| 1551 new (allocation_zone()) SpillRange(range, allocation_zone()); | 1550 new (allocation_zone()) SpillRange(range, allocation_zone()); |
| 1552 return spill_range; | 1551 return spill_range; |
| 1553 } | 1552 } |
| 1554 | 1553 |
| 1555 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep, | 1554 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep, |
| 1556 int index) { | 1555 int index) { |
| 1557 switch (rep) { | 1556 switch (rep) { |
| 1558 case MachineRepresentation::kFloat32: | 1557 case MachineRepresentation::kFloat32: |
| 1559 if (config()->fp_aliasing_kind() == RegisterConfiguration::COMBINE) { | 1558 if (kSimpleFPAliasing) { |
| 1559 assigned_double_registers_->Add(index); | |
|
bbudge
2016/06/26 23:08:32
Fixes a bug.
| |
| 1560 } else { | |
| 1560 int alias_base_index = -1; | 1561 int alias_base_index = -1; |
| 1561 int aliases = config()->GetAliases( | 1562 int aliases = config()->GetAliases( |
| 1562 rep, index, MachineRepresentation::kFloat64, &alias_base_index); | 1563 rep, index, MachineRepresentation::kFloat64, &alias_base_index); |
| 1563 while (aliases--) { | 1564 while (aliases--) { |
| 1564 int aliased_reg = alias_base_index + aliases; | 1565 int aliased_reg = alias_base_index + aliases; |
| 1565 assigned_double_registers_->Add(aliased_reg); | 1566 assigned_double_registers_->Add(aliased_reg); |
| 1566 } | 1567 } |
| 1567 } | 1568 } |
| 1568 break; | 1569 break; |
| 1569 case MachineRepresentation::kFloat64: | 1570 case MachineRepresentation::kFloat64: |
| (...skipping 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2417 } | 2418 } |
| 2418 | 2419 |
| 2419 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data, | 2420 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data, |
| 2420 RegisterKind kind) | 2421 RegisterKind kind) |
| 2421 : data_(data), | 2422 : data_(data), |
| 2422 mode_(kind), | 2423 mode_(kind), |
| 2423 num_registers_(GetRegisterCount(data->config(), kind)), | 2424 num_registers_(GetRegisterCount(data->config(), kind)), |
| 2424 num_allocatable_registers_( | 2425 num_allocatable_registers_( |
| 2425 GetAllocatableRegisterCount(data->config(), kind)), | 2426 GetAllocatableRegisterCount(data->config(), kind)), |
| 2426 allocatable_register_codes_( | 2427 allocatable_register_codes_( |
| 2427 GetAllocatableRegisterCodes(data->config(), kind)), | 2428 GetAllocatableRegisterCodes(data->config(), kind)) {} |
| 2428 no_combining_(kind != FP_REGISTERS || | |
| 2429 data->config()->fp_aliasing_kind() != | |
| 2430 RegisterConfiguration::COMBINE) {} | |
| 2431 | 2429 |
| 2432 LifetimePosition RegisterAllocator::GetSplitPositionForInstruction( | 2430 LifetimePosition RegisterAllocator::GetSplitPositionForInstruction( |
| 2433 const LiveRange* range, int instruction_index) { | 2431 const LiveRange* range, int instruction_index) { |
| 2434 LifetimePosition ret = LifetimePosition::Invalid(); | 2432 LifetimePosition ret = LifetimePosition::Invalid(); |
| 2435 | 2433 |
| 2436 ret = LifetimePosition::GapFromInstructionIndex(instruction_index); | 2434 ret = LifetimePosition::GapFromInstructionIndex(instruction_index); |
| 2437 if (range->Start() >= ret || ret >= range->End()) { | 2435 if (range->Start() >= ret || ret >= range->End()) { |
| 2438 return LifetimePosition::Invalid(); | 2436 return LifetimePosition::Invalid(); |
| 2439 } | 2437 } |
| 2440 return ret; | 2438 return ret; |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2816 active_live_ranges().push_back(range); | 2814 active_live_ranges().push_back(range); |
| 2817 TRACE("Moving live range %d:%d from inactive to active\n", | 2815 TRACE("Moving live range %d:%d from inactive to active\n", |
| 2818 range->TopLevel()->vreg(), range->relative_id()); | 2816 range->TopLevel()->vreg(), range->relative_id()); |
| 2819 } | 2817 } |
| 2820 | 2818 |
| 2821 | 2819 |
| 2822 bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) { | 2820 bool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) { |
| 2823 int num_regs = num_registers(); | 2821 int num_regs = num_registers(); |
| 2824 int num_codes = num_allocatable_registers(); | 2822 int num_codes = num_allocatable_registers(); |
| 2825 const int* codes = allocatable_register_codes(); | 2823 const int* codes = allocatable_register_codes(); |
| 2826 if (!no_combining() && | 2824 if (!kSimpleFPAliasing && |
| 2827 (current->representation() == MachineRepresentation::kFloat32)) { | 2825 (current->representation() == MachineRepresentation::kFloat32)) { |
| 2828 num_regs = data()->config()->num_float_registers(); | 2826 num_regs = data()->config()->num_float_registers(); |
| 2829 num_codes = data()->config()->num_allocatable_float_registers(); | 2827 num_codes = data()->config()->num_allocatable_float_registers(); |
| 2830 codes = data()->config()->allocatable_float_codes(); | 2828 codes = data()->config()->allocatable_float_codes(); |
| 2831 } | 2829 } |
| 2832 LifetimePosition free_until_pos[RegisterConfiguration::kMaxFPRegisters]; | 2830 LifetimePosition free_until_pos[RegisterConfiguration::kMaxFPRegisters]; |
| 2833 for (int i = 0; i < num_regs; i++) { | 2831 for (int i = 0; i < num_regs; i++) { |
| 2834 free_until_pos[i] = LifetimePosition::MaxPosition(); | 2832 free_until_pos[i] = LifetimePosition::MaxPosition(); |
| 2835 } | 2833 } |
| 2836 | 2834 |
| 2837 for (LiveRange* cur_active : active_live_ranges()) { | 2835 for (LiveRange* cur_active : active_live_ranges()) { |
| 2838 int cur_reg = cur_active->assigned_register(); | 2836 int cur_reg = cur_active->assigned_register(); |
| 2839 if (no_combining()) { | 2837 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 2840 free_until_pos[cur_reg] = LifetimePosition::GapFromInstructionIndex(0); | 2838 free_until_pos[cur_reg] = LifetimePosition::GapFromInstructionIndex(0); |
| 2841 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg), | 2839 TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg), |
| 2842 LifetimePosition::GapFromInstructionIndex(0).value()); | 2840 LifetimePosition::GapFromInstructionIndex(0).value()); |
| 2843 } else { | 2841 } else { |
| 2844 int alias_base_index = -1; | 2842 int alias_base_index = -1; |
| 2845 int aliases = data()->config()->GetAliases( | 2843 int aliases = data()->config()->GetAliases( |
| 2846 cur_active->representation(), cur_reg, current->representation(), | 2844 cur_active->representation(), cur_reg, current->representation(), |
| 2847 &alias_base_index); | 2845 &alias_base_index); |
| 2848 while (aliases--) { | 2846 while (aliases--) { |
| 2849 int aliased_reg = alias_base_index + aliases; | 2847 int aliased_reg = alias_base_index + aliases; |
| 2850 free_until_pos[aliased_reg] = | 2848 free_until_pos[aliased_reg] = |
| 2851 LifetimePosition::GapFromInstructionIndex(0); | 2849 LifetimePosition::GapFromInstructionIndex(0); |
| 2852 } | 2850 } |
| 2853 } | 2851 } |
| 2854 } | 2852 } |
| 2855 | 2853 |
| 2856 for (LiveRange* cur_inactive : inactive_live_ranges()) { | 2854 for (LiveRange* cur_inactive : inactive_live_ranges()) { |
| 2857 DCHECK(cur_inactive->End() > current->Start()); | 2855 DCHECK(cur_inactive->End() > current->Start()); |
| 2858 LifetimePosition next_intersection = | 2856 LifetimePosition next_intersection = |
| 2859 cur_inactive->FirstIntersection(current); | 2857 cur_inactive->FirstIntersection(current); |
| 2860 if (!next_intersection.IsValid()) continue; | 2858 if (!next_intersection.IsValid()) continue; |
| 2861 int cur_reg = cur_inactive->assigned_register(); | 2859 int cur_reg = cur_inactive->assigned_register(); |
| 2862 if (no_combining()) { | 2860 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 2863 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection); | 2861 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection); |
| 2864 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), | 2862 TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg), |
| 2865 Min(free_until_pos[cur_reg], next_intersection).value()); | 2863 Min(free_until_pos[cur_reg], next_intersection).value()); |
| 2866 } else { | 2864 } else { |
| 2867 int alias_base_index = -1; | 2865 int alias_base_index = -1; |
| 2868 int aliases = data()->config()->GetAliases( | 2866 int aliases = data()->config()->GetAliases( |
| 2869 cur_inactive->representation(), cur_reg, current->representation(), | 2867 cur_inactive->representation(), cur_reg, current->representation(), |
| 2870 &alias_base_index); | 2868 &alias_base_index); |
| 2871 while (aliases--) { | 2869 while (aliases--) { |
| 2872 int aliased_reg = alias_base_index + aliases; | 2870 int aliased_reg = alias_base_index + aliases; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2933 if (register_use == nullptr) { | 2931 if (register_use == nullptr) { |
| 2934 // There is no use in the current live range that requires a register. | 2932 // There is no use in the current live range that requires a register. |
| 2935 // We can just spill it. | 2933 // We can just spill it. |
| 2936 Spill(current); | 2934 Spill(current); |
| 2937 return; | 2935 return; |
| 2938 } | 2936 } |
| 2939 | 2937 |
| 2940 int num_regs = num_registers(); | 2938 int num_regs = num_registers(); |
| 2941 int num_codes = num_allocatable_registers(); | 2939 int num_codes = num_allocatable_registers(); |
| 2942 const int* codes = allocatable_register_codes(); | 2940 const int* codes = allocatable_register_codes(); |
| 2943 if (!no_combining() && | 2941 if (!kSimpleFPAliasing && |
| 2944 (current->representation() == MachineRepresentation::kFloat32)) { | 2942 (current->representation() == MachineRepresentation::kFloat32)) { |
| 2945 num_regs = data()->config()->num_float_registers(); | 2943 num_regs = data()->config()->num_float_registers(); |
| 2946 num_codes = data()->config()->num_allocatable_float_registers(); | 2944 num_codes = data()->config()->num_allocatable_float_registers(); |
| 2947 codes = data()->config()->allocatable_float_codes(); | 2945 codes = data()->config()->allocatable_float_codes(); |
| 2948 } | 2946 } |
| 2949 | 2947 |
| 2950 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters]; | 2948 LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters]; |
| 2951 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters]; | 2949 LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters]; |
| 2952 for (int i = 0; i < num_regs; i++) { | 2950 for (int i = 0; i < num_regs; i++) { |
| 2953 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); | 2951 use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); |
| 2954 } | 2952 } |
| 2955 | 2953 |
| 2956 for (LiveRange* range : active_live_ranges()) { | 2954 for (LiveRange* range : active_live_ranges()) { |
| 2957 int cur_reg = range->assigned_register(); | 2955 int cur_reg = range->assigned_register(); |
| 2958 bool is_fixed_or_cant_spill = | 2956 bool is_fixed_or_cant_spill = |
| 2959 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start()); | 2957 range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start()); |
| 2960 if (no_combining()) { | 2958 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 2961 if (is_fixed_or_cant_spill) { | 2959 if (is_fixed_or_cant_spill) { |
| 2962 block_pos[cur_reg] = use_pos[cur_reg] = | 2960 block_pos[cur_reg] = use_pos[cur_reg] = |
| 2963 LifetimePosition::GapFromInstructionIndex(0); | 2961 LifetimePosition::GapFromInstructionIndex(0); |
| 2964 } else { | 2962 } else { |
| 2965 UsePosition* next_use = | 2963 UsePosition* next_use = |
| 2966 range->NextUsePositionRegisterIsBeneficial(current->Start()); | 2964 range->NextUsePositionRegisterIsBeneficial(current->Start()); |
| 2967 if (next_use == nullptr) { | 2965 if (next_use == nullptr) { |
| 2968 use_pos[cur_reg] = range->End(); | 2966 use_pos[cur_reg] = range->End(); |
| 2969 } else { | 2967 } else { |
| 2970 use_pos[cur_reg] = next_use->pos(); | 2968 use_pos[cur_reg] = next_use->pos(); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 2992 } | 2990 } |
| 2993 } | 2991 } |
| 2994 } | 2992 } |
| 2995 | 2993 |
| 2996 for (LiveRange* range : inactive_live_ranges()) { | 2994 for (LiveRange* range : inactive_live_ranges()) { |
| 2997 DCHECK(range->End() > current->Start()); | 2995 DCHECK(range->End() > current->Start()); |
| 2998 LifetimePosition next_intersection = range->FirstIntersection(current); | 2996 LifetimePosition next_intersection = range->FirstIntersection(current); |
| 2999 if (!next_intersection.IsValid()) continue; | 2997 if (!next_intersection.IsValid()) continue; |
| 3000 int cur_reg = range->assigned_register(); | 2998 int cur_reg = range->assigned_register(); |
| 3001 bool is_fixed = range->TopLevel()->IsFixed(); | 2999 bool is_fixed = range->TopLevel()->IsFixed(); |
| 3002 if (no_combining()) { | 3000 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 3003 if (is_fixed) { | 3001 if (is_fixed) { |
| 3004 block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); | 3002 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]); | 3003 use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); |
| 3006 } else { | 3004 } else { |
| 3007 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); | 3005 use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); |
| 3008 } | 3006 } |
| 3009 } else { | 3007 } else { |
| 3010 int alias_base_index = -1; | 3008 int alias_base_index = -1; |
| 3011 int aliases = data()->config()->GetAliases( | 3009 int aliases = data()->config()->GetAliases( |
| 3012 range->representation(), cur_reg, current->representation(), | 3010 range->representation(), cur_reg, current->representation(), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3066 SplitAndSpillIntersecting(current); | 3064 SplitAndSpillIntersecting(current); |
| 3067 } | 3065 } |
| 3068 | 3066 |
| 3069 | 3067 |
| 3070 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { | 3068 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) { |
| 3071 DCHECK(current->HasRegisterAssigned()); | 3069 DCHECK(current->HasRegisterAssigned()); |
| 3072 int reg = current->assigned_register(); | 3070 int reg = current->assigned_register(); |
| 3073 LifetimePosition split_pos = current->Start(); | 3071 LifetimePosition split_pos = current->Start(); |
| 3074 for (size_t i = 0; i < active_live_ranges().size(); ++i) { | 3072 for (size_t i = 0; i < active_live_ranges().size(); ++i) { |
| 3075 LiveRange* range = active_live_ranges()[i]; | 3073 LiveRange* range = active_live_ranges()[i]; |
| 3076 if (no_combining()) { | 3074 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 3077 if (range->assigned_register() != reg) continue; | 3075 if (range->assigned_register() != reg) continue; |
| 3078 } else { | 3076 } else { |
| 3079 if (!data()->config()->AreAliases(current->representation(), reg, | 3077 if (!data()->config()->AreAliases(current->representation(), reg, |
| 3080 range->representation(), | 3078 range->representation(), |
| 3081 range->assigned_register())) { | 3079 range->assigned_register())) { |
| 3082 continue; | 3080 continue; |
| 3083 } | 3081 } |
| 3084 } | 3082 } |
| 3085 | 3083 |
| 3086 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); | 3084 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 3101 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); | 3099 SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); |
| 3102 } | 3100 } |
| 3103 ActiveToHandled(range); | 3101 ActiveToHandled(range); |
| 3104 --i; | 3102 --i; |
| 3105 } | 3103 } |
| 3106 | 3104 |
| 3107 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { | 3105 for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { |
| 3108 LiveRange* range = inactive_live_ranges()[i]; | 3106 LiveRange* range = inactive_live_ranges()[i]; |
| 3109 DCHECK(range->End() > current->Start()); | 3107 DCHECK(range->End() > current->Start()); |
| 3110 if (range->TopLevel()->IsFixed()) continue; | 3108 if (range->TopLevel()->IsFixed()) continue; |
| 3111 if (no_combining()) { | 3109 if (kSimpleFPAliasing || mode() == GENERAL_REGISTERS) { |
| 3112 if (range->assigned_register() != reg) continue; | 3110 if (range->assigned_register() != reg) continue; |
| 3113 } else { | 3111 } else { |
| 3114 if (!data()->config()->AreAliases(current->representation(), reg, | 3112 if (!data()->config()->AreAliases(current->representation(), reg, |
| 3115 range->representation(), | 3113 range->representation(), |
| 3116 range->assigned_register())) | 3114 range->assigned_register())) |
| 3117 continue; | 3115 continue; |
| 3118 } | 3116 } |
| 3119 | 3117 |
| 3120 LifetimePosition next_intersection = range->FirstIntersection(current); | 3118 LifetimePosition next_intersection = range->FirstIntersection(current); |
| 3121 if (next_intersection.IsValid()) { | 3119 if (next_intersection.IsValid()) { |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3771 } | 3769 } |
| 3772 } | 3770 } |
| 3773 } | 3771 } |
| 3774 } | 3772 } |
| 3775 } | 3773 } |
| 3776 | 3774 |
| 3777 | 3775 |
| 3778 } // namespace compiler | 3776 } // namespace compiler |
| 3779 } // namespace internal | 3777 } // namespace internal |
| 3780 } // namespace v8 | 3778 } // namespace v8 |
| OLD | NEW |