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 |