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/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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |