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

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

Issue 1501363002: [turbofan] regalloc: model context and function mark as reg-defined. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years 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
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 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 if (move_op->IsEliminated()) continue; 767 if (move_op->IsEliminated()) continue;
768 if (move_op->source().Equals(*to_spill->operand) && 768 if (move_op->source().Equals(*to_spill->operand) &&
769 move_op->destination().Equals(op)) { 769 move_op->destination().Equals(op)) {
770 found = true; 770 found = true;
771 if (has_preassigned_slot()) move_op->Eliminate(); 771 if (has_preassigned_slot()) move_op->Eliminate();
772 break; 772 break;
773 } 773 }
774 } 774 }
775 if (found) continue; 775 if (found) continue;
776 } 776 }
777 move->AddMove(*to_spill->operand, op); 777 if (!has_preassigned_slot()) {
778 move->AddMove(*to_spill->operand, op);
779 }
778 } 780 }
779 } 781 }
780 782
781 783
782 void TopLevelLiveRange::SetSpillOperand(InstructionOperand* operand) { 784 void TopLevelLiveRange::SetSpillOperand(InstructionOperand* operand) {
783 DCHECK(HasNoSpillType()); 785 DCHECK(HasNoSpillType());
784 DCHECK(!operand->IsUnallocated() && !operand->IsImmediate()); 786 DCHECK(!operand->IsUnallocated() && !operand->IsImmediate());
785 set_spill_type(SpillType::kSpillOperand); 787 set_spill_type(SpillType::kSpillOperand);
786 spill_operand_ = operand; 788 spill_operand_ = operand;
787 } 789 }
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || 1128 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
1127 this->End() <= other->use_interval_->start() || 1129 this->End() <= other->use_interval_->start() ||
1128 other->End() <= this->use_interval_->start()) { 1130 other->End() <= this->use_interval_->start()) {
1129 return false; 1131 return false;
1130 } 1132 }
1131 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); 1133 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
1132 } 1134 }
1133 1135
1134 1136
1135 bool SpillRange::TryMerge(SpillRange* other) { 1137 bool SpillRange::TryMerge(SpillRange* other) {
1138 if (HasSlot() || other->HasSlot()) return false;
1136 // TODO(dcarney): byte widths should be compared here not kinds. 1139 // TODO(dcarney): byte widths should be compared here not kinds.
1137 if (live_ranges_[0]->kind() != other->live_ranges_[0]->kind() || 1140 if (live_ranges_[0]->kind() != other->live_ranges_[0]->kind() ||
1138 IsIntersectingWith(other)) { 1141 IsIntersectingWith(other)) {
1139 return false; 1142 return false;
1140 } 1143 }
1141 1144
1142 auto max = LifetimePosition::MaxPosition(); 1145 auto max = LifetimePosition::MaxPosition();
1143 if (End() < other->End() && other->End() != max) { 1146 if (End() < other->End() && other->End() != max) {
1144 end_position_ = other->End(); 1147 end_position_ = other->End();
1145 } 1148 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 live_ranges_(code->VirtualRegisterCount() * 2, nullptr, 1230 live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
1228 allocation_zone()), 1231 allocation_zone()),
1229 fixed_live_ranges_(this->config()->num_general_registers(), nullptr, 1232 fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
1230 allocation_zone()), 1233 allocation_zone()),
1231 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, 1234 fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
1232 allocation_zone()), 1235 allocation_zone()),
1233 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()), 1236 spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
1234 delayed_references_(allocation_zone()), 1237 delayed_references_(allocation_zone()),
1235 assigned_registers_(nullptr), 1238 assigned_registers_(nullptr),
1236 assigned_double_registers_(nullptr), 1239 assigned_double_registers_(nullptr),
1237 virtual_register_count_(code->VirtualRegisterCount()) { 1240 virtual_register_count_(code->VirtualRegisterCount()),
1241 preassigned_slot_ranges_(allocation_zone()) {
1238 DCHECK(this->config()->num_general_registers() <= 1242 DCHECK(this->config()->num_general_registers() <=
1239 RegisterConfiguration::kMaxGeneralRegisters); 1243 RegisterConfiguration::kMaxGeneralRegisters);
1240 DCHECK(this->config()->num_double_registers() <= 1244 DCHECK(this->config()->num_double_registers() <=
1241 RegisterConfiguration::kMaxDoubleRegisters); 1245 RegisterConfiguration::kMaxDoubleRegisters);
1242 assigned_registers_ = new (code_zone()) 1246 assigned_registers_ = new (code_zone())
1243 BitVector(this->config()->num_general_registers(), code_zone()); 1247 BitVector(this->config()->num_general_registers(), code_zone());
1244 assigned_double_registers_ = new (code_zone()) 1248 assigned_double_registers_ = new (code_zone())
1245 BitVector(this->config()->num_double_registers(), code_zone()); 1249 BitVector(this->config()->num_double_registers(), code_zone());
1246 this->frame()->SetAllocatedRegisters(assigned_registers_); 1250 this->frame()->SetAllocatedRegisters(assigned_registers_);
1247 this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_); 1251 this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1619 auto first_output = UnallocatedOperand::cast(output); 1623 auto first_output = UnallocatedOperand::cast(output);
1620 auto range = 1624 auto range =
1621 data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); 1625 data()->GetOrCreateLiveRangeFor(first_output->virtual_register());
1622 bool assigned = false; 1626 bool assigned = false;
1623 if (first_output->HasFixedPolicy()) { 1627 if (first_output->HasFixedPolicy()) {
1624 int output_vreg = first_output->virtual_register(); 1628 int output_vreg = first_output->virtual_register();
1625 UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); 1629 UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
1626 bool is_tagged = code()->IsReference(output_vreg); 1630 bool is_tagged = code()->IsReference(output_vreg);
1627 if (first_output->HasSecondaryStorage()) { 1631 if (first_output->HasSecondaryStorage()) {
1628 range->MarkHasPreassignedSlot(); 1632 range->MarkHasPreassignedSlot();
1629 InstructionOperand* spill_op = AllocatedOperand::New( 1633 data()->preassigned_slot_ranges()[range] =
1630 data()->code_zone(), LocationOperand::LocationKind::STACK_SLOT, 1634 first_output->GetSecondaryStorage();
1631 range->machine_type(), first_output->GetSecondaryStorage());
1632 range->RecordSpillLocation(allocation_zone(), instr_index + 1,
1633 first_output);
1634 range->SetSpillOperand(spill_op);
1635 range->SetSpillStartIndex(instr_index + 1);
1636 assigned = true;
1637 } 1635 }
1638 AllocateFixed(first_output, instr_index, is_tagged); 1636 AllocateFixed(first_output, instr_index, is_tagged);
1639 1637
1640 // This value is produced on the stack, we never need to spill it. 1638 // This value is produced on the stack, we never need to spill it.
1641 if (first_output->IsStackSlot()) { 1639 if (first_output->IsStackSlot()) {
1642 DCHECK(LocationOperand::cast(first_output)->index() < 1640 DCHECK(LocationOperand::cast(first_output)->index() <
1643 data()->frame()->GetTotalFrameSlotCount()); 1641 data()->frame()->GetTotalFrameSlotCount());
1644 range->SetSpillOperand(LocationOperand::cast(first_output)); 1642 range->SetSpillOperand(LocationOperand::cast(first_output));
1645 range->SetSpillStartIndex(instr_index + 1); 1643 range->SetSpillStartIndex(instr_index + 1);
1646 assigned = true; 1644 assigned = true;
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
2157 if (pos->type() == UsePositionType::kRequiresSlot) continue; 2155 if (pos->type() == UsePositionType::kRequiresSlot) continue;
2158 UsePositionType new_type = UsePositionType::kAny; 2156 UsePositionType new_type = UsePositionType::kAny;
2159 // Can't mark phis as needing a register. 2157 // Can't mark phis as needing a register.
2160 if (!pos->pos().IsGapPosition()) { 2158 if (!pos->pos().IsGapPosition()) {
2161 new_type = UsePositionType::kRequiresRegister; 2159 new_type = UsePositionType::kRequiresRegister;
2162 } 2160 }
2163 pos->set_type(new_type, true); 2161 pos->set_type(new_type, true);
2164 } 2162 }
2165 } 2163 }
2166 } 2164 }
2165 for (auto preassigned : data()->preassigned_slot_ranges()) {
2166 TopLevelLiveRange* range = preassigned.first;
2167 int slot_id = preassigned.second;
2168 SpillRange* spill = range->HasSpillRange()
2169 ? range->GetSpillRange()
2170 : data()->AssignSpillRangeToLiveRange(range);
2171 spill->set_assigned_slot(slot_id);
2172 }
2167 #ifdef DEBUG 2173 #ifdef DEBUG
2168 Verify(); 2174 Verify();
2169 #endif 2175 #endif
2170 } 2176 }
2171 2177
2172 2178
2173 void LiveRangeBuilder::MapPhiHint(InstructionOperand* operand, 2179 void LiveRangeBuilder::MapPhiHint(InstructionOperand* operand,
2174 UsePosition* use_pos) { 2180 UsePosition* use_pos) {
2175 DCHECK(!use_pos->IsResolved()); 2181 DCHECK(!use_pos->IsResolved());
2176 auto res = phi_hints_.insert(std::make_pair(operand, use_pos)); 2182 auto res = phi_hints_.insert(std::make_pair(operand, use_pos));
(...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after
2976 SpillRange* other = spill_ranges[j]; 2982 SpillRange* other = spill_ranges[j];
2977 if (other != nullptr && !other->IsEmpty()) { 2983 if (other != nullptr && !other->IsEmpty()) {
2978 range->TryMerge(other); 2984 range->TryMerge(other);
2979 } 2985 }
2980 } 2986 }
2981 } 2987 }
2982 // Allocate slots for the merged spill ranges. 2988 // Allocate slots for the merged spill ranges.
2983 for (SpillRange* range : spill_ranges) { 2989 for (SpillRange* range : spill_ranges) {
2984 if (range == nullptr || range->IsEmpty()) continue; 2990 if (range == nullptr || range->IsEmpty()) continue;
2985 // Allocate a new operand referring to the spill slot. 2991 // Allocate a new operand referring to the spill slot.
2986 int byte_width = range->ByteWidth(); 2992 if (!range->HasSlot()) {
2987 int index = data()->frame()->AllocateSpillSlot(byte_width); 2993 int byte_width = range->ByteWidth();
2988 range->set_assigned_slot(index); 2994 int index = data()->frame()->AllocateSpillSlot(byte_width);
2995 range->set_assigned_slot(index);
2996 }
2989 } 2997 }
2990 } 2998 }
2991 2999
2992 3000
2993 void OperandAssigner::CommitAssignment() { 3001 void OperandAssigner::CommitAssignment() {
2994 for (TopLevelLiveRange* top_range : data()->live_ranges()) { 3002 for (TopLevelLiveRange* top_range : data()->live_ranges()) {
2995 if (top_range == nullptr || top_range->IsEmpty()) continue; 3003 if (top_range == nullptr || top_range->IsEmpty()) continue;
2996 InstructionOperand spill_operand; 3004 InstructionOperand spill_operand;
2997 if (top_range->HasSpillOperand()) { 3005 if (top_range->HasSpillOperand()) {
2998 spill_operand = *top_range->TopLevel()->GetSpillOperand(); 3006 spill_operand = *top_range->TopLevel()->GetSpillOperand();
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
3445 auto eliminate = moves->PrepareInsertAfter(move); 3453 auto eliminate = moves->PrepareInsertAfter(move);
3446 to_insert.push_back(move); 3454 to_insert.push_back(move);
3447 if (eliminate != nullptr) to_eliminate.push_back(eliminate); 3455 if (eliminate != nullptr) to_eliminate.push_back(eliminate);
3448 } 3456 }
3449 } 3457 }
3450 3458
3451 3459
3452 } // namespace compiler 3460 } // namespace compiler
3453 } // namespace internal 3461 } // namespace internal
3454 } // namespace v8 3462 } // namespace v8
OLDNEW
« src/compiler/register-allocator.h ('K') | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698