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

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

Issue 948033002: [turbofan] only use two gaps (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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') | test/unittests/compiler/instruction-sequence-unittest.h » ('j') | 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 1de5773e7fefb59064bc83633bb231e430b008ce..d27519a9060c99da77d0967a0c35d57f57dd3f16 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -1415,22 +1415,6 @@ void RegisterAllocator::ResolvePhis() {
}
-ParallelMove* RegisterAllocator::GetConnectingParallelMove(
- LifetimePosition pos) {
- int index = pos.InstructionIndex();
- if (code()->IsGapAt(index)) {
- auto gap = code()->GapAt(index);
- return gap->GetOrCreateParallelMove(
- pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END,
- code_zone());
- }
- int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1);
- return code()->GapAt(gap_pos)->GetOrCreateParallelMove(
- (gap_pos < index) ? GapInstruction::AFTER : GapInstruction::START,
- code_zone());
-}
-
-
const InstructionBlock* RegisterAllocator::GetInstructionBlock(
LifetimePosition pos) {
return code()->GetInstructionBlock(pos.InstructionIndex());
@@ -1438,33 +1422,74 @@ const InstructionBlock* RegisterAllocator::GetInstructionBlock(
void RegisterAllocator::ConnectRanges() {
+ ZoneMap<std::pair<ParallelMove*, InstructionOperand*>, InstructionOperand*>
+ delayed_insertion_map(local_zone());
for (auto first_range : live_ranges()) {
if (first_range == nullptr || first_range->IsChild()) continue;
- auto second_range = first_range->next();
- while (second_range != nullptr) {
+ for (auto second_range = first_range->next(); second_range != nullptr;
+ first_range = second_range, second_range = second_range->next()) {
auto pos = second_range->Start();
- if (!second_range->IsSpilled()) {
- // Add gap move if the two live ranges touch and there is no block
- // boundary.
- if (first_range->End().Value() == pos.Value()) {
- bool should_insert = true;
- if (IsBlockBoundary(pos)) {
- should_insert =
- CanEagerlyResolveControlFlow(GetInstructionBlock(pos));
- }
- if (should_insert) {
- auto move = GetConnectingParallelMove(pos);
- auto prev_operand =
- first_range->GetAssignedOperand(operand_cache());
- auto cur_operand =
- second_range->GetAssignedOperand(operand_cache());
- move->AddMove(prev_operand, cur_operand, code_zone());
- }
- }
+ // Add gap move if the two live ranges touch and there is no block
+ // boundary.
+ if (second_range->IsSpilled()) continue;
+ if (first_range->End().Value() != pos.Value()) continue;
+ if (IsBlockBoundary(pos) &&
+ !CanEagerlyResolveControlFlow(GetInstructionBlock(pos))) {
+ continue;
+ }
+ auto prev_operand = first_range->GetAssignedOperand(operand_cache());
+ auto cur_operand = second_range->GetAssignedOperand(operand_cache());
+ if (prev_operand->Equals(cur_operand)) continue;
+ int index = pos.InstructionIndex();
+ bool delay_insertion = false;
+ GapInstruction::InnerPosition gap_pos;
+ int gap_index = index;
+ if (code()->IsGapAt(index)) {
+ gap_pos = pos.IsInstructionStart() ? GapInstruction::START
+ : GapInstruction::END;
+ } else {
+ gap_index = pos.IsInstructionStart() ? (index - 1) : (index + 1);
+ delay_insertion = gap_index < index;
+ gap_pos = delay_insertion ? GapInstruction::END : GapInstruction::START;
+ }
+ auto move = code()->GapAt(gap_index)->GetOrCreateParallelMove(
+ gap_pos, code_zone());
+ if (!delay_insertion) {
+ move->AddMove(prev_operand, cur_operand, code_zone());
+ } else {
+ delayed_insertion_map.insert(
+ std::make_pair(std::make_pair(move, prev_operand), cur_operand));
+ }
+ }
+ }
+ if (delayed_insertion_map.empty()) return;
+ // Insert all the moves which should occur after the stored move.
+ ZoneVector<MoveOperands> to_insert(local_zone());
+ ZoneVector<MoveOperands*> to_eliminate(local_zone());
+ to_insert.reserve(4);
+ to_eliminate.reserve(4);
+ auto move = delayed_insertion_map.begin()->first.first;
+ for (auto it = delayed_insertion_map.begin();; ++it) {
+ bool done = it == delayed_insertion_map.end();
+ if (done || it->first.first != move) {
+ // Commit the MoveOperands for current ParallelMove.
+ for (auto move_ops : to_eliminate) {
+ move_ops->Eliminate();
+ }
+ for (auto move_ops : to_insert) {
+ move->AddMove(move_ops.source(), move_ops.destination(), code_zone());
}
- first_range = second_range;
- second_range = second_range->next();
+ if (done) break;
+ // Reset state.
+ to_eliminate.clear();
+ to_insert.clear();
+ move = it->first.first;
}
+ // Gather all MoveOperands for a single ParallelMove.
+ MoveOperands move_ops(it->first.second, it->second);
+ auto eliminate = move->PrepareInsertAfter(&move_ops);
+ to_insert.push_back(move_ops);
+ if (eliminate != nullptr) to_eliminate.push_back(eliminate);
}
}
« no previous file with comments | « src/compiler/register-allocator.h ('k') | test/unittests/compiler/instruction-sequence-unittest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698