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

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

Issue 748773002: [turbofan] put spill slot reuse behind a flag (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 6 years, 1 month 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/flag-definitions.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/compiler/linkage.h" 5 #include "src/compiler/linkage.h"
6 #include "src/compiler/register-allocator.h" 6 #include "src/compiler/register-allocator.h"
7 #include "src/string-stream.h" 7 #include "src/string-stream.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 tail->set_next(current); 874 tail->set_next(current);
875 } 875 }
876 tail = current; 876 tail = current;
877 current = current->next(); 877 current = current->next();
878 } 878 }
879 // Other list is empty => we are done 879 // Other list is empty => we are done
880 } 880 }
881 881
882 882
883 void RegisterAllocator::ReuseSpillSlots() { 883 void RegisterAllocator::ReuseSpillSlots() {
884 DCHECK(FLAG_turbo_reuse_spill_slots);
885
884 // Merge disjoint spill ranges 886 // Merge disjoint spill ranges
885 for (int i = 0; i < spill_ranges_.length(); i++) { 887 for (int i = 0; i < spill_ranges_.length(); i++) {
886 SpillRange* range = spill_ranges_.at(i); 888 SpillRange* range = spill_ranges_.at(i);
887 if (!range->IsEmpty()) { 889 if (!range->IsEmpty()) {
888 for (int j = i + 1; j < spill_ranges_.length(); j++) { 890 for (int j = i + 1; j < spill_ranges_.length(); j++) {
889 SpillRange* other = spill_ranges_.at(j); 891 SpillRange* other = spill_ranges_.at(j);
890 if (!other->IsEmpty()) { 892 if (!other->IsEmpty()) {
891 range->TryMerge(spill_ranges_.at(j), local_zone()); 893 range->TryMerge(spill_ranges_.at(j), local_zone());
892 } 894 }
893 } 895 }
(...skipping 14 matching lines...) Expand all
908 DCHECK(kind == GENERAL_REGISTERS); 910 DCHECK(kind == GENERAL_REGISTERS);
909 op = StackSlotOperand::Create(index, local_zone()); 911 op = StackSlotOperand::Create(index, local_zone());
910 } 912 }
911 range->SetOperand(op); 913 range->SetOperand(op);
912 } 914 }
913 } 915 }
914 } 916 }
915 917
916 918
917 SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { 919 SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
920 DCHECK(FLAG_turbo_reuse_spill_slots);
918 int spill_id = spill_ranges_.length(); 921 int spill_id = spill_ranges_.length();
919 SpillRange* spill_range = 922 SpillRange* spill_range =
920 new (local_zone()) SpillRange(range, spill_id, local_zone()); 923 new (local_zone()) SpillRange(range, spill_id, local_zone());
921 spill_ranges_.Add(spill_range, local_zone()); 924 spill_ranges_.Add(spill_range, local_zone());
922 return spill_range; 925 return spill_range;
923 } 926 }
924 927
925 928
926 void RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) { 929 void RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) {
927 int start = block->first_instruction_index(); 930 int start = block->first_instruction_index();
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
1925 int len = unhandled_live_ranges_.length(); 1928 int len = unhandled_live_ranges_.length();
1926 for (int i = 1; i < len; i++) { 1929 for (int i = 1; i < len; i++) {
1927 LiveRange* a = unhandled_live_ranges_.at(i - 1); 1930 LiveRange* a = unhandled_live_ranges_.at(i - 1);
1928 LiveRange* b = unhandled_live_ranges_.at(i); 1931 LiveRange* b = unhandled_live_ranges_.at(i);
1929 if (a->Start().Value() < b->Start().Value()) return false; 1932 if (a->Start().Value() < b->Start().Value()) return false;
1930 } 1933 }
1931 return true; 1934 return true;
1932 } 1935 }
1933 1936
1934 1937
1938 void RegisterAllocator::FreeSpillSlot(LiveRange* range) {
1939 DCHECK(!FLAG_turbo_reuse_spill_slots);
1940 // Check that we are the last range.
1941 if (range->next() != NULL) return;
1942
1943 if (!range->TopLevel()->HasAllocatedSpillOperand()) return;
1944
1945 InstructionOperand* spill_operand = range->TopLevel()->GetSpillOperand();
1946 if (spill_operand->IsConstant()) return;
1947 if (spill_operand->index() >= 0) {
1948 reusable_slots_.Add(range, local_zone());
1949 }
1950 }
1951
1952
1953 InstructionOperand* RegisterAllocator::TryReuseSpillSlot(LiveRange* range) {
1954 DCHECK(!FLAG_turbo_reuse_spill_slots);
1955 if (reusable_slots_.is_empty()) return NULL;
1956 if (reusable_slots_.first()->End().Value() >
1957 range->TopLevel()->Start().Value()) {
1958 return NULL;
1959 }
1960 InstructionOperand* result =
1961 reusable_slots_.first()->TopLevel()->GetSpillOperand();
1962 reusable_slots_.Remove(0);
1963 return result;
1964 }
1965
1966
1935 void RegisterAllocator::ActiveToHandled(LiveRange* range) { 1967 void RegisterAllocator::ActiveToHandled(LiveRange* range) {
1936 DCHECK(active_live_ranges_.Contains(range)); 1968 DCHECK(active_live_ranges_.Contains(range));
1937 active_live_ranges_.RemoveElement(range); 1969 active_live_ranges_.RemoveElement(range);
1938 TraceAlloc("Moving live range %d from active to handled\n", range->id()); 1970 TraceAlloc("Moving live range %d from active to handled\n", range->id());
1971 if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
1939 } 1972 }
1940 1973
1941 1974
1942 void RegisterAllocator::ActiveToInactive(LiveRange* range) { 1975 void RegisterAllocator::ActiveToInactive(LiveRange* range) {
1943 DCHECK(active_live_ranges_.Contains(range)); 1976 DCHECK(active_live_ranges_.Contains(range));
1944 active_live_ranges_.RemoveElement(range); 1977 active_live_ranges_.RemoveElement(range);
1945 inactive_live_ranges_.Add(range, local_zone()); 1978 inactive_live_ranges_.Add(range, local_zone());
1946 TraceAlloc("Moving live range %d from active to inactive\n", range->id()); 1979 TraceAlloc("Moving live range %d from active to inactive\n", range->id());
1947 } 1980 }
1948 1981
1949 1982
1950 void RegisterAllocator::InactiveToHandled(LiveRange* range) { 1983 void RegisterAllocator::InactiveToHandled(LiveRange* range) {
1951 DCHECK(inactive_live_ranges_.Contains(range)); 1984 DCHECK(inactive_live_ranges_.Contains(range));
1952 inactive_live_ranges_.RemoveElement(range); 1985 inactive_live_ranges_.RemoveElement(range);
1953 TraceAlloc("Moving live range %d from inactive to handled\n", range->id()); 1986 TraceAlloc("Moving live range %d from inactive to handled\n", range->id());
1987 if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
1954 } 1988 }
1955 1989
1956 1990
1957 void RegisterAllocator::InactiveToActive(LiveRange* range) { 1991 void RegisterAllocator::InactiveToActive(LiveRange* range) {
1958 DCHECK(inactive_live_ranges_.Contains(range)); 1992 DCHECK(inactive_live_ranges_.Contains(range));
1959 inactive_live_ranges_.RemoveElement(range); 1993 inactive_live_ranges_.RemoveElement(range);
1960 active_live_ranges_.Add(range, local_zone()); 1994 active_live_ranges_.Add(range, local_zone());
1961 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); 1995 TraceAlloc("Moving live range %d from inactive to active\n", range->id());
1962 } 1996 }
1963 1997
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 } 2362 }
2329 } 2363 }
2330 2364
2331 2365
2332 void RegisterAllocator::Spill(LiveRange* range) { 2366 void RegisterAllocator::Spill(LiveRange* range) {
2333 DCHECK(!range->IsSpilled()); 2367 DCHECK(!range->IsSpilled());
2334 TraceAlloc("Spilling live range %d\n", range->id()); 2368 TraceAlloc("Spilling live range %d\n", range->id());
2335 LiveRange* first = range->TopLevel(); 2369 LiveRange* first = range->TopLevel();
2336 2370
2337 if (!first->HasAllocatedSpillOperand()) { 2371 if (!first->HasAllocatedSpillOperand()) {
2338 AssignSpillRangeToLiveRange(first); 2372 if (FLAG_turbo_reuse_spill_slots) {
2373 AssignSpillRangeToLiveRange(first);
2374 } else {
2375 InstructionOperand* op = TryReuseSpillSlot(range);
2376 if (op == NULL) {
2377 // Allocate a new operand referring to the spill slot.
2378 RegisterKind kind = range->Kind();
2379 int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
2380 if (kind == DOUBLE_REGISTERS) {
2381 op = DoubleStackSlotOperand::Create(index, local_zone());
2382 } else {
2383 DCHECK(kind == GENERAL_REGISTERS);
2384 op = StackSlotOperand::Create(index, local_zone());
2385 }
2386 }
2387 first->SetSpillOperand(op);
2388 }
2339 } 2389 }
2340 range->MakeSpilled(code_zone()); 2390 range->MakeSpilled(code_zone());
2341 } 2391 }
2342 2392
2343 2393
2344 int RegisterAllocator::RegisterCount() const { return num_registers_; } 2394 int RegisterAllocator::RegisterCount() const { return num_registers_; }
2345 2395
2346 2396
2347 #ifdef DEBUG 2397 #ifdef DEBUG
2348 2398
(...skipping 15 matching lines...) Expand all
2364 } else { 2414 } else {
2365 DCHECK(range->Kind() == GENERAL_REGISTERS); 2415 DCHECK(range->Kind() == GENERAL_REGISTERS);
2366 assigned_registers_->Add(reg); 2416 assigned_registers_->Add(reg);
2367 } 2417 }
2368 range->set_assigned_register(reg, code_zone()); 2418 range->set_assigned_register(reg, code_zone());
2369 } 2419 }
2370 2420
2371 } 2421 }
2372 } 2422 }
2373 } // namespace v8::internal::compiler 2423 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698