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

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

Issue 1086563004: [turbofan] break link between split use intervals (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 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') | 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/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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 } 105 }
106 106
107 107
108 void UsePosition::set_type(UsePositionType type, bool register_beneficial) { 108 void UsePosition::set_type(UsePositionType type, bool register_beneficial) {
109 DCHECK_IMPLIES(type == UsePositionType::kRequiresSlot, !register_beneficial); 109 DCHECK_IMPLIES(type == UsePositionType::kRequiresSlot, !register_beneficial);
110 flags_ = TypeField::encode(type) | 110 flags_ = TypeField::encode(type) |
111 RegisterBeneficialField::encode(register_beneficial); 111 RegisterBeneficialField::encode(register_beneficial);
112 } 112 }
113 113
114 114
115 void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) { 115 UseInterval* UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
116 DCHECK(Contains(pos) && pos.Value() != start().Value()); 116 DCHECK(Contains(pos) && pos.Value() != start().Value());
117 auto after = new (zone) UseInterval(pos, end_); 117 auto after = new (zone) UseInterval(pos, end_);
118 after->next_ = next_; 118 after->next_ = next_;
119 next_ = after; 119 next_ = nullptr;
120 end_ = pos; 120 end_ = pos;
121 return after;
121 } 122 }
122 123
123 124
124 struct LiveRange::SpillAtDefinitionList : ZoneObject { 125 struct LiveRange::SpillAtDefinitionList : ZoneObject {
125 SpillAtDefinitionList(int gap_index, InstructionOperand* operand, 126 SpillAtDefinitionList(int gap_index, InstructionOperand* operand,
126 SpillAtDefinitionList* next) 127 SpillAtDefinitionList* next)
127 : gap_index(gap_index), operand(operand), next(next) {} 128 : gap_index(gap_index), operand(operand), next(next) {}
128 const int gap_index; 129 const int gap_index;
129 InstructionOperand* const operand; 130 InstructionOperand* const operand;
130 SpillAtDefinitionList* const next; 131 SpillAtDefinitionList* const next;
(...skipping 16 matching lines...) Expand all
147 current_interval_(nullptr), 148 current_interval_(nullptr),
148 last_processed_use_(nullptr), 149 last_processed_use_(nullptr),
149 current_hint_operand_(nullptr), 150 current_hint_operand_(nullptr),
150 spill_start_index_(kMaxInt), 151 spill_start_index_(kMaxInt),
151 spill_type_(SpillType::kNoSpillType), 152 spill_type_(SpillType::kNoSpillType),
152 spill_operand_(nullptr), 153 spill_operand_(nullptr),
153 spills_at_definition_(nullptr) {} 154 spills_at_definition_(nullptr) {}
154 155
155 156
156 void LiveRange::Verify() const { 157 void LiveRange::Verify() const {
157 UsePosition* cur = first_pos_; 158 // Walk the positions, verifying that each is in an interval.
158 while (cur != nullptr) { 159 auto interval = first_interval_;
159 CHECK(Start().Value() <= cur->pos().Value() && 160 for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) {
160 cur->pos().Value() <= End().Value()); 161 CHECK(Start().Value() <= pos->pos().Value());
161 cur = cur->next(); 162 CHECK(pos->pos().Value() <= End().Value());
163 CHECK(interval != nullptr);
164 while (!interval->Contains(pos->pos()) &&
165 interval->end().Value() != pos->pos().Value()) {
166 interval = interval->next();
167 CHECK(interval != nullptr);
168 }
162 } 169 }
163 } 170 }
164 171
165 172
166 bool LiveRange::HasOverlap(UseInterval* target) const {
167 UseInterval* current_interval = first_interval_;
168 while (current_interval != nullptr) {
169 // Intervals overlap if the start of one is contained in the other.
170 if (current_interval->Contains(target->start()) ||
171 target->Contains(current_interval->start())) {
172 return true;
173 }
174 current_interval = current_interval->next();
175 }
176 return false;
177 }
178
179
180 void LiveRange::set_assigned_register(int reg) { 173 void LiveRange::set_assigned_register(int reg) {
181 DCHECK(!HasRegisterAssigned() && !IsSpilled()); 174 DCHECK(!HasRegisterAssigned() && !IsSpilled());
182 assigned_register_ = reg; 175 assigned_register_ = reg;
183 } 176 }
184 177
185 178
186 void LiveRange::MakeSpilled() { 179 void LiveRange::MakeSpilled() {
187 DCHECK(!IsSpilled()); 180 DCHECK(!IsSpilled());
188 DCHECK(!TopLevel()->HasNoSpillType()); 181 DCHECK(!TopLevel()->HasNoSpillType());
189 spilled_ = true; 182 spilled_ = true;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 352
360 // If the split position coincides with the beginning of a use interval 353 // If the split position coincides with the beginning of a use interval
361 // we need to split use positons in a special way. 354 // we need to split use positons in a special way.
362 bool split_at_start = false; 355 bool split_at_start = false;
363 356
364 if (current->start().Value() == position.Value()) { 357 if (current->start().Value() == position.Value()) {
365 // When splitting at start we need to locate the previous use interval. 358 // When splitting at start we need to locate the previous use interval.
366 current = first_interval_; 359 current = first_interval_;
367 } 360 }
368 361
362 UseInterval* after = nullptr;
369 while (current != nullptr) { 363 while (current != nullptr) {
370 if (current->Contains(position)) { 364 if (current->Contains(position)) {
371 current->SplitAt(position, zone); 365 after = current->SplitAt(position, zone);
372 break; 366 break;
373 } 367 }
374 auto next = current->next(); 368 auto next = current->next();
375 if (next->start().Value() >= position.Value()) { 369 if (next->start().Value() >= position.Value()) {
376 split_at_start = (next->start().Value() == position.Value()); 370 split_at_start = (next->start().Value() == position.Value());
377 break; 371 break;
378 } 372 }
379 current = next; 373 current = next;
380 } 374 }
381 375
382 // Partition original use intervals to the two live ranges. 376 // Partition original use intervals to the two live ranges.
383 auto before = current; 377 auto before = current;
384 auto after = before->next(); 378 if (after == nullptr) after = before->next();
385 result->last_interval_ = 379 result->last_interval_ =
386 (last_interval_ == before) 380 (last_interval_ == before)
387 ? after // Only interval in the range after split. 381 ? after // Only interval in the range after split.
388 : last_interval_; // Last interval of the original range. 382 : last_interval_; // Last interval of the original range.
389 result->first_interval_ = after; 383 result->first_interval_ = after;
390 last_interval_ = before; 384 last_interval_ = before;
391 385
392 // Find the last use position before the split and the first use 386 // Find the last use position before the split and the first use
393 // position after it. 387 // position after it.
394 auto use_after = first_pos_; 388 auto use_after = first_pos_;
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 if (interval2->end().Value() > interval1->start().Value()) { 619 if (interval2->end().Value() > interval1->start().Value()) {
626 return true; 620 return true;
627 } 621 }
628 interval2 = interval2->next(); 622 interval2 = interval2->next();
629 } 623 }
630 } 624 }
631 return false; 625 return false;
632 } 626 }
633 627
634 628
635 SpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) { 629 SpillRange::SpillRange(LiveRange* parent, Zone* zone) : live_ranges_(zone) {
636 auto src = range->first_interval(); 630 DCHECK(!parent->IsChild());
637 UseInterval* result = nullptr; 631 UseInterval* result = nullptr;
638 UseInterval* node = nullptr; 632 UseInterval* node = nullptr;
639 // Copy the nodes 633 // Copy the intervals for all ranges.
640 while (src != nullptr) { 634 for (auto range = parent; range != nullptr; range = range->next()) {
641 auto new_node = new (zone) UseInterval(src->start(), src->end()); 635 auto src = range->first_interval();
642 if (result == nullptr) { 636 while (src != nullptr) {
643 result = new_node; 637 auto new_node = new (zone) UseInterval(src->start(), src->end());
644 } else { 638 if (result == nullptr) {
645 node->set_next(new_node); 639 result = new_node;
640 } else {
641 node->set_next(new_node);
642 }
643 node = new_node;
644 src = src->next();
646 } 645 }
647 node = new_node;
648 src = src->next();
649 } 646 }
650 use_interval_ = result; 647 use_interval_ = result;
651 live_ranges().push_back(range); 648 live_ranges().push_back(parent);
652 end_position_ = node->end(); 649 end_position_ = node->end();
653 DCHECK(!range->HasSpillRange()); 650 DCHECK(!parent->HasSpillRange());
654 range->SetSpillRange(this); 651 parent->SetSpillRange(this);
655 } 652 }
656 653
657 654
658 bool SpillRange::IsIntersectingWith(SpillRange* other) const { 655 bool SpillRange::IsIntersectingWith(SpillRange* other) const {
659 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || 656 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
660 this->End().Value() <= other->use_interval_->start().Value() || 657 this->End().Value() <= other->use_interval_->start().Value() ||
661 other->End().Value() <= this->use_interval_->start().Value()) { 658 other->End().Value() <= this->use_interval_->start().Value()) {
662 return false; 659 return false;
663 } 660 }
664 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); 661 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
(...skipping 2199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2864 auto eliminate = moves->PrepareInsertAfter(move); 2861 auto eliminate = moves->PrepareInsertAfter(move);
2865 to_insert.push_back(move); 2862 to_insert.push_back(move);
2866 if (eliminate != nullptr) to_eliminate.push_back(eliminate); 2863 if (eliminate != nullptr) to_eliminate.push_back(eliminate);
2867 } 2864 }
2868 } 2865 }
2869 2866
2870 2867
2871 } // namespace compiler 2868 } // namespace compiler
2872 } // namespace internal 2869 } // namespace internal
2873 } // namespace v8 2870 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698