Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #include "src/compiler/backend/register-allocator.h"
6 : #include "test/unittests/test-utils.h"
7 :
8 : // TODO(mtrofin): would we want to centralize this definition?
9 : #ifdef DEBUG
10 : #define V8_ASSERT_DEBUG_DEATH(statement, regex) \
11 : ASSERT_DEATH_IF_SUPPORTED(statement, regex)
12 : #define DISABLE_IN_RELEASE(Name) Name
13 :
14 : #else
15 : #define V8_ASSERT_DEBUG_DEATH(statement, regex) statement
16 : #define DISABLE_IN_RELEASE(Name) DISABLED_##Name
17 : #endif // DEBUG
18 :
19 : namespace v8 {
20 : namespace internal {
21 : namespace compiler {
22 :
23 : // Utility offering shorthand syntax for building up a range by providing its ID
24 : // and pairs (start, end) specifying intervals. Circumvents current incomplete
25 : // support for C++ features such as instantiation lists, on OS X and Android.
26 116 : class TestRangeBuilder {
27 : public:
28 : explicit TestRangeBuilder(Zone* zone)
29 116 : : id_(-1), pairs_(), uses_(), zone_(zone) {}
30 :
31 : TestRangeBuilder& Id(int id) {
32 1 : id_ = id;
33 : return *this;
34 : }
35 : TestRangeBuilder& Add(int start, int end) {
36 90 : pairs_.push_back({start, end});
37 : return *this;
38 : }
39 :
40 : TestRangeBuilder& AddUse(int pos) {
41 : uses_.insert(pos);
42 : return *this;
43 : }
44 :
45 : TopLevelLiveRange* Build(int start, int end) {
46 19 : return Add(start, end).Build();
47 : }
48 :
49 58 : TopLevelLiveRange* Build() {
50 : TopLevelLiveRange* range =
51 116 : new (zone_) TopLevelLiveRange(id_, MachineRepresentation::kTagged);
52 : // Traverse the provided interval specifications backwards, because that is
53 : // what LiveRange expects.
54 148 : for (int i = static_cast<int>(pairs_.size()) - 1; i >= 0; --i) {
55 180 : Interval pair = pairs_[i];
56 : LifetimePosition start = LifetimePosition::FromInt(pair.first);
57 : LifetimePosition end = LifetimePosition::FromInt(pair.second);
58 90 : CHECK(start < end);
59 90 : range->AddUseInterval(start, end, zone_);
60 : }
61 82 : for (int pos : uses_) {
62 : UsePosition* use_position =
63 48 : new (zone_) UsePosition(LifetimePosition::FromInt(pos), nullptr,
64 48 : nullptr, UsePositionHintType::kNone);
65 24 : range->AddUsePosition(use_position);
66 : }
67 :
68 : pairs_.clear();
69 58 : return range;
70 : }
71 :
72 : private:
73 : typedef std::pair<int, int> Interval;
74 : typedef std::vector<Interval> IntervalList;
75 : int id_;
76 : IntervalList pairs_;
77 : std::set<int> uses_;
78 : Zone* zone_;
79 : };
80 :
81 48 : class LiveRangeUnitTest : public TestWithZone {
82 : public:
83 : // Split helper, to avoid int->LifetimePosition conversion nuisance.
84 : LiveRange* Split(LiveRange* range, int pos) {
85 17 : return range->SplitAt(LifetimePosition::FromInt(pos), zone());
86 : }
87 :
88 12 : TopLevelLiveRange* Splinter(TopLevelLiveRange* top, int start, int end,
89 : int new_id = 0) {
90 12 : if (top->splinter() == nullptr) {
91 : TopLevelLiveRange* ret = new (zone())
92 11 : TopLevelLiveRange(new_id, MachineRepresentation::kTagged);
93 11 : top->SetSplinter(ret);
94 : }
95 : top->Splinter(LifetimePosition::FromInt(start),
96 12 : LifetimePosition::FromInt(end), zone());
97 12 : return top->splinter();
98 : }
99 :
100 : // Ranges first and second match structurally.
101 35 : bool RangesMatch(LiveRange* first, LiveRange* second) {
102 35 : if (first->Start() != second->Start() || first->End() != second->End()) {
103 : return false;
104 : }
105 : UseInterval* i1 = first->first_interval();
106 : UseInterval* i2 = second->first_interval();
107 :
108 131 : while (i1 != nullptr && i2 != nullptr) {
109 48 : if (i1->start() != i2->start() || i1->end() != i2->end()) return false;
110 : i1 = i1->next();
111 : i2 = i2->next();
112 : }
113 35 : if (i1 != nullptr || i2 != nullptr) return false;
114 :
115 : UsePosition* p1 = first->first_pos();
116 : UsePosition* p2 = second->first_pos();
117 :
118 59 : while (p1 != nullptr && p2 != nullptr) {
119 12 : if (p1->pos() != p2->pos()) return false;
120 : p1 = p1->next();
121 : p2 = p2->next();
122 : }
123 35 : if (p1 != nullptr || p2 != nullptr) return false;
124 35 : return true;
125 : }
126 : };
127 :
128 15444 : TEST_F(LiveRangeUnitTest, InvalidConstruction) {
129 : // Build a range manually, because the builder guards against empty cases.
130 : TopLevelLiveRange* range =
131 1 : new (zone()) TopLevelLiveRange(1, MachineRepresentation::kTagged);
132 : V8_ASSERT_DEBUG_DEATH(
133 : range->AddUseInterval(LifetimePosition::FromInt(0),
134 : LifetimePosition::FromInt(0), zone()),
135 1 : ".*");
136 1 : }
137 :
138 15444 : TEST_F(LiveRangeUnitTest, SplitInvalidStart) {
139 1 : TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 1);
140 : V8_ASSERT_DEBUG_DEATH(Split(range, 0), ".*");
141 1 : }
142 :
143 15440 : TEST_F(LiveRangeUnitTest, DISABLE_IN_RELEASE(InvalidSplitEnd)) {
144 0 : TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 1);
145 0 : ASSERT_DEATH_IF_SUPPORTED(Split(range, 1), ".*");
146 : }
147 :
148 15440 : TEST_F(LiveRangeUnitTest, DISABLE_IN_RELEASE(SplitInvalidPreStart)) {
149 0 : TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(1, 2);
150 0 : ASSERT_DEATH_IF_SUPPORTED(Split(range, 0), ".*");
151 : }
152 :
153 15440 : TEST_F(LiveRangeUnitTest, DISABLE_IN_RELEASE(SplitInvalidPostEnd)) {
154 0 : TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 1);
155 0 : ASSERT_DEATH_IF_SUPPORTED(Split(range, 2), ".*");
156 : }
157 :
158 15444 : TEST_F(LiveRangeUnitTest, SplitSingleIntervalNoUsePositions) {
159 1 : TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 2);
160 1 : LiveRange* child = Split(range, 1);
161 :
162 1 : EXPECT_NE(nullptr, range->next());
163 2 : EXPECT_EQ(child, range->next());
164 :
165 1 : LiveRange* expected_top = TestRangeBuilder(zone()).Build(0, 1);
166 1 : LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(1, 2);
167 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
168 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
169 1 : }
170 :
171 15444 : TEST_F(LiveRangeUnitTest, SplitManyIntervalNoUsePositionsBetween) {
172 : TopLevelLiveRange* range =
173 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).Build();
174 1 : LiveRange* child = Split(range, 3);
175 :
176 1 : EXPECT_NE(nullptr, range->next());
177 2 : EXPECT_EQ(child, range->next());
178 :
179 1 : LiveRange* expected_top = TestRangeBuilder(zone()).Build(0, 2);
180 1 : LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(4, 6);
181 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
182 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
183 1 : }
184 :
185 15444 : TEST_F(LiveRangeUnitTest, SplitManyIntervalNoUsePositionsFront) {
186 : TopLevelLiveRange* range =
187 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).Build();
188 1 : LiveRange* child = Split(range, 1);
189 :
190 1 : EXPECT_NE(nullptr, range->next());
191 2 : EXPECT_EQ(child, range->next());
192 :
193 1 : LiveRange* expected_top = TestRangeBuilder(zone()).Build(0, 1);
194 : LiveRange* expected_bottom =
195 1 : TestRangeBuilder(zone()).Add(1, 2).Add(4, 6).Build();
196 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
197 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
198 1 : }
199 :
200 15444 : TEST_F(LiveRangeUnitTest, SplitManyIntervalNoUsePositionsAfter) {
201 : TopLevelLiveRange* range =
202 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).Build();
203 1 : LiveRange* child = Split(range, 5);
204 :
205 1 : EXPECT_NE(nullptr, range->next());
206 2 : EXPECT_EQ(child, range->next());
207 :
208 : LiveRange* expected_top =
209 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 5).Build();
210 1 : LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(5, 6);
211 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
212 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
213 1 : }
214 :
215 15444 : TEST_F(LiveRangeUnitTest, SplitSingleIntervalUsePositions) {
216 : TopLevelLiveRange* range =
217 1 : TestRangeBuilder(zone()).Add(0, 3).AddUse(0).AddUse(2).Build();
218 :
219 1 : LiveRange* child = Split(range, 1);
220 :
221 1 : EXPECT_NE(nullptr, range->next());
222 2 : EXPECT_EQ(child, range->next());
223 :
224 : LiveRange* expected_top =
225 1 : TestRangeBuilder(zone()).Add(0, 1).AddUse(0).Build();
226 : LiveRange* expected_bottom =
227 1 : TestRangeBuilder(zone()).Add(1, 3).AddUse(2).Build();
228 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
229 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
230 1 : }
231 :
232 15444 : TEST_F(LiveRangeUnitTest, SplitSingleIntervalUsePositionsAtPos) {
233 : TopLevelLiveRange* range =
234 1 : TestRangeBuilder(zone()).Add(0, 3).AddUse(0).AddUse(2).Build();
235 :
236 1 : LiveRange* child = Split(range, 2);
237 :
238 1 : EXPECT_NE(nullptr, range->next());
239 2 : EXPECT_EQ(child, range->next());
240 :
241 : LiveRange* expected_top =
242 1 : TestRangeBuilder(zone()).Add(0, 2).AddUse(0).AddUse(2).Build();
243 1 : LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(2, 3);
244 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
245 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
246 1 : }
247 :
248 15444 : TEST_F(LiveRangeUnitTest, SplitManyIntervalUsePositionsBetween) {
249 : TopLevelLiveRange* range =
250 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).AddUse(1).AddUse(5).Build();
251 1 : LiveRange* child = Split(range, 3);
252 :
253 1 : EXPECT_NE(nullptr, range->next());
254 2 : EXPECT_EQ(child, range->next());
255 :
256 : LiveRange* expected_top =
257 1 : TestRangeBuilder(zone()).Add(0, 2).AddUse(1).Build();
258 : LiveRange* expected_bottom =
259 1 : TestRangeBuilder(zone()).Add(4, 6).AddUse(5).Build();
260 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
261 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
262 1 : }
263 :
264 15444 : TEST_F(LiveRangeUnitTest, SplitManyIntervalUsePositionsAtInterval) {
265 : TopLevelLiveRange* range =
266 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).AddUse(1).AddUse(4).Build();
267 1 : LiveRange* child = Split(range, 4);
268 :
269 1 : EXPECT_NE(nullptr, range->next());
270 2 : EXPECT_EQ(child, range->next());
271 :
272 : LiveRange* expected_top =
273 1 : TestRangeBuilder(zone()).Add(0, 2).AddUse(1).Build();
274 : LiveRange* expected_bottom =
275 1 : TestRangeBuilder(zone()).Add(4, 6).AddUse(4).Build();
276 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
277 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
278 1 : }
279 :
280 15444 : TEST_F(LiveRangeUnitTest, SplitManyIntervalUsePositionsFront) {
281 : TopLevelLiveRange* range =
282 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).AddUse(1).AddUse(5).Build();
283 1 : LiveRange* child = Split(range, 1);
284 :
285 1 : EXPECT_NE(nullptr, range->next());
286 2 : EXPECT_EQ(child, range->next());
287 :
288 : LiveRange* expected_top =
289 1 : TestRangeBuilder(zone()).Add(0, 1).AddUse(1).Build();
290 : LiveRange* expected_bottom =
291 1 : TestRangeBuilder(zone()).Add(1, 2).Add(4, 6).AddUse(5).Build();
292 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
293 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
294 1 : }
295 :
296 15444 : TEST_F(LiveRangeUnitTest, SplitManyIntervalUsePositionsAfter) {
297 : TopLevelLiveRange* range =
298 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 6).AddUse(1).AddUse(5).Build();
299 1 : LiveRange* child = Split(range, 5);
300 :
301 1 : EXPECT_NE(nullptr, range->next());
302 2 : EXPECT_EQ(child, range->next());
303 :
304 : LiveRange* expected_top =
305 1 : TestRangeBuilder(zone()).Add(0, 2).Add(4, 5).AddUse(1).AddUse(5).Build();
306 1 : LiveRange* expected_bottom = TestRangeBuilder(zone()).Build(5, 6);
307 2 : EXPECT_TRUE(RangesMatch(expected_top, range));
308 2 : EXPECT_TRUE(RangesMatch(expected_bottom, child));
309 1 : }
310 :
311 15444 : TEST_F(LiveRangeUnitTest, SplinterSingleInterval) {
312 1 : TopLevelLiveRange* range = TestRangeBuilder(zone()).Build(0, 6);
313 1 : TopLevelLiveRange* splinter = Splinter(range, 3, 5);
314 2 : EXPECT_EQ(nullptr, range->next());
315 1 : EXPECT_EQ(nullptr, splinter->next());
316 2 : EXPECT_EQ(range, splinter->splintered_from());
317 :
318 : TopLevelLiveRange* expected_source =
319 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 6).Build();
320 1 : TopLevelLiveRange* expected_splinter = TestRangeBuilder(zone()).Build(3, 5);
321 2 : EXPECT_TRUE(RangesMatch(expected_source, range));
322 2 : EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
323 1 : }
324 :
325 15444 : TEST_F(LiveRangeUnitTest, MergeSingleInterval) {
326 1 : TopLevelLiveRange* original = TestRangeBuilder(zone()).Build(0, 6);
327 1 : TopLevelLiveRange* splinter = Splinter(original, 3, 5);
328 :
329 1 : original->Merge(splinter, zone());
330 1 : TopLevelLiveRange* result = TestRangeBuilder(zone()).Build(0, 6);
331 : LiveRange* child_1 = Split(result, 3);
332 : Split(child_1, 5);
333 :
334 2 : EXPECT_TRUE(RangesMatch(result, original));
335 1 : }
336 :
337 15444 : TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsOutside) {
338 : TopLevelLiveRange* range =
339 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
340 1 : TopLevelLiveRange* splinter = Splinter(range, 2, 6);
341 2 : EXPECT_EQ(nullptr, range->next());
342 1 : EXPECT_EQ(nullptr, splinter->next());
343 2 : EXPECT_EQ(range, splinter->splintered_from());
344 :
345 : TopLevelLiveRange* expected_source =
346 1 : TestRangeBuilder(zone()).Add(0, 2).Add(6, 8).Build();
347 : TopLevelLiveRange* expected_splinter =
348 1 : TestRangeBuilder(zone()).Add(2, 3).Add(5, 6).Build();
349 2 : EXPECT_TRUE(RangesMatch(expected_source, range));
350 2 : EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
351 1 : }
352 :
353 15444 : TEST_F(LiveRangeUnitTest, MergeMultipleIntervalsOutside) {
354 : TopLevelLiveRange* original =
355 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
356 1 : TopLevelLiveRange* splinter = Splinter(original, 2, 6);
357 1 : original->Merge(splinter, zone());
358 :
359 : TopLevelLiveRange* result =
360 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
361 : LiveRange* child_1 = Split(result, 2);
362 : Split(child_1, 6);
363 2 : EXPECT_TRUE(RangesMatch(result, original));
364 1 : }
365 :
366 15444 : TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsInside) {
367 : TopLevelLiveRange* range =
368 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
369 1 : V8_ASSERT_DEBUG_DEATH(Splinter(range, 3, 5), ".*");
370 1 : }
371 :
372 15444 : TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsLeft) {
373 : TopLevelLiveRange* range =
374 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
375 1 : TopLevelLiveRange* splinter = Splinter(range, 2, 4);
376 2 : EXPECT_EQ(nullptr, range->next());
377 1 : EXPECT_EQ(nullptr, splinter->next());
378 2 : EXPECT_EQ(range, splinter->splintered_from());
379 :
380 : TopLevelLiveRange* expected_source =
381 1 : TestRangeBuilder(zone()).Add(0, 2).Add(5, 8).Build();
382 1 : TopLevelLiveRange* expected_splinter = TestRangeBuilder(zone()).Build(2, 3);
383 2 : EXPECT_TRUE(RangesMatch(expected_source, range));
384 2 : EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
385 1 : }
386 :
387 15444 : TEST_F(LiveRangeUnitTest, MergeMultipleIntervalsLeft) {
388 : TopLevelLiveRange* original =
389 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
390 1 : TopLevelLiveRange* splinter = Splinter(original, 2, 4);
391 1 : original->Merge(splinter, zone());
392 :
393 : TopLevelLiveRange* result =
394 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
395 : Split(result, 2);
396 2 : EXPECT_TRUE(RangesMatch(result, original));
397 1 : }
398 :
399 15444 : TEST_F(LiveRangeUnitTest, SplinterMultipleIntervalsRight) {
400 : TopLevelLiveRange* range =
401 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
402 1 : TopLevelLiveRange* splinter = Splinter(range, 4, 6);
403 2 : EXPECT_EQ(nullptr, range->next());
404 1 : EXPECT_EQ(nullptr, splinter->next());
405 2 : EXPECT_EQ(range, splinter->splintered_from());
406 :
407 : TopLevelLiveRange* expected_source =
408 1 : TestRangeBuilder(zone()).Add(0, 3).Add(6, 8).Build();
409 1 : TopLevelLiveRange* expected_splinter = TestRangeBuilder(zone()).Build(5, 6);
410 2 : EXPECT_TRUE(RangesMatch(expected_source, range));
411 2 : EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
412 1 : }
413 :
414 15444 : TEST_F(LiveRangeUnitTest, SplinterMergeMultipleTimes) {
415 : TopLevelLiveRange* range =
416 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 10).Add(12, 16).Build();
417 1 : Splinter(range, 4, 6);
418 1 : Splinter(range, 8, 14);
419 1 : TopLevelLiveRange* splinter = range->splinter();
420 1 : EXPECT_EQ(nullptr, range->next());
421 1 : EXPECT_EQ(nullptr, splinter->next());
422 2 : EXPECT_EQ(range, splinter->splintered_from());
423 :
424 : TopLevelLiveRange* expected_source =
425 1 : TestRangeBuilder(zone()).Add(0, 3).Add(6, 8).Add(14, 16).Build();
426 : TopLevelLiveRange* expected_splinter =
427 1 : TestRangeBuilder(zone()).Add(5, 6).Add(8, 10).Add(12, 14).Build();
428 2 : EXPECT_TRUE(RangesMatch(expected_source, range));
429 2 : EXPECT_TRUE(RangesMatch(expected_splinter, splinter));
430 1 : }
431 :
432 15444 : TEST_F(LiveRangeUnitTest, MergeMultipleIntervalsRight) {
433 : TopLevelLiveRange* original =
434 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
435 1 : TopLevelLiveRange* splinter = Splinter(original, 4, 6);
436 1 : original->Merge(splinter, zone());
437 :
438 : TopLevelLiveRange* result =
439 1 : TestRangeBuilder(zone()).Add(0, 3).Add(5, 8).Build();
440 : LiveRange* child_1 = Split(result, 5);
441 : Split(child_1, 6);
442 :
443 2 : EXPECT_TRUE(RangesMatch(result, original));
444 1 : }
445 :
446 15444 : TEST_F(LiveRangeUnitTest, MergeAfterSplitting) {
447 1 : TopLevelLiveRange* original = TestRangeBuilder(zone()).Build(0, 8);
448 1 : TopLevelLiveRange* splinter = Splinter(original, 4, 6);
449 : LiveRange* original_child = Split(original, 2);
450 : Split(original_child, 7);
451 1 : original->Merge(splinter, zone());
452 :
453 1 : TopLevelLiveRange* result = TestRangeBuilder(zone()).Build(0, 8);
454 : LiveRange* child_1 = Split(result, 2);
455 : LiveRange* child_2 = Split(child_1, 4);
456 : LiveRange* child_3 = Split(child_2, 6);
457 : Split(child_3, 7);
458 :
459 2 : EXPECT_TRUE(RangesMatch(result, original));
460 1 : }
461 :
462 15444 : TEST_F(LiveRangeUnitTest, IDGeneration) {
463 1 : TopLevelLiveRange* vreg = TestRangeBuilder(zone()).Id(2).Build(0, 100);
464 2 : EXPECT_EQ(2, vreg->vreg());
465 2 : EXPECT_EQ(0, vreg->relative_id());
466 :
467 : TopLevelLiveRange* splinter =
468 1 : new (zone()) TopLevelLiveRange(101, MachineRepresentation::kTagged);
469 1 : vreg->SetSplinter(splinter);
470 : vreg->Splinter(LifetimePosition::FromInt(4), LifetimePosition::FromInt(12),
471 1 : zone());
472 :
473 2 : EXPECT_EQ(101, splinter->vreg());
474 2 : EXPECT_EQ(1, splinter->relative_id());
475 :
476 1 : LiveRange* child = vreg->SplitAt(LifetimePosition::FromInt(50), zone());
477 :
478 2 : EXPECT_EQ(2, child->relative_id());
479 :
480 : LiveRange* splinter_child =
481 1 : splinter->SplitAt(LifetimePosition::FromInt(8), zone());
482 :
483 2 : EXPECT_EQ(1, splinter->relative_id());
484 2 : EXPECT_EQ(3, splinter_child->relative_id());
485 :
486 1 : vreg->Merge(splinter, zone());
487 2 : EXPECT_EQ(1, splinter->relative_id());
488 1 : }
489 :
490 : } // namespace compiler
491 : } // namespace internal
492 9264 : } // namespace v8
|