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

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

Issue 1372213005: [turbofan] Greedy: smarter last resort splitting. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 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/greedy-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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/greedy-allocator.h" 5 #include "src/compiler/greedy-allocator.h"
6 #include "src/compiler/register-allocator.h" 6 #include "src/compiler/register-allocator.h"
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 namespace compiler { 10 namespace compiler {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 LifetimePosition ret = LifetimePosition::Invalid(); 56 LifetimePosition ret = LifetimePosition::Invalid();
57 57
58 ret = LifetimePosition::GapFromInstructionIndex(instruction_index); 58 ret = LifetimePosition::GapFromInstructionIndex(instruction_index);
59 if (range->Start() >= ret || ret >= range->End()) { 59 if (range->Start() >= ret || ret >= range->End()) {
60 return LifetimePosition::Invalid(); 60 return LifetimePosition::Invalid();
61 } 61 }
62 return ret; 62 return ret;
63 } 63 }
64 64
65 65
66 int GetFirstGapIndex(const UseInterval* interval) {
67 LifetimePosition start = interval->start();
68 int ret = start.ToInstructionIndex();
69 return ret;
70 }
71
72
73 int GetLastGapIndex(const UseInterval* interval) {
74 LifetimePosition end = interval->end();
75 return end.ToInstructionIndex();
76 }
77
78
79 // Basic heuristic for advancing the algorithm, if any other splitting heuristic
80 // failed.
81 LifetimePosition GetLastResortSplitPosition(const LiveRange* range,
82 const InstructionSequence* code) {
83 if (range->first_interval()->next() != nullptr) {
84 return range->first_interval()->next()->start();
85 }
86
87 UseInterval* interval = range->first_interval();
88 int first = GetFirstGapIndex(interval);
89 int last = GetLastGapIndex(interval);
90 if (first == last) return LifetimePosition::Invalid();
91
92 // TODO(mtrofin:) determine why we can't just split somewhere arbitrary
93 // within the range, e.g. it's middle.
94 for (UsePosition* pos = range->first_pos(); pos != nullptr;
95 pos = pos->next()) {
96 if (pos->type() != UsePositionType::kRequiresRegister) continue;
97 LifetimePosition before =
98 GetSplitPositionForInstruction(range, pos->pos().ToInstructionIndex());
99 if (before.IsValid()) return before;
100 LifetimePosition after = GetSplitPositionForInstruction(
101 range, pos->pos().ToInstructionIndex() + 1);
102 if (after.IsValid()) return after;
103 }
104 return LifetimePosition::Invalid();
105 }
106
107
108 bool IsProgressPossible(const LiveRange* range,
109 const InstructionSequence* code) {
110 return range->CanBeSpilled(range->Start()) ||
111 GetLastResortSplitPosition(range, code).IsValid();
112 }
113 } // namespace 66 } // namespace
114 67
115 68
116 AllocationCandidate AllocationScheduler::GetNext() { 69 AllocationCandidate AllocationScheduler::GetNext() {
117 DCHECK(!queue_.empty()); 70 DCHECK(!queue_.empty());
118 AllocationCandidate ret = queue_.top(); 71 AllocationCandidate ret = queue_.top();
119 queue_.pop(); 72 queue_.pop();
120 return ret; 73 return ret;
121 } 74 }
122 75
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 void GreedyAllocator::EnsureValidRangeWeight(LiveRange* range) { 502 void GreedyAllocator::EnsureValidRangeWeight(LiveRange* range) {
550 // The live range weight will be invalidated when ranges are created or split. 503 // The live range weight will be invalidated when ranges are created or split.
551 // Otherwise, it is consistently updated when the range is allocated or 504 // Otherwise, it is consistently updated when the range is allocated or
552 // unallocated. 505 // unallocated.
553 if (range->weight() != LiveRange::kInvalidWeight) return; 506 if (range->weight() != LiveRange::kInvalidWeight) return;
554 507
555 if (range->TopLevel()->IsFixed()) { 508 if (range->TopLevel()->IsFixed()) {
556 range->set_weight(LiveRange::kMaxWeight); 509 range->set_weight(LiveRange::kMaxWeight);
557 return; 510 return;
558 } 511 }
559 if (!IsProgressPossible(range, code())) { 512 if (!IsProgressPossible(range)) {
560 range->set_weight(LiveRange::kMaxWeight); 513 range->set_weight(LiveRange::kMaxWeight);
561 return; 514 return;
562 } 515 }
563 516
564 float use_count = 0.0; 517 float use_count = 0.0;
565 for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next()) { 518 for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next()) {
566 ++use_count; 519 ++use_count;
567 } 520 }
568 range->set_weight(use_count / static_cast<float>(range->GetSize())); 521 range->set_weight(use_count / static_cast<float>(range->GetSize()));
569 } 522 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 pos = GetSplitPositionForInstruction(range, pos.ToInstructionIndex()); 628 pos = GetSplitPositionForInstruction(range, pos.ToInstructionIndex());
676 return pos; 629 return pos;
677 } 630 }
678 631
679 632
680 void GreedyAllocator::SplitOrSpillBlockedRange(LiveRange* range) { 633 void GreedyAllocator::SplitOrSpillBlockedRange(LiveRange* range) {
681 if (TrySplitAroundCalls(range)) return; 634 if (TrySplitAroundCalls(range)) return;
682 635
683 LifetimePosition pos = FindSplitPositionBeforeLoops(range); 636 LifetimePosition pos = FindSplitPositionBeforeLoops(range);
684 637
685 if (!pos.IsValid()) pos = GetLastResortSplitPosition(range, code()); 638 if (!pos.IsValid()) pos = GetLastResortSplitPosition(range);
686 if (pos.IsValid()) { 639 if (pos.IsValid()) {
687 LiveRange* tail = Split(range, data(), pos); 640 LiveRange* tail = Split(range, data(), pos);
688 DCHECK(tail != range); 641 DCHECK(tail != range);
689 scheduler().Schedule(tail); 642 scheduler().Schedule(tail);
690 scheduler().Schedule(range); 643 scheduler().Schedule(range);
691 return; 644 return;
692 } 645 }
693 SpillRangeAsLastResort(range); 646 SpillRangeAsLastResort(range);
694 } 647 }
695 648
696 649
650 // Basic heuristic for advancing the algorithm, if any other splitting heuristic
651 // failed.
652 LifetimePosition GreedyAllocator::GetLastResortSplitPosition(
653 const LiveRange* range) {
654 LifetimePosition previous = range->Start();
655 for (UsePosition *pos = range->NextRegisterPosition(previous); pos != nullptr;
656 previous = previous.NextFullStart(),
657 pos = range->NextRegisterPosition(previous)) {
658 LifetimePosition optimal = FindOptimalSplitPos(previous, pos->pos());
659 LifetimePosition before =
660 GetSplitPositionForInstruction(range, optimal.ToInstructionIndex());
661 if (before.IsValid()) return before;
662 LifetimePosition after = GetSplitPositionForInstruction(
663 range, pos->pos().ToInstructionIndex() + 1);
664 if (after.IsValid()) return after;
665 }
666 return LifetimePosition::Invalid();
667 }
668
669
670 bool GreedyAllocator::IsProgressPossible(const LiveRange* range) {
671 return range->CanBeSpilled(range->Start()) ||
672 GetLastResortSplitPosition(range).IsValid();
673 }
674
697 } // namespace compiler 675 } // namespace compiler
698 } // namespace internal 676 } // namespace internal
699 } // namespace v8 677 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/greedy-allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698