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

Side by Side Diff: src/compiler/coalesced-live-ranges.cc

Issue 1219063017: [turbofan] Unit tests for live range conflicts. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Incorporated feedback. Created 5 years, 5 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
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/coalesced-live-ranges.h" 5 #include "src/compiler/coalesced-live-ranges.h"
6 #include "src/compiler/greedy-allocator.h" 6 #include "src/compiler/greedy-allocator.h"
7 #include "src/compiler/register-allocator.h" 7 #include "src/compiler/register-allocator.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
11 namespace compiler { 11 namespace compiler {
12 12
13 #define TRACE(...) \
14 do { \
15 if (FLAG_trace_alloc) PrintF(__VA_ARGS__); \
16 } while (false)
17
18
19 const float CoalescedLiveRanges::kAllocatedRangeMultiplier = 10.0;
20 13
21 void CoalescedLiveRanges::AllocateRange(LiveRange* range) { 14 void CoalescedLiveRanges::AllocateRange(LiveRange* range) {
22 UpdateWeightAtAllocation(range);
23 for (auto interval = range->first_interval(); interval != nullptr; 15 for (auto interval = range->first_interval(); interval != nullptr;
24 interval = interval->next()) { 16 interval = interval->next()) {
25 storage().insert({interval->start(), interval->end(), range}); 17 storage().insert({interval->start(), interval->end(), range});
26 } 18 }
27 } 19 }
28 20
29 21
30 void CoalescedLiveRanges::Remove(LiveRange* range) { 22 void CoalescedLiveRanges::Remove(LiveRange* range) {
31 for (auto interval = range->first_interval(); interval != nullptr; 23 for (auto interval = range->first_interval(); interval != nullptr;
32 interval = interval->next()) { 24 interval = interval->next()) {
33 storage().erase({interval->start(), interval->end(), nullptr}); 25 storage().erase({interval->start(), interval->end(), nullptr});
34 } 26 }
35 range->UnsetAssignedRegister();
36 }
37
38
39 float CoalescedLiveRanges::GetMaximumConflictingWeight(
40 const LiveRange* range) const {
41 float ret = LiveRange::kInvalidWeight;
42 auto end = storage().end();
43 for (auto query = range->first_interval(); query != nullptr;
44 query = query->next()) {
45 auto conflict = GetFirstConflict(query);
46
47 if (conflict == end) continue;
48 for (; QueryIntersectsAllocatedInterval(query, conflict); ++conflict) {
49 // It is possible we'll visit the same range multiple times, because
50 // successive (not necessarily consecutive) intervals belong to the same
51 // range, or because different intervals of the query range have the same
52 // range as conflict.
53 DCHECK_NE(conflict->range->weight(), LiveRange::kInvalidWeight);
54 ret = Max(ret, conflict->range->weight());
55 if (ret == LiveRange::kMaxWeight) break;
56 }
57 }
58 return ret;
59 }
60
61
62 void CoalescedLiveRanges::EvictAndRescheduleConflicts(
63 LiveRange* range, AllocationScheduler* scheduler) {
64 auto end = storage().end();
65
66 for (auto query = range->first_interval(); query != nullptr;
67 query = query->next()) {
68 auto conflict = GetFirstConflict(query);
69 if (conflict == end) continue;
70 while (QueryIntersectsAllocatedInterval(query, conflict)) {
71 LiveRange* range_to_evict = conflict->range;
72 // Bypass successive intervals belonging to the same range, because we're
73 // about to remove this range, and we don't want the storage iterator to
74 // become invalid.
75 while (conflict != end && conflict->range == range_to_evict) {
76 ++conflict;
77 }
78
79 DCHECK(range_to_evict->HasRegisterAssigned());
80 CHECK(!range_to_evict->IsFixed());
81 Remove(range_to_evict);
82 UpdateWeightAtEviction(range_to_evict);
83 TRACE("Evicted range %d.\n", range_to_evict->id());
84 scheduler->Schedule(range_to_evict);
85 }
86 }
87 } 27 }
88 28
89 29
90 bool CoalescedLiveRanges::VerifyAllocationsAreValid() const { 30 bool CoalescedLiveRanges::TestOnlyVerifyAllocationsAreValid() const {
91 LifetimePosition last_end = LifetimePosition::GapFromInstructionIndex(0); 31 LifetimePosition last_end = LifetimePosition::GapFromInstructionIndex(0);
92 for (auto i : storage_) { 32 for (auto i : storage_) {
93 if (i.start < last_end) { 33 if (i.start < last_end) {
94 return false; 34 return false;
95 } 35 }
96 last_end = i.end; 36 last_end = i.end;
97 } 37 }
98 return true; 38 return true;
99 } 39 }
100 40
101 41
102 void CoalescedLiveRanges::UpdateWeightAtAllocation(LiveRange* range) {
103 DCHECK_NE(range->weight(), LiveRange::kInvalidWeight);
104 range->set_weight(range->weight() * kAllocatedRangeMultiplier);
105 }
106
107
108 void CoalescedLiveRanges::UpdateWeightAtEviction(LiveRange* range) {
109 DCHECK_NE(range->weight(), LiveRange::kInvalidWeight);
110 range->set_weight(range->weight() / kAllocatedRangeMultiplier);
111 }
112
113
114 CoalescedLiveRanges::interval_iterator CoalescedLiveRanges::GetFirstConflict( 42 CoalescedLiveRanges::interval_iterator CoalescedLiveRanges::GetFirstConflict(
115 const UseInterval* query) const { 43 const UseInterval* query) const {
116 DCHECK(query != nullptr); 44 DCHECK(query != nullptr);
117 auto end = storage().end(); 45 auto end = storage().end();
118 LifetimePosition q_start = query->start(); 46 LifetimePosition q_start = query->start();
119 LifetimePosition q_end = query->end(); 47 LifetimePosition q_end = query->end();
120 48
121 if (storage().empty() || storage().rbegin()->end <= q_start || 49 if (storage().empty() || storage().rbegin()->end <= q_start ||
122 storage().begin()->start >= q_end) { 50 storage().begin()->start >= q_end) {
123 return end; 51 return end;
(...skipping 15 matching lines...) Expand all
139 } 67 }
140 } 68 }
141 if (ret != end && QueryIntersectsAllocatedInterval(query, ret)) return ret; 69 if (ret != end && QueryIntersectsAllocatedInterval(query, ret)) return ret;
142 return end; 70 return end;
143 } 71 }
144 72
145 73
146 } // namespace compiler 74 } // namespace compiler
147 } // namespace internal 75 } // namespace internal
148 } // namespace v8 76 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698