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

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

Issue 1014093008: [turbofan] Macro-ify the tracing code in RegisterAllocator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 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 | « no previous file | no next file » | 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 {
11 namespace compiler { 11 namespace compiler {
12 12
13 #define TRACE(...) \
14 do { \
15 if (FLAG_trace_alloc) PrintF(__VA_ARGS__); \
16 } while (false)
17
13 static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) { 18 static inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) {
14 return a.Value() < b.Value() ? a : b; 19 return a.Value() < b.Value() ? a : b;
15 } 20 }
16 21
17 22
18 static inline LifetimePosition Max(LifetimePosition a, LifetimePosition b) { 23 static inline LifetimePosition Max(LifetimePosition a, LifetimePosition b) {
19 return a.Value() > b.Value() ? a : b; 24 return a.Value() > b.Value() ? a : b;
20 } 25 }
21 26
22 27
23 static void TraceAlloc(const char* msg, ...) {
24 if (FLAG_trace_alloc) {
25 va_list arguments;
26 va_start(arguments, msg);
27 base::OS::VPrint(msg, arguments);
28 va_end(arguments);
29 }
30 }
31
32
33 static void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) { 28 static void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
34 auto it = std::find(v->begin(), v->end(), range); 29 auto it = std::find(v->begin(), v->end(), range);
35 DCHECK(it != v->end()); 30 DCHECK(it != v->end());
36 v->erase(it); 31 v->erase(it);
37 } 32 }
38 33
39 34
40 UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand, 35 UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
41 InstructionOperand* hint) 36 InstructionOperand* hint)
42 : operand_(operand), hint_(hint), pos_(pos), next_(nullptr), flags_(0) { 37 : operand_(operand), hint_(hint), pos_(pos), next_(nullptr), flags_(0) {
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 if (pos == nullptr) return false; 435 if (pos == nullptr) return false;
441 UsePosition* other_pos = other->first_pos(); 436 UsePosition* other_pos = other->first_pos();
442 if (other_pos == nullptr) return true; 437 if (other_pos == nullptr) return true;
443 return pos->pos().Value() < other_pos->pos().Value(); 438 return pos->pos().Value() < other_pos->pos().Value();
444 } 439 }
445 return start.Value() < other_start.Value(); 440 return start.Value() < other_start.Value();
446 } 441 }
447 442
448 443
449 void LiveRange::ShortenTo(LifetimePosition start) { 444 void LiveRange::ShortenTo(LifetimePosition start) {
450 TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value()); 445 TRACE("Shorten live range %d to [%d\n", id_, start.Value());
451 DCHECK(first_interval_ != nullptr); 446 DCHECK(first_interval_ != nullptr);
452 DCHECK(first_interval_->start().Value() <= start.Value()); 447 DCHECK(first_interval_->start().Value() <= start.Value());
453 DCHECK(start.Value() < first_interval_->end().Value()); 448 DCHECK(start.Value() < first_interval_->end().Value());
454 first_interval_->set_start(start); 449 first_interval_->set_start(start);
455 } 450 }
456 451
457 452
458 void LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end, 453 void LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end,
459 Zone* zone) { 454 Zone* zone) {
460 TraceAlloc("Ensure live range %d in interval [%d %d[\n", id_, start.Value(), 455 TRACE("Ensure live range %d in interval [%d %d[\n", id_, start.Value(),
461 end.Value()); 456 end.Value());
462 auto new_end = end; 457 auto new_end = end;
463 while (first_interval_ != nullptr && 458 while (first_interval_ != nullptr &&
464 first_interval_->start().Value() <= end.Value()) { 459 first_interval_->start().Value() <= end.Value()) {
465 if (first_interval_->end().Value() > end.Value()) { 460 if (first_interval_->end().Value() > end.Value()) {
466 new_end = first_interval_->end(); 461 new_end = first_interval_->end();
467 } 462 }
468 first_interval_ = first_interval_->next(); 463 first_interval_ = first_interval_->next();
469 } 464 }
470 465
471 auto new_interval = new (zone) UseInterval(start, new_end); 466 auto new_interval = new (zone) UseInterval(start, new_end);
472 new_interval->next_ = first_interval_; 467 new_interval->next_ = first_interval_;
473 first_interval_ = new_interval; 468 first_interval_ = new_interval;
474 if (new_interval->next() == nullptr) { 469 if (new_interval->next() == nullptr) {
475 last_interval_ = new_interval; 470 last_interval_ = new_interval;
476 } 471 }
477 } 472 }
478 473
479 474
480 void LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end, 475 void LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end,
481 Zone* zone) { 476 Zone* zone) {
482 TraceAlloc("Add to live range %d interval [%d %d[\n", id_, start.Value(), 477 TRACE("Add to live range %d interval [%d %d[\n", id_, start.Value(),
483 end.Value()); 478 end.Value());
484 if (first_interval_ == nullptr) { 479 if (first_interval_ == nullptr) {
485 auto interval = new (zone) UseInterval(start, end); 480 auto interval = new (zone) UseInterval(start, end);
486 first_interval_ = interval; 481 first_interval_ = interval;
487 last_interval_ = interval; 482 last_interval_ = interval;
488 } else { 483 } else {
489 if (end.Value() == first_interval_->start().Value()) { 484 if (end.Value() == first_interval_->start().Value()) {
490 first_interval_->set_start(start); 485 first_interval_->set_start(start);
491 } else if (end.Value() < first_interval_->start().Value()) { 486 } else if (end.Value() < first_interval_->start().Value()) {
492 auto interval = new (zone) UseInterval(start, end); 487 auto interval = new (zone) UseInterval(start, end);
493 interval->set_next(first_interval_); 488 interval->set_next(first_interval_);
494 first_interval_ = interval; 489 first_interval_ = interval;
495 } else { 490 } else {
496 // Order of instruction's processing (see ProcessInstructions) guarantees 491 // Order of instruction's processing (see ProcessInstructions) guarantees
497 // that each new use interval either precedes or intersects with 492 // that each new use interval either precedes or intersects with
498 // last added interval. 493 // last added interval.
499 DCHECK(start.Value() < first_interval_->end().Value()); 494 DCHECK(start.Value() < first_interval_->end().Value());
500 first_interval_->start_ = Min(start, first_interval_->start_); 495 first_interval_->start_ = Min(start, first_interval_->start_);
501 first_interval_->end_ = Max(end, first_interval_->end_); 496 first_interval_->end_ = Max(end, first_interval_->end_);
502 } 497 }
503 } 498 }
504 } 499 }
505 500
506 501
507 void LiveRange::AddUsePosition(LifetimePosition pos, 502 void LiveRange::AddUsePosition(LifetimePosition pos,
508 InstructionOperand* operand, 503 InstructionOperand* operand,
509 InstructionOperand* hint, Zone* zone) { 504 InstructionOperand* hint, Zone* zone) {
510 TraceAlloc("Add to live range %d use position %d\n", id_, pos.Value()); 505 TRACE("Add to live range %d use position %d\n", id_, pos.Value());
511 auto use_pos = new (zone) UsePosition(pos, operand, hint); 506 auto use_pos = new (zone) UsePosition(pos, operand, hint);
512 UsePosition* prev_hint = nullptr; 507 UsePosition* prev_hint = nullptr;
513 UsePosition* prev = nullptr; 508 UsePosition* prev = nullptr;
514 auto current = first_pos_; 509 auto current = first_pos_;
515 while (current != nullptr && current->pos().Value() < pos.Value()) { 510 while (current != nullptr && current->pos().Value() < pos.Value()) {
516 prev_hint = current->HasHint() ? current : prev_hint; 511 prev_hint = current->HasHint() ? current : prev_hint;
517 prev = current; 512 prev = current;
518 current = current->next(); 513 current = current->next();
519 } 514 }
520 515
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 } 699 }
705 700
706 701
707 int RegisterAllocator::FixedDoubleLiveRangeID(int index) { 702 int RegisterAllocator::FixedDoubleLiveRangeID(int index) {
708 return -index - 1 - config()->num_general_registers(); 703 return -index - 1 - config()->num_general_registers();
709 } 704 }
710 705
711 706
712 InstructionOperand* RegisterAllocator::AllocateFixed( 707 InstructionOperand* RegisterAllocator::AllocateFixed(
713 UnallocatedOperand* operand, int pos, bool is_tagged) { 708 UnallocatedOperand* operand, int pos, bool is_tagged) {
714 TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); 709 TRACE("Allocating fixed reg for op %d\n", operand->virtual_register());
715 DCHECK(operand->HasFixedPolicy()); 710 DCHECK(operand->HasFixedPolicy());
716 if (operand->HasFixedSlotPolicy()) { 711 if (operand->HasFixedSlotPolicy()) {
717 operand->ConvertTo(InstructionOperand::STACK_SLOT, 712 operand->ConvertTo(InstructionOperand::STACK_SLOT,
718 operand->fixed_slot_index()); 713 operand->fixed_slot_index());
719 } else if (operand->HasFixedRegisterPolicy()) { 714 } else if (operand->HasFixedRegisterPolicy()) {
720 int reg_index = operand->fixed_register_index(); 715 int reg_index = operand->fixed_register_index();
721 operand->ConvertTo(InstructionOperand::REGISTER, reg_index); 716 operand->ConvertTo(InstructionOperand::REGISTER, reg_index);
722 } else if (operand->HasFixedDoubleRegisterPolicy()) { 717 } else if (operand->HasFixedDoubleRegisterPolicy()) {
723 int reg_index = operand->fixed_register_index(); 718 int reg_index = operand->fixed_register_index();
724 operand->ConvertTo(InstructionOperand::DOUBLE_REGISTER, reg_index); 719 operand->ConvertTo(InstructionOperand::DOUBLE_REGISTER, reg_index);
725 } else { 720 } else {
726 UNREACHABLE(); 721 UNREACHABLE();
727 } 722 }
728 if (is_tagged) { 723 if (is_tagged) {
729 TraceAlloc("Fixed reg is tagged at %d\n", pos); 724 TRACE("Fixed reg is tagged at %d\n", pos);
730 auto instr = InstructionAt(pos); 725 auto instr = InstructionAt(pos);
731 if (instr->HasPointerMap()) { 726 if (instr->HasPointerMap()) {
732 instr->pointer_map()->RecordPointer(operand, code_zone()); 727 instr->pointer_map()->RecordPointer(operand, code_zone());
733 } 728 }
734 } 729 }
735 return operand; 730 return operand;
736 } 731 }
737 732
738 733
739 LiveRange* RegisterAllocator::NewLiveRange(int index) { 734 LiveRange* RegisterAllocator::NewLiveRange(int index) {
(...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1934 while (cur != nullptr && !cur->Covers(safe_point_pos)) { 1929 while (cur != nullptr && !cur->Covers(safe_point_pos)) {
1935 cur = cur->next(); 1930 cur = cur->next();
1936 } 1931 }
1937 if (cur == nullptr) continue; 1932 if (cur == nullptr) continue;
1938 1933
1939 // Check if the live range is spilled and the safe point is after 1934 // Check if the live range is spilled and the safe point is after
1940 // the spill position. 1935 // the spill position.
1941 if (range->HasSpillOperand() && 1936 if (range->HasSpillOperand() &&
1942 safe_point >= range->spill_start_index() && 1937 safe_point >= range->spill_start_index() &&
1943 !range->GetSpillOperand()->IsConstant()) { 1938 !range->GetSpillOperand()->IsConstant()) {
1944 TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n", 1939 TRACE("Pointer for range %d (spilled at %d) at safe point %d\n",
1945 range->id(), range->spill_start_index(), safe_point); 1940 range->id(), range->spill_start_index(), safe_point);
1946 map->RecordPointer(range->GetSpillOperand(), code_zone()); 1941 map->RecordPointer(range->GetSpillOperand(), code_zone());
1947 } 1942 }
1948 1943
1949 if (!cur->IsSpilled()) { 1944 if (!cur->IsSpilled()) {
1950 TraceAlloc( 1945 TRACE(
1951 "Pointer in register for range %d (start at %d) " 1946 "Pointer in register for range %d (start at %d) "
1952 "at safe point %d\n", 1947 "at safe point %d\n",
1953 cur->id(), cur->Start().Value(), safe_point); 1948 cur->id(), cur->Start().Value(), safe_point);
1954 InstructionOperand* operand = cur->GetAssignedOperand(operand_cache()); 1949 InstructionOperand* operand = cur->GetAssignedOperand(operand_cache());
1955 DCHECK(!operand->IsStackSlot()); 1950 DCHECK(!operand->IsStackSlot());
1956 map->RecordPointer(operand, code_zone()); 1951 map->RecordPointer(operand, code_zone());
1957 } 1952 }
1958 } 1953 }
1959 } 1954 }
1960 } 1955 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 2002
2008 while (!unhandled_live_ranges().empty()) { 2003 while (!unhandled_live_ranges().empty()) {
2009 DCHECK(UnhandledIsSorted()); 2004 DCHECK(UnhandledIsSorted());
2010 auto current = unhandled_live_ranges().back(); 2005 auto current = unhandled_live_ranges().back();
2011 unhandled_live_ranges().pop_back(); 2006 unhandled_live_ranges().pop_back();
2012 DCHECK(UnhandledIsSorted()); 2007 DCHECK(UnhandledIsSorted());
2013 auto position = current->Start(); 2008 auto position = current->Start();
2014 #ifdef DEBUG 2009 #ifdef DEBUG
2015 allocation_finger_ = position; 2010 allocation_finger_ = position;
2016 #endif 2011 #endif
2017 TraceAlloc("Processing interval %d start=%d\n", current->id(), 2012 TRACE("Processing interval %d start=%d\n", current->id(), position.Value());
2018 position.Value());
2019 2013
2020 if (!current->HasNoSpillType()) { 2014 if (!current->HasNoSpillType()) {
2021 TraceAlloc("Live range %d already has a spill operand\n", current->id()); 2015 TRACE("Live range %d already has a spill operand\n", current->id());
2022 auto next_pos = position; 2016 auto next_pos = position;
2023 if (code()->IsGapAt(next_pos.InstructionIndex())) { 2017 if (code()->IsGapAt(next_pos.InstructionIndex())) {
2024 next_pos = next_pos.NextInstruction(); 2018 next_pos = next_pos.NextInstruction();
2025 } 2019 }
2026 auto pos = current->NextUsePositionRegisterIsBeneficial(next_pos); 2020 auto pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
2027 // If the range already has a spill operand and it doesn't need a 2021 // If the range already has a spill operand and it doesn't need a
2028 // register immediately, split it and spill the first part of the range. 2022 // register immediately, split it and spill the first part of the range.
2029 if (pos == nullptr) { 2023 if (pos == nullptr) {
2030 Spill(current); 2024 Spill(current);
2031 continue; 2025 continue;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 2086
2093 2087
2094 RegisterKind RegisterAllocator::RequiredRegisterKind( 2088 RegisterKind RegisterAllocator::RequiredRegisterKind(
2095 int virtual_register) const { 2089 int virtual_register) const {
2096 return (code()->IsDouble(virtual_register)) ? DOUBLE_REGISTERS 2090 return (code()->IsDouble(virtual_register)) ? DOUBLE_REGISTERS
2097 : GENERAL_REGISTERS; 2091 : GENERAL_REGISTERS;
2098 } 2092 }
2099 2093
2100 2094
2101 void RegisterAllocator::AddToActive(LiveRange* range) { 2095 void RegisterAllocator::AddToActive(LiveRange* range) {
2102 TraceAlloc("Add live range %d to active\n", range->id()); 2096 TRACE("Add live range %d to active\n", range->id());
2103 active_live_ranges().push_back(range); 2097 active_live_ranges().push_back(range);
2104 } 2098 }
2105 2099
2106 2100
2107 void RegisterAllocator::AddToInactive(LiveRange* range) { 2101 void RegisterAllocator::AddToInactive(LiveRange* range) {
2108 TraceAlloc("Add live range %d to inactive\n", range->id()); 2102 TRACE("Add live range %d to inactive\n", range->id());
2109 inactive_live_ranges().push_back(range); 2103 inactive_live_ranges().push_back(range);
2110 } 2104 }
2111 2105
2112 2106
2113 void RegisterAllocator::AddToUnhandledSorted(LiveRange* range) { 2107 void RegisterAllocator::AddToUnhandledSorted(LiveRange* range) {
2114 if (range == nullptr || range->IsEmpty()) return; 2108 if (range == nullptr || range->IsEmpty()) return;
2115 DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled()); 2109 DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
2116 DCHECK(allocation_finger_.Value() <= range->Start().Value()); 2110 DCHECK(allocation_finger_.Value() <= range->Start().Value());
2117 for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0; 2111 for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
2118 --i) { 2112 --i) {
2119 auto cur_range = unhandled_live_ranges().at(i); 2113 auto cur_range = unhandled_live_ranges().at(i);
2120 if (!range->ShouldBeAllocatedBefore(cur_range)) continue; 2114 if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
2121 TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1); 2115 TRACE("Add live range %d to unhandled at %d\n", range->id(), i + 1);
2122 auto it = unhandled_live_ranges().begin() + (i + 1); 2116 auto it = unhandled_live_ranges().begin() + (i + 1);
2123 unhandled_live_ranges().insert(it, range); 2117 unhandled_live_ranges().insert(it, range);
2124 DCHECK(UnhandledIsSorted()); 2118 DCHECK(UnhandledIsSorted());
2125 return; 2119 return;
2126 } 2120 }
2127 TraceAlloc("Add live range %d to unhandled at start\n", range->id()); 2121 TRACE("Add live range %d to unhandled at start\n", range->id());
2128 unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range); 2122 unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
2129 DCHECK(UnhandledIsSorted()); 2123 DCHECK(UnhandledIsSorted());
2130 } 2124 }
2131 2125
2132 2126
2133 void RegisterAllocator::AddToUnhandledUnsorted(LiveRange* range) { 2127 void RegisterAllocator::AddToUnhandledUnsorted(LiveRange* range) {
2134 if (range == nullptr || range->IsEmpty()) return; 2128 if (range == nullptr || range->IsEmpty()) return;
2135 DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled()); 2129 DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
2136 TraceAlloc("Add live range %d to unhandled unsorted at end\n", range->id()); 2130 TRACE("Add live range %d to unhandled unsorted at end\n", range->id());
2137 unhandled_live_ranges().push_back(range); 2131 unhandled_live_ranges().push_back(range);
2138 } 2132 }
2139 2133
2140 2134
2141 static bool UnhandledSortHelper(LiveRange* a, LiveRange* b) { 2135 static bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
2142 DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a)); 2136 DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
2143 if (a->ShouldBeAllocatedBefore(b)) return false; 2137 if (a->ShouldBeAllocatedBefore(b)) return false;
2144 if (b->ShouldBeAllocatedBefore(a)) return true; 2138 if (b->ShouldBeAllocatedBefore(a)) return true;
2145 return a->id() < b->id(); 2139 return a->id() < b->id();
2146 } 2140 }
2147 2141
2148 2142
2149 // Sort the unhandled live ranges so that the ranges to be processed first are 2143 // Sort the unhandled live ranges so that the ranges to be processed first are
2150 // at the end of the array list. This is convenient for the register allocation 2144 // at the end of the array list. This is convenient for the register allocation
2151 // algorithm because it is efficient to remove elements from the end. 2145 // algorithm because it is efficient to remove elements from the end.
2152 void RegisterAllocator::SortUnhandled() { 2146 void RegisterAllocator::SortUnhandled() {
2153 TraceAlloc("Sort unhandled\n"); 2147 TRACE("Sort unhandled\n");
2154 std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(), 2148 std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
2155 &UnhandledSortHelper); 2149 &UnhandledSortHelper);
2156 } 2150 }
2157 2151
2158 2152
2159 bool RegisterAllocator::UnhandledIsSorted() { 2153 bool RegisterAllocator::UnhandledIsSorted() {
2160 size_t len = unhandled_live_ranges().size(); 2154 size_t len = unhandled_live_ranges().size();
2161 for (size_t i = 1; i < len; i++) { 2155 for (size_t i = 1; i < len; i++) {
2162 auto a = unhandled_live_ranges().at(i - 1); 2156 auto a = unhandled_live_ranges().at(i - 1);
2163 auto b = unhandled_live_ranges().at(i); 2157 auto b = unhandled_live_ranges().at(i);
2164 if (a->Start().Value() < b->Start().Value()) return false; 2158 if (a->Start().Value() < b->Start().Value()) return false;
2165 } 2159 }
2166 return true; 2160 return true;
2167 } 2161 }
2168 2162
2169 2163
2170 void RegisterAllocator::ActiveToHandled(LiveRange* range) { 2164 void RegisterAllocator::ActiveToHandled(LiveRange* range) {
2171 RemoveElement(&active_live_ranges(), range); 2165 RemoveElement(&active_live_ranges(), range);
2172 TraceAlloc("Moving live range %d from active to handled\n", range->id()); 2166 TRACE("Moving live range %d from active to handled\n", range->id());
2173 } 2167 }
2174 2168
2175 2169
2176 void RegisterAllocator::ActiveToInactive(LiveRange* range) { 2170 void RegisterAllocator::ActiveToInactive(LiveRange* range) {
2177 RemoveElement(&active_live_ranges(), range); 2171 RemoveElement(&active_live_ranges(), range);
2178 inactive_live_ranges().push_back(range); 2172 inactive_live_ranges().push_back(range);
2179 TraceAlloc("Moving live range %d from active to inactive\n", range->id()); 2173 TRACE("Moving live range %d from active to inactive\n", range->id());
2180 } 2174 }
2181 2175
2182 2176
2183 void RegisterAllocator::InactiveToHandled(LiveRange* range) { 2177 void RegisterAllocator::InactiveToHandled(LiveRange* range) {
2184 RemoveElement(&inactive_live_ranges(), range); 2178 RemoveElement(&inactive_live_ranges(), range);
2185 TraceAlloc("Moving live range %d from inactive to handled\n", range->id()); 2179 TRACE("Moving live range %d from inactive to handled\n", range->id());
2186 } 2180 }
2187 2181
2188 2182
2189 void RegisterAllocator::InactiveToActive(LiveRange* range) { 2183 void RegisterAllocator::InactiveToActive(LiveRange* range) {
2190 RemoveElement(&inactive_live_ranges(), range); 2184 RemoveElement(&inactive_live_ranges(), range);
2191 active_live_ranges().push_back(range); 2185 active_live_ranges().push_back(range);
2192 TraceAlloc("Moving live range %d from inactive to active\n", range->id()); 2186 TRACE("Moving live range %d from inactive to active\n", range->id());
2193 } 2187 }
2194 2188
2195 2189
2196 bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) { 2190 bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) {
2197 LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters]; 2191 LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
2198 2192
2199 for (int i = 0; i < num_registers_; i++) { 2193 for (int i = 0; i < num_registers_; i++) {
2200 free_until_pos[i] = LifetimePosition::MaxPosition(); 2194 free_until_pos[i] = LifetimePosition::MaxPosition();
2201 } 2195 }
2202 2196
2203 for (auto cur_active : active_live_ranges()) { 2197 for (auto cur_active : active_live_ranges()) {
2204 free_until_pos[cur_active->assigned_register()] = 2198 free_until_pos[cur_active->assigned_register()] =
2205 LifetimePosition::FromInstructionIndex(0); 2199 LifetimePosition::FromInstructionIndex(0);
2206 } 2200 }
2207 2201
2208 for (auto cur_inactive : inactive_live_ranges()) { 2202 for (auto cur_inactive : inactive_live_ranges()) {
2209 DCHECK(cur_inactive->End().Value() > current->Start().Value()); 2203 DCHECK(cur_inactive->End().Value() > current->Start().Value());
2210 auto next_intersection = cur_inactive->FirstIntersection(current); 2204 auto next_intersection = cur_inactive->FirstIntersection(current);
2211 if (!next_intersection.IsValid()) continue; 2205 if (!next_intersection.IsValid()) continue;
2212 int cur_reg = cur_inactive->assigned_register(); 2206 int cur_reg = cur_inactive->assigned_register();
2213 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection); 2207 free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
2214 } 2208 }
2215 2209
2216 auto hint = current->FirstHint(); 2210 auto hint = current->FirstHint();
2217 if (hint != nullptr && (hint->IsRegister() || hint->IsDoubleRegister())) { 2211 if (hint != nullptr && (hint->IsRegister() || hint->IsDoubleRegister())) {
2218 int register_index = hint->index(); 2212 int register_index = hint->index();
2219 TraceAlloc( 2213 TRACE("Found reg hint %s (free until [%d) for live range %d (end %d[).\n",
2220 "Found reg hint %s (free until [%d) for live range %d (end %d[).\n", 2214 RegisterName(register_index), free_until_pos[register_index].Value(),
2221 RegisterName(register_index), free_until_pos[register_index].Value(), 2215 current->id(), current->End().Value());
2222 current->id(), current->End().Value());
2223 2216
2224 // The desired register is free until the end of the current live range. 2217 // The desired register is free until the end of the current live range.
2225 if (free_until_pos[register_index].Value() >= current->End().Value()) { 2218 if (free_until_pos[register_index].Value() >= current->End().Value()) {
2226 TraceAlloc("Assigning preferred reg %s to live range %d\n", 2219 TRACE("Assigning preferred reg %s to live range %d\n",
2227 RegisterName(register_index), current->id()); 2220 RegisterName(register_index), current->id());
2228 SetLiveRangeAssignedRegister(current, register_index); 2221 SetLiveRangeAssignedRegister(current, register_index);
2229 return true; 2222 return true;
2230 } 2223 }
2231 } 2224 }
2232 2225
2233 // Find the register which stays free for the longest time. 2226 // Find the register which stays free for the longest time.
2234 int reg = 0; 2227 int reg = 0;
2235 for (int i = 1; i < RegisterCount(); ++i) { 2228 for (int i = 1; i < RegisterCount(); ++i) {
2236 if (free_until_pos[i].Value() > free_until_pos[reg].Value()) { 2229 if (free_until_pos[i].Value() > free_until_pos[reg].Value()) {
2237 reg = i; 2230 reg = i;
(...skipping 10 matching lines...) Expand all
2248 if (pos.Value() < current->End().Value()) { 2241 if (pos.Value() < current->End().Value()) {
2249 // Register reg is available at the range start but becomes blocked before 2242 // Register reg is available at the range start but becomes blocked before
2250 // the range end. Split current at position where it becomes blocked. 2243 // the range end. Split current at position where it becomes blocked.
2251 auto tail = SplitRangeAt(current, pos); 2244 auto tail = SplitRangeAt(current, pos);
2252 AddToUnhandledSorted(tail); 2245 AddToUnhandledSorted(tail);
2253 } 2246 }
2254 2247
2255 // Register reg is available at the range start and is free until 2248 // Register reg is available at the range start and is free until
2256 // the range end. 2249 // the range end.
2257 DCHECK(pos.Value() >= current->End().Value()); 2250 DCHECK(pos.Value() >= current->End().Value());
2258 TraceAlloc("Assigning free reg %s to live range %d\n", RegisterName(reg), 2251 TRACE("Assigning free reg %s to live range %d\n", RegisterName(reg),
2259 current->id()); 2252 current->id());
2260 SetLiveRangeAssignedRegister(current, reg); 2253 SetLiveRangeAssignedRegister(current, reg);
2261 2254
2262 return true; 2255 return true;
2263 } 2256 }
2264 2257
2265 2258
2266 void RegisterAllocator::AllocateBlockedReg(LiveRange* current) { 2259 void RegisterAllocator::AllocateBlockedReg(LiveRange* current) {
2267 auto register_use = current->NextRegisterPosition(current->Start()); 2260 auto register_use = current->NextRegisterPosition(current->Start());
2268 if (register_use == nullptr) { 2261 if (register_use == nullptr) {
2269 // There is no use in the current live range that requires a register. 2262 // There is no use in the current live range that requires a register.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2327 if (block_pos[reg].Value() < current->End().Value()) { 2320 if (block_pos[reg].Value() < current->End().Value()) {
2328 // Register becomes blocked before the current range end. Split before that 2321 // Register becomes blocked before the current range end. Split before that
2329 // position. 2322 // position.
2330 LiveRange* tail = SplitBetween(current, current->Start(), 2323 LiveRange* tail = SplitBetween(current, current->Start(),
2331 block_pos[reg].InstructionStart()); 2324 block_pos[reg].InstructionStart());
2332 AddToUnhandledSorted(tail); 2325 AddToUnhandledSorted(tail);
2333 } 2326 }
2334 2327
2335 // Register reg is not blocked for the whole range. 2328 // Register reg is not blocked for the whole range.
2336 DCHECK(block_pos[reg].Value() >= current->End().Value()); 2329 DCHECK(block_pos[reg].Value() >= current->End().Value());
2337 TraceAlloc("Assigning blocked reg %s to live range %d\n", RegisterName(reg), 2330 TRACE("Assigning blocked reg %s to live range %d\n", RegisterName(reg),
2338 current->id()); 2331 current->id());
2339 SetLiveRangeAssignedRegister(current, reg); 2332 SetLiveRangeAssignedRegister(current, reg);
2340 2333
2341 // This register was not free. Thus we need to find and spill 2334 // This register was not free. Thus we need to find and spill
2342 // parts of active and inactive live regions that use the same register 2335 // parts of active and inactive live regions that use the same register
2343 // at the same lifetime positions as current. 2336 // at the same lifetime positions as current.
2344 SplitAndSpillIntersecting(current); 2337 SplitAndSpillIntersecting(current);
2345 } 2338 }
2346 2339
2347 2340
2348 static const InstructionBlock* GetContainingLoop( 2341 static const InstructionBlock* GetContainingLoop(
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2436 bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) { 2429 bool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) {
2437 return pos.IsInstructionStart() && 2430 return pos.IsInstructionStart() &&
2438 code()->GetInstructionBlock(pos.InstructionIndex())->code_start() == 2431 code()->GetInstructionBlock(pos.InstructionIndex())->code_start() ==
2439 pos.InstructionIndex(); 2432 pos.InstructionIndex();
2440 } 2433 }
2441 2434
2442 2435
2443 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range, 2436 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
2444 LifetimePosition pos) { 2437 LifetimePosition pos) {
2445 DCHECK(!range->IsFixed()); 2438 DCHECK(!range->IsFixed());
2446 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); 2439 TRACE("Splitting live range %d at %d\n", range->id(), pos.Value());
2447 2440
2448 if (pos.Value() <= range->Start().Value()) return range; 2441 if (pos.Value() <= range->Start().Value()) return range;
2449 2442
2450 // We can't properly connect liveranges if splitting occurred at the end 2443 // We can't properly connect liveranges if splitting occurred at the end
2451 // a block. 2444 // a block.
2452 DCHECK(pos.IsInstructionStart() || 2445 DCHECK(pos.IsInstructionStart() ||
2453 (code()->GetInstructionBlock(pos.InstructionIndex())) 2446 (code()->GetInstructionBlock(pos.InstructionIndex()))
2454 ->last_instruction_index() != pos.InstructionIndex()); 2447 ->last_instruction_index() != pos.InstructionIndex());
2455 2448
2456 int vreg = GetVirtualRegister(); 2449 int vreg = GetVirtualRegister();
2457 auto result = LiveRangeFor(vreg); 2450 auto result = LiveRangeFor(vreg);
2458 range->SplitAt(pos, result, local_zone()); 2451 range->SplitAt(pos, result, local_zone());
2459 return result; 2452 return result;
2460 } 2453 }
2461 2454
2462 2455
2463 LiveRange* RegisterAllocator::SplitBetween(LiveRange* range, 2456 LiveRange* RegisterAllocator::SplitBetween(LiveRange* range,
2464 LifetimePosition start, 2457 LifetimePosition start,
2465 LifetimePosition end) { 2458 LifetimePosition end) {
2466 DCHECK(!range->IsFixed()); 2459 DCHECK(!range->IsFixed());
2467 TraceAlloc("Splitting live range %d in position between [%d, %d]\n", 2460 TRACE("Splitting live range %d in position between [%d, %d]\n", range->id(),
2468 range->id(), start.Value(), end.Value()); 2461 start.Value(), end.Value());
2469 2462
2470 auto split_pos = FindOptimalSplitPos(start, end); 2463 auto split_pos = FindOptimalSplitPos(start, end);
2471 DCHECK(split_pos.Value() >= start.Value()); 2464 DCHECK(split_pos.Value() >= start.Value());
2472 return SplitRangeAt(range, split_pos); 2465 return SplitRangeAt(range, split_pos);
2473 } 2466 }
2474 2467
2475 2468
2476 LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start, 2469 LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
2477 LifetimePosition end) { 2470 LifetimePosition end) {
2478 int start_instr = start.InstructionIndex(); 2471 int start_instr = start.InstructionIndex();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 } else { 2540 } else {
2548 // The split result does not intersect with [start, end[. 2541 // The split result does not intersect with [start, end[.
2549 // Nothing to spill. Just put it to unhandled as whole. 2542 // Nothing to spill. Just put it to unhandled as whole.
2550 AddToUnhandledSorted(second_part); 2543 AddToUnhandledSorted(second_part);
2551 } 2544 }
2552 } 2545 }
2553 2546
2554 2547
2555 void RegisterAllocator::Spill(LiveRange* range) { 2548 void RegisterAllocator::Spill(LiveRange* range) {
2556 DCHECK(!range->IsSpilled()); 2549 DCHECK(!range->IsSpilled());
2557 TraceAlloc("Spilling live range %d\n", range->id()); 2550 TRACE("Spilling live range %d\n", range->id());
2558 auto first = range->TopLevel(); 2551 auto first = range->TopLevel();
2559 if (first->HasNoSpillType()) { 2552 if (first->HasNoSpillType()) {
2560 AssignSpillRangeToLiveRange(first); 2553 AssignSpillRangeToLiveRange(first);
2561 } 2554 }
2562 range->MakeSpilled(); 2555 range->MakeSpilled();
2563 } 2556 }
2564 2557
2565 2558
2566 int RegisterAllocator::RegisterCount() const { return num_registers_; } 2559 int RegisterAllocator::RegisterCount() const { return num_registers_; }
2567 2560
(...skipping 18 matching lines...) Expand all
2586 } else { 2579 } else {
2587 DCHECK(range->Kind() == GENERAL_REGISTERS); 2580 DCHECK(range->Kind() == GENERAL_REGISTERS);
2588 assigned_registers_->Add(reg); 2581 assigned_registers_->Add(reg);
2589 } 2582 }
2590 range->set_assigned_register(reg, operand_cache()); 2583 range->set_assigned_register(reg, operand_cache());
2591 } 2584 }
2592 2585
2593 } // namespace compiler 2586 } // namespace compiler
2594 } // namespace internal 2587 } // namespace internal
2595 } // namespace v8 2588 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698