Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: src/compiler/register-allocator.cc

Issue 2101473002: [Turbofan] Allow compiler to elide complex aliasing code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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);
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698