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

Unified Diff: src/compiler/register-allocator.cc

Issue 1099093002: [turbofan] Split ConstraintBuilder off of LiveRangeBuilder. (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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/register-allocator.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/register-allocator.cc
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
index c96a7e94f7fe333ecb78d546b27d90a40f012ba6..cff644d24c9c42167c62b4ed2b37191511256e71 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -69,6 +69,11 @@ bool IsBlockBoundary(const InstructionSequence* code, LifetimePosition pos) {
}
+Instruction* GetLastInstruction(InstructionSequence* code,
+ const InstructionBlock* block) {
+ return code->InstructionAt(block->last_instruction_index());
+}
+
} // namespace
@@ -833,67 +838,12 @@ void RegisterAllocationData::SetLiveRangeAssignedRegister(LiveRange* range,
}
-LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data)
+ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
: data_(data) {}
-BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block) {
- // Compute live out for the given block, except not including backward
- // successor edges.
- auto live_out = new (allocation_zone())
- BitVector(code()->VirtualRegisterCount(), allocation_zone());
-
- // Process all successor blocks.
- for (auto succ : block->successors()) {
- // Add values live on entry to the successor. Note the successor's
- // live_in will not be computed yet for backwards edges.
- auto live_in = live_in_sets()[succ.ToSize()];
- if (live_in != nullptr) live_out->Union(*live_in);
-
- // All phi input operands corresponding to this successor edge are live
- // out from this block.
- auto successor = code()->InstructionBlockAt(succ);
- size_t index = successor->PredecessorIndexOf(block->rpo_number());
- DCHECK(index < successor->PredecessorCount());
- for (auto phi : successor->phis()) {
- live_out->Add(phi->operands()[index]);
- }
- }
- return live_out;
-}
-
-
-void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
- BitVector* live_out) {
- // Add an interval that includes the entire block to the live range for
- // each live_out value.
- auto start = LifetimePosition::GapFromInstructionIndex(
- block->first_instruction_index());
- auto end = LifetimePosition::InstructionFromInstructionIndex(
- block->last_instruction_index()).NextStart();
- BitVector::Iterator iterator(live_out);
- while (!iterator.Done()) {
- int operand_index = iterator.Current();
- auto range = LiveRangeFor(operand_index);
- range->AddUseInterval(start, end, allocation_zone());
- iterator.Advance();
- }
-}
-
-
-Instruction* LiveRangeBuilder::GetLastInstruction(
- const InstructionBlock* block) {
- return code()->InstructionAt(block->last_instruction_index());
-}
-
-
-int LiveRangeBuilder::FixedDoubleLiveRangeID(int index) {
- return -index - 1 - config()->num_general_registers();
-}
-
-
-InstructionOperand* LiveRangeBuilder::AllocateFixed(UnallocatedOperand* operand,
- int pos, bool is_tagged) {
+InstructionOperand* ConstraintBuilder::AllocateFixed(
+ UnallocatedOperand* operand, int pos, bool is_tagged) {
TRACE("Allocating fixed reg for op %d\n", operand->virtual_register());
DCHECK(operand->HasFixedPolicy());
InstructionOperand allocated;
@@ -921,87 +871,14 @@ InstructionOperand* LiveRangeBuilder::AllocateFixed(UnallocatedOperand* operand,
}
-LiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
- DCHECK(index < config()->num_general_registers());
- auto result = fixed_live_ranges()[index];
- if (result == nullptr) {
- result = data()->NewLiveRange(FixedLiveRangeID(index));
- DCHECK(result->IsFixed());
- result->set_kind(GENERAL_REGISTERS);
- data()->SetLiveRangeAssignedRegister(result, index);
- fixed_live_ranges()[index] = result;
- }
- return result;
-}
-
-
-LiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) {
- DCHECK(index < config()->num_aliased_double_registers());
- auto result = fixed_double_live_ranges()[index];
- if (result == nullptr) {
- result = data()->NewLiveRange(FixedDoubleLiveRangeID(index));
- DCHECK(result->IsFixed());
- result->set_kind(DOUBLE_REGISTERS);
- data()->SetLiveRangeAssignedRegister(result, index);
- fixed_double_live_ranges()[index] = result;
- }
- return result;
-}
-
-
-LiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
- if (operand->IsUnallocated()) {
- return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register());
- } else if (operand->IsConstant()) {
- return LiveRangeFor(ConstantOperand::cast(operand)->virtual_register());
- } else if (operand->IsRegister()) {
- return FixedLiveRangeFor(RegisterOperand::cast(operand)->index());
- } else if (operand->IsDoubleRegister()) {
- return FixedDoubleLiveRangeFor(
- DoubleRegisterOperand::cast(operand)->index());
- } else {
- return nullptr;
- }
-}
-
-
-void LiveRangeBuilder::Define(LifetimePosition position,
- InstructionOperand* operand,
- InstructionOperand* hint) {
- auto range = LiveRangeFor(operand);
- if (range == nullptr) return;
-
- if (range->IsEmpty() || range->Start().Value() > position.Value()) {
- // Can happen if there is a definition without use.
- range->AddUseInterval(position, position.NextStart(), allocation_zone());
- range->AddUsePosition(position.NextStart(), nullptr, nullptr,
- allocation_zone());
- } else {
- range->ShortenTo(position);
- }
-
- if (operand->IsUnallocated()) {
- auto unalloc_operand = UnallocatedOperand::cast(operand);
- range->AddUsePosition(position, unalloc_operand, hint, allocation_zone());
- }
-}
-
-
-void LiveRangeBuilder::Use(LifetimePosition block_start,
- LifetimePosition position,
- InstructionOperand* operand,
- InstructionOperand* hint) {
- auto range = LiveRangeFor(operand);
- if (range == nullptr) return;
- if (operand->IsUnallocated()) {
- UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
- range->AddUsePosition(position, unalloc_operand, hint, allocation_zone());
+void ConstraintBuilder::MeetRegisterConstraints() {
+ for (auto block : code()->instruction_blocks()) {
+ MeetRegisterConstraints(block);
}
- range->AddUseInterval(block_start, position, allocation_zone());
}
-void LiveRangeBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
+void ConstraintBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
int start = block->first_instruction_index();
int end = block->last_instruction_index();
DCHECK_NE(-1, start);
@@ -1014,7 +891,7 @@ void LiveRangeBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
}
-void LiveRangeBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
+void ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
const InstructionBlock* block) {
int end = block->last_instruction_index();
auto last_instruction = InstructionAt(end);
@@ -1060,7 +937,7 @@ void LiveRangeBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
}
-void LiveRangeBuilder::MeetConstraintsAfter(int instr_index) {
+void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
auto first = InstructionAt(instr_index);
// Handle fixed temporaries.
for (size_t i = 0; i < first->TempCount(); i++) {
@@ -1108,7 +985,7 @@ void LiveRangeBuilder::MeetConstraintsAfter(int instr_index) {
}
-void LiveRangeBuilder::MeetConstraintsBefore(int instr_index) {
+void ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
auto second = InstructionAt(instr_index);
// Handle fixed input operands of second instruction.
for (size_t i = 0; i < second->InputCount(); i++) {
@@ -1153,6 +1030,177 @@ void LiveRangeBuilder::MeetConstraintsBefore(int instr_index) {
}
+void ConstraintBuilder::ResolvePhis() {
+ // Process the blocks in reverse order.
+ for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
+ ResolvePhis(block);
+ }
+}
+
+
+void ConstraintBuilder::ResolvePhis(const InstructionBlock* block) {
+ for (auto phi : block->phis()) {
+ int phi_vreg = phi->virtual_register();
+ auto map_value = new (allocation_zone())
+ RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
+ auto res = data()->phi_map().insert(std::make_pair(phi_vreg, map_value));
+ DCHECK(res.second);
+ USE(res);
+ auto& output = phi->output();
+ for (size_t i = 0; i < phi->operands().size(); ++i) {
+ InstructionBlock* cur_block =
+ code()->InstructionBlockAt(block->predecessors()[i]);
+ UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
+ auto move = data()->AddGapMove(cur_block->last_instruction_index(),
+ Instruction::END, input, output);
+ map_value->incoming_moves.push_back(move);
+ DCHECK(!InstructionAt(cur_block->last_instruction_index())
+ ->HasReferenceMap());
+ }
+ auto live_range = LiveRangeFor(phi_vreg);
+ int gap_index = block->first_instruction_index();
+ live_range->SpillAtDefinition(allocation_zone(), gap_index, &output);
+ live_range->SetSpillStartIndex(gap_index);
+ // We use the phi-ness of some nodes in some later heuristics.
+ live_range->set_is_phi(true);
+ live_range->set_is_non_loop_phi(!block->IsLoopHeader());
+ }
+}
+
+
+LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data)
+ : data_(data) {}
+
+
+BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block) {
+ // Compute live out for the given block, except not including backward
+ // successor edges.
+ auto live_out = new (allocation_zone())
+ BitVector(code()->VirtualRegisterCount(), allocation_zone());
+
+ // Process all successor blocks.
+ for (auto succ : block->successors()) {
+ // Add values live on entry to the successor. Note the successor's
+ // live_in will not be computed yet for backwards edges.
+ auto live_in = live_in_sets()[succ.ToSize()];
+ if (live_in != nullptr) live_out->Union(*live_in);
+
+ // All phi input operands corresponding to this successor edge are live
+ // out from this block.
+ auto successor = code()->InstructionBlockAt(succ);
+ size_t index = successor->PredecessorIndexOf(block->rpo_number());
+ DCHECK(index < successor->PredecessorCount());
+ for (auto phi : successor->phis()) {
+ live_out->Add(phi->operands()[index]);
+ }
+ }
+ return live_out;
+}
+
+
+void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
+ BitVector* live_out) {
+ // Add an interval that includes the entire block to the live range for
+ // each live_out value.
+ auto start = LifetimePosition::GapFromInstructionIndex(
+ block->first_instruction_index());
+ auto end = LifetimePosition::InstructionFromInstructionIndex(
+ block->last_instruction_index()).NextStart();
+ BitVector::Iterator iterator(live_out);
+ while (!iterator.Done()) {
+ int operand_index = iterator.Current();
+ auto range = LiveRangeFor(operand_index);
+ range->AddUseInterval(start, end, allocation_zone());
+ iterator.Advance();
+ }
+}
+
+
+int LiveRangeBuilder::FixedDoubleLiveRangeID(int index) {
+ return -index - 1 - config()->num_general_registers();
+}
+
+
+LiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
+ DCHECK(index < config()->num_general_registers());
+ auto result = data()->fixed_live_ranges()[index];
+ if (result == nullptr) {
+ result = data()->NewLiveRange(FixedLiveRangeID(index));
+ DCHECK(result->IsFixed());
+ result->set_kind(GENERAL_REGISTERS);
+ data()->SetLiveRangeAssignedRegister(result, index);
+ data()->fixed_live_ranges()[index] = result;
+ }
+ return result;
+}
+
+
+LiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) {
+ DCHECK(index < config()->num_aliased_double_registers());
+ auto result = data()->fixed_double_live_ranges()[index];
+ if (result == nullptr) {
+ result = data()->NewLiveRange(FixedDoubleLiveRangeID(index));
+ DCHECK(result->IsFixed());
+ result->set_kind(DOUBLE_REGISTERS);
+ data()->SetLiveRangeAssignedRegister(result, index);
+ data()->fixed_double_live_ranges()[index] = result;
+ }
+ return result;
+}
+
+
+LiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
+ if (operand->IsUnallocated()) {
+ return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register());
+ } else if (operand->IsConstant()) {
+ return LiveRangeFor(ConstantOperand::cast(operand)->virtual_register());
+ } else if (operand->IsRegister()) {
+ return FixedLiveRangeFor(RegisterOperand::cast(operand)->index());
+ } else if (operand->IsDoubleRegister()) {
+ return FixedDoubleLiveRangeFor(
+ DoubleRegisterOperand::cast(operand)->index());
+ } else {
+ return nullptr;
+ }
+}
+
+
+void LiveRangeBuilder::Define(LifetimePosition position,
+ InstructionOperand* operand,
+ InstructionOperand* hint) {
+ auto range = LiveRangeFor(operand);
+ if (range == nullptr) return;
+
+ if (range->IsEmpty() || range->Start().Value() > position.Value()) {
+ // Can happen if there is a definition without use.
+ range->AddUseInterval(position, position.NextStart(), allocation_zone());
+ range->AddUsePosition(position.NextStart(), nullptr, nullptr,
+ allocation_zone());
+ } else {
+ range->ShortenTo(position);
+ }
+
+ if (operand->IsUnallocated()) {
+ auto unalloc_operand = UnallocatedOperand::cast(operand);
+ range->AddUsePosition(position, unalloc_operand, hint, allocation_zone());
+ }
+}
+
+
+void LiveRangeBuilder::Use(LifetimePosition block_start,
+ LifetimePosition position,
+ InstructionOperand* operand,
+ InstructionOperand* hint) {
+ auto range = LiveRangeFor(operand);
+ if (range == nullptr) return;
+ if (operand->IsUnallocated()) {
+ UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
+ range->AddUsePosition(position, unalloc_operand, hint, allocation_zone());
+ }
+ range->AddUseInterval(block_start, position, allocation_zone());
+}
+
+
bool LiveRangeBuilder::IsOutputRegisterOf(Instruction* instr, int index) {
for (size_t i = 0; i < instr->OutputCount(); i++) {
auto output = instr->OutputAt(i);
@@ -1184,7 +1232,7 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
index--) {
auto curr_position =
LifetimePosition::InstructionFromInstructionIndex(index);
- auto instr = InstructionAt(index);
+ auto instr = code()->InstructionAt(index);
DCHECK(instr != nullptr);
DCHECK(curr_position.IsInstructionPosition());
// Process output, inputs, and temps of this instruction.
@@ -1308,51 +1356,6 @@ void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
}
-void LiveRangeBuilder::ResolvePhis(const InstructionBlock* block) {
- for (auto phi : block->phis()) {
- int phi_vreg = phi->virtual_register();
- auto map_value = new (allocation_zone())
- RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
- auto res = phi_map().insert(std::make_pair(phi_vreg, map_value));
- DCHECK(res.second);
- USE(res);
- auto& output = phi->output();
- for (size_t i = 0; i < phi->operands().size(); ++i) {
- InstructionBlock* cur_block =
- code()->InstructionBlockAt(block->predecessors()[i]);
- UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
- auto move = data()->AddGapMove(cur_block->last_instruction_index(),
- Instruction::END, input, output);
- map_value->incoming_moves.push_back(move);
- DCHECK(!InstructionAt(cur_block->last_instruction_index())
- ->HasReferenceMap());
- }
- auto live_range = LiveRangeFor(phi_vreg);
- int gap_index = block->first_instruction_index();
- live_range->SpillAtDefinition(allocation_zone(), gap_index, &output);
- live_range->SetSpillStartIndex(gap_index);
- // We use the phi-ness of some nodes in some later heuristics.
- live_range->set_is_phi(true);
- live_range->set_is_non_loop_phi(!block->IsLoopHeader());
- }
-}
-
-
-void LiveRangeBuilder::MeetRegisterConstraints() {
- for (auto block : code()->instruction_blocks()) {
- MeetRegisterConstraints(block);
- }
-}
-
-
-void LiveRangeBuilder::ResolvePhis() {
- // Process the blocks in reverse order.
- for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
- ResolvePhis(block);
- }
-}
-
-
void LiveRangeBuilder::BuildLiveRanges() {
// Process the blocks in reverse order.
for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
@@ -1374,7 +1377,7 @@ void LiveRangeBuilder::BuildLiveRanges() {
live->Remove(phi_vreg);
InstructionOperand* hint = nullptr;
auto instr = GetLastInstruction(
- code()->InstructionBlockAt(block->predecessors()[0]));
+ code(), code()->InstructionBlockAt(block->predecessors()[0]));
for (auto move : *instr->GetParallelMove(Instruction::END)) {
auto& to = move->destination();
if (to.IsUnallocated() &&
@@ -1415,7 +1418,7 @@ void LiveRangeBuilder::BuildLiveRanges() {
}
}
- for (auto range : live_ranges()) {
+ for (auto range : data()->live_ranges()) {
if (range == nullptr) continue;
range->set_kind(RequiredRegisterKind(range->id()));
// Give slots to all ranges with a non fixed slot use.
@@ -1474,14 +1477,16 @@ LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
// TryAllocateFreeReg and AllocateBlockedReg assume this
// when allocating local arrays.
DCHECK(RegisterConfiguration::kMaxDoubleRegisters >=
- config()->num_general_registers());
+ this->data()->config()->num_general_registers());
}
void LinearScanAllocator::AllocateRegisters() {
DCHECK(unhandled_live_ranges().empty());
+ DCHECK(active_live_ranges().empty());
+ DCHECK(inactive_live_ranges().empty());
- for (auto range : live_ranges()) {
+ for (auto range : data()->live_ranges()) {
if (range == nullptr) continue;
if (range->Kind() == mode_) {
AddToUnhandledUnsorted(range);
@@ -1490,9 +1495,6 @@ void LinearScanAllocator::AllocateRegisters() {
SortUnhandled();
DCHECK(UnhandledIsSorted());
- DCHECK(active_live_ranges().empty());
- DCHECK(inactive_live_ranges().empty());
-
auto& fixed_ranges = GetFixedRegisters(data(), mode_);
for (auto current : fixed_ranges) {
if (current != nullptr) {
@@ -1565,17 +1567,14 @@ void LinearScanAllocator::AllocateRegisters() {
AddToActive(current);
}
}
-
- active_live_ranges().clear();
- inactive_live_ranges().clear();
}
const char* LinearScanAllocator::RegisterName(int allocation_index) const {
if (mode_ == GENERAL_REGISTERS) {
- return config()->general_register_name(allocation_index);
+ return data()->config()->general_register_name(allocation_index);
} else {
- return config()->double_register_name(allocation_index);
+ return data()->config()->double_register_name(allocation_index);
}
}
@@ -1910,8 +1909,8 @@ bool LinearScanAllocator::TryReuseSpillForPhi(LiveRange* range) {
if (range->IsChild() || !range->is_phi()) return false;
DCHECK(!range->HasSpillOperand());
- auto lookup = phi_map().find(range->id());
- DCHECK(lookup != phi_map().end());
+ auto lookup = data()->phi_map().find(range->id());
+ DCHECK(lookup != data()->phi_map().end());
auto phi = lookup->second->phi;
auto block = lookup->second->block;
// Count the number of spilled operands.
@@ -2190,7 +2189,7 @@ void ReferenceMapPopulator::PopulateReferenceMaps() {
// Iterate over the first parts of multi-part live ranges.
if (range->IsChild()) continue;
// Skip non-reference values.
- if (!IsReference(range->id())) continue;
+ if (!data()->IsReference(range->id())) continue;
// Skip empty live ranges.
if (range->IsEmpty()) continue;
@@ -2444,7 +2443,7 @@ void LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
position = Instruction::START;
} else {
DCHECK(pred->SuccessorCount() == 1);
- DCHECK(!data()
+ DCHECK(!code()
->InstructionAt(pred->last_instruction_index())
->HasReferenceMap());
gap_index = pred->last_instruction_index();
« 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