blob: 92742f9a06c07d5e215144dab58d6c1954f64192 [file] [log] [blame]
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +01001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "builder.h"
Nicolas Geoffray31d76b42014-06-09 15:02:22 +010018#include "code_generator.h"
Nicolas Geoffray8a16d972014-09-11 10:30:02 +010019#include "code_generator_x86.h"
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010020#include "dex_file.h"
21#include "dex_instruction.h"
Calin Juravlecd6dffe2015-01-08 17:35:35 +000022#include "driver/compiler_options.h"
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010023#include "nodes.h"
24#include "optimizing_unit_test.h"
Nicolas Geoffray360231a2014-10-08 21:07:48 +010025#include "prepare_for_register_allocation.h"
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010026#include "ssa_liveness_analysis.h"
27#include "utils/arena_allocator.h"
28
29#include "gtest/gtest.h"
30
31namespace art {
32
33static HGraph* BuildGraph(const uint16_t* data, ArenaAllocator* allocator) {
34 HGraphBuilder builder(allocator);
35 const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
36 HGraph* graph = builder.BuildGraph(*item);
Nicolas Geoffrayfbc695f2014-09-15 15:33:30 +000037 // Suspend checks implementation may change in the future, and this test relies
38 // on how instructions are ordered.
39 RemoveSuspendChecks(graph);
Nicolas Geoffraye53798a2014-12-01 10:31:54 +000040 graph->TryBuildingSsa();
Nicolas Geoffray360231a2014-10-08 21:07:48 +010041 // `Inline` conditions into ifs.
42 PrepareForRegisterAllocation(graph).Run();
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010043 return graph;
44}
45
46TEST(LiveRangesTest, CFG1) {
47 /*
48 * Test the following snippet:
49 * return 0;
50 *
51 * Which becomes the following graph (numbered by lifetime position):
52 * 2: constant0
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010053 * 4: goto
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010054 * |
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010055 * 8: return
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010056 * |
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010057 * 12: exit
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010058 */
59 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
60 Instruction::CONST_4 | 0 | 0,
61 Instruction::RETURN);
62
63 ArenaPool pool;
64 ArenaAllocator allocator(&pool);
65 HGraph* graph = BuildGraph(data, &allocator);
Nicolas Geoffray31d76b42014-06-09 15:02:22 +010066
Calin Juravlecd6dffe2015-01-08 17:35:35 +000067 x86::CodeGeneratorX86 codegen(graph, CompilerOptions());
Nicolas Geoffray8a16d972014-09-11 10:30:02 +010068 SsaLivenessAnalysis liveness(*graph, &codegen);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010069 liveness.Analyze();
70
71 LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010072 LiveRange* range = interval->GetFirstRange();
73 ASSERT_EQ(2u, range->GetStart());
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010074 // Last use is the return instruction.
Nicolas Geoffray8e3964b2014-10-17 11:06:38 +010075 ASSERT_EQ(8u, range->GetEnd());
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010076 HBasicBlock* block = graph->GetBlocks().Get(1);
Roland Levillain476df552014-10-09 17:51:36 +010077 ASSERT_TRUE(block->GetLastInstruction()->IsReturn());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010078 ASSERT_EQ(8u, block->GetLastInstruction()->GetLifetimePosition());
79 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010080}
81
82TEST(LiveRangesTest, CFG2) {
83 /*
84 * Test the following snippet:
85 * var a = 0;
86 * if (0 == 0) {
87 * } else {
88 * }
89 * return a;
90 *
91 * Which becomes the following graph (numbered by lifetime position):
92 * 2: constant0
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010093 * 4: goto
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010094 * |
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010095 * 8: equal
96 * 10: if
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010097 * / \
Nicolas Geoffraya7062e02014-05-22 12:50:17 +010098 * 14: goto 18: goto
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +010099 * \ /
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100100 * 22: return
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100101 * |
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100102 * 26: exit
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100103 */
104 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
105 Instruction::CONST_4 | 0 | 0,
106 Instruction::IF_EQ, 3,
107 Instruction::GOTO | 0x100,
108 Instruction::RETURN | 0 << 8);
109
110 ArenaPool pool;
111 ArenaAllocator allocator(&pool);
112 HGraph* graph = BuildGraph(data, &allocator);
Calin Juravlecd6dffe2015-01-08 17:35:35 +0000113 x86::CodeGeneratorX86 codegen(graph, CompilerOptions());
Nicolas Geoffray8a16d972014-09-11 10:30:02 +0100114 SsaLivenessAnalysis liveness(*graph, &codegen);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100115 liveness.Analyze();
116
117 LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100118 LiveRange* range = interval->GetFirstRange();
119 ASSERT_EQ(2u, range->GetStart());
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100120 // Last use is the return instruction.
Nicolas Geoffray8e3964b2014-10-17 11:06:38 +0100121 ASSERT_EQ(22u, range->GetEnd());
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100122 HBasicBlock* block = graph->GetBlocks().Get(3);
Roland Levillain476df552014-10-09 17:51:36 +0100123 ASSERT_TRUE(block->GetLastInstruction()->IsReturn());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100124 ASSERT_EQ(22u, block->GetLastInstruction()->GetLifetimePosition());
125 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100126}
127
128TEST(LiveRangesTest, CFG3) {
129 /*
130 * Test the following snippet:
131 * var a = 0;
132 * if (0 == 0) {
133 * } else {
134 * a = 4;
135 * }
136 * return a;
137 *
138 * Which becomes the following graph (numbered by lifetime position):
139 * 2: constant0
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100140 * 4: constant4
141 * 6: goto
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100142 * |
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100143 * 10: equal
144 * 12: if
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100145 * / \
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100146 * 16: goto 20: goto
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100147 * \ /
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100148 * 22: phi
149 * 24: return
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100150 * |
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100151 * 28: exit
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100152 */
153 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
154 Instruction::CONST_4 | 0 | 0,
155 Instruction::IF_EQ, 3,
156 Instruction::CONST_4 | 4 << 12 | 0,
157 Instruction::RETURN | 0 << 8);
158
159 ArenaPool pool;
160 ArenaAllocator allocator(&pool);
161 HGraph* graph = BuildGraph(data, &allocator);
Calin Juravlecd6dffe2015-01-08 17:35:35 +0000162 x86::CodeGeneratorX86 codegen(graph, CompilerOptions());
Nicolas Geoffray8a16d972014-09-11 10:30:02 +0100163 SsaLivenessAnalysis liveness(*graph, &codegen);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100164 liveness.Analyze();
165
Nicolas Geoffrayec7e4722014-06-06 11:24:33 +0100166 // Test for the 4 constant.
167 LiveInterval* interval = liveness.GetInstructionFromSsaIndex(1)->GetLiveInterval();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100168 LiveRange* range = interval->GetFirstRange();
Nicolas Geoffrayec7e4722014-06-06 11:24:33 +0100169 ASSERT_EQ(4u, range->GetStart());
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100170 // Last use is the phi at the return block so instruction is live until
171 // the end of the then block.
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100172 ASSERT_EQ(18u, range->GetEnd());
173 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100174
Nicolas Geoffrayec7e4722014-06-06 11:24:33 +0100175 // Test for the 0 constant.
176 interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100177 // The then branch is a hole for this constant, therefore its interval has 2 ranges.
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100178 // First range starts from the definition and ends at the if block.
179 range = interval->GetFirstRange();
Nicolas Geoffrayec7e4722014-06-06 11:24:33 +0100180 ASSERT_EQ(2u, range->GetStart());
181 // 14 is the end of the if block.
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100182 ASSERT_EQ(14u, range->GetEnd());
183 // Second range is the else block.
184 range = range->GetNext();
185 ASSERT_EQ(18u, range->GetStart());
186 // Last use is the phi at the return block.
187 ASSERT_EQ(22u, range->GetEnd());
188 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100189
190 // Test for the phi.
Nicolas Geoffraye5038322014-07-04 09:41:32 +0100191 interval = liveness.GetInstructionFromSsaIndex(2)->GetLiveInterval();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100192 range = interval->GetFirstRange();
Nicolas Geoffraye5038322014-07-04 09:41:32 +0100193 ASSERT_EQ(22u, liveness.GetInstructionFromSsaIndex(2)->GetLifetimePosition());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100194 ASSERT_EQ(22u, range->GetStart());
Nicolas Geoffray8e3964b2014-10-17 11:06:38 +0100195 ASSERT_EQ(24u, range->GetEnd());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100196 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100197}
198
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100199TEST(LiveRangesTest, Loop1) {
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100200 /*
201 * Test the following snippet:
202 * var a = 0;
203 * while (a == a) {
204 * a = 4;
205 * }
206 * return 5;
207 *
208 * Which becomes the following graph (numbered by lifetime position):
209 * 2: constant0
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100210 * 4: constant4
211 * 6: constant5
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100212 * 8: goto
213 * |
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100214 * 12: goto
215 * |
216 * 14: phi
217 * 16: equal
218 * 18: if +++++
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100219 * | \ +
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100220 * | 22: goto
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100221 * |
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100222 * 26: return
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100223 * |
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100224 * 30: exit
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100225 */
226
227 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
228 Instruction::CONST_4 | 0 | 0,
229 Instruction::IF_EQ, 4,
230 Instruction::CONST_4 | 4 << 12 | 0,
231 Instruction::GOTO | 0xFD00,
232 Instruction::CONST_4 | 5 << 12 | 1 << 8,
233 Instruction::RETURN | 1 << 8);
234
235 ArenaPool pool;
236 ArenaAllocator allocator(&pool);
237 HGraph* graph = BuildGraph(data, &allocator);
Nicolas Geoffray9ebc72c2014-09-25 16:33:42 +0100238 RemoveSuspendChecks(graph);
Calin Juravlecd6dffe2015-01-08 17:35:35 +0000239 x86::CodeGeneratorX86 codegen(graph, CompilerOptions());
Nicolas Geoffray8a16d972014-09-11 10:30:02 +0100240 SsaLivenessAnalysis liveness(*graph, &codegen);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100241 liveness.Analyze();
242
243 // Test for the 0 constant.
244 LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100245 LiveRange* range = interval->GetFirstRange();
246 ASSERT_EQ(2u, range->GetStart());
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100247 // Last use is the loop phi so instruction is live until
248 // the end of the pre loop header.
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100249 ASSERT_EQ(14u, range->GetEnd());
250 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100251
252 // Test for the 4 constant.
253 interval = liveness.GetInstructionFromSsaIndex(1)->GetLiveInterval();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100254 range = interval->GetFirstRange();
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100255 // The instruction is live until the end of the loop.
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100256 ASSERT_EQ(4u, range->GetStart());
257 ASSERT_EQ(24u, range->GetEnd());
258 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100259
260 // Test for the 5 constant.
261 interval = liveness.GetInstructionFromSsaIndex(2)->GetLiveInterval();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100262 range = interval->GetFirstRange();
263 // The instruction is live until the return instruction after the loop.
264 ASSERT_EQ(6u, range->GetStart());
Nicolas Geoffray8e3964b2014-10-17 11:06:38 +0100265 ASSERT_EQ(26u, range->GetEnd());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100266 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100267
268 // Test for the phi.
269 interval = liveness.GetInstructionFromSsaIndex(3)->GetLiveInterval();
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100270 range = interval->GetFirstRange();
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100271 // Instruction is consumed by the if.
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100272 ASSERT_EQ(14u, range->GetStart());
Nicolas Geoffray8e3964b2014-10-17 11:06:38 +0100273 ASSERT_EQ(17u, range->GetEnd());
Nicolas Geoffraya7062e02014-05-22 12:50:17 +0100274 ASSERT_TRUE(range->GetNext() == nullptr);
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100275}
276
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100277TEST(LiveRangesTest, Loop2) {
278 /*
279 * Test the following snippet:
280 * var a = 0;
281 * while (a == a) {
282 * a = a + a;
283 * }
284 * return a;
285 *
286 * Which becomes the following graph (numbered by lifetime position):
287 * 2: constant0
288 * 4: goto
289 * |
290 * 8: goto
291 * |
292 * 10: phi
293 * 12: equal
294 * 14: if +++++
295 * | \ +
296 * | 18: suspend
297 * | 20: add
298 * | 22: goto
299 * |
300 * 26: return
301 * |
302 * 30: exit
303 *
304 * We want to make sure the phi at 10 has a lifetime hole after the add at 20.
305 */
306
307 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
308 Instruction::CONST_4 | 0 | 0,
309 Instruction::IF_EQ, 6,
310 Instruction::ADD_INT, 0, 0,
311 Instruction::GOTO | 0xFB00,
312 Instruction::RETURN | 0 << 8);
313
314 ArenaPool pool;
315 ArenaAllocator allocator(&pool);
316 HGraph* graph = BuildGraph(data, &allocator);
Calin Juravlecd6dffe2015-01-08 17:35:35 +0000317 x86::CodeGeneratorX86 codegen(graph, CompilerOptions());
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100318 SsaLivenessAnalysis liveness(*graph, &codegen);
319 liveness.Analyze();
320
321 // Test for the 0 constant.
322 HIntConstant* constant = liveness.GetInstructionFromSsaIndex(0)->AsIntConstant();
323 LiveInterval* interval = constant->GetLiveInterval();
324 LiveRange* range = interval->GetFirstRange();
325 ASSERT_EQ(2u, range->GetStart());
326 // Last use is the loop phi so instruction is live until
327 // the end of the pre loop header.
328 ASSERT_EQ(10u, range->GetEnd());
329 ASSERT_TRUE(range->GetNext() == nullptr);
330
331 // Test for the loop phi.
332 HPhi* phi = liveness.GetInstructionFromSsaIndex(1)->AsPhi();
333 interval = phi->GetLiveInterval();
334 range = interval->GetFirstRange();
335 ASSERT_EQ(10u, range->GetStart());
336 ASSERT_EQ(21u, range->GetEnd());
337 range = range->GetNext();
338 ASSERT_TRUE(range != nullptr);
339 ASSERT_EQ(24u, range->GetStart());
Nicolas Geoffray8e3964b2014-10-17 11:06:38 +0100340 ASSERT_EQ(26u, range->GetEnd());
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100341
342 // Test for the add instruction.
343 HAdd* add = liveness.GetInstructionFromSsaIndex(2)->AsAdd();
344 interval = add->GetLiveInterval();
345 range = interval->GetFirstRange();
346 ASSERT_EQ(20u, range->GetStart());
347 ASSERT_EQ(24u, range->GetEnd());
348 ASSERT_TRUE(range->GetNext() == nullptr);
349}
350
351TEST(LiveRangesTest, CFG4) {
352 /*
353 * Test the following snippet:
354 * var a = 0;
355 * var b = 4;
356 * if (a == a) {
357 * a = b + a;
358 * } else {
359 * a = b + a
360 * }
361 * return b;
362 *
363 * Which becomes the following graph (numbered by lifetime position):
364 * 2: constant0
365 * 4: constant4
366 * 6: goto
367 * |
368 * 10: equal
369 * 12: if
370 * / \
371 * 16: add 22: add
372 * 18: goto 24: goto
373 * \ /
374 * 26: phi
375 * 28: return
376 * |
377 * 32: exit
378 *
379 * We want to make sure the constant0 has a lifetime hole after the 16: add.
380 */
381 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
382 Instruction::CONST_4 | 0 | 0,
383 Instruction::CONST_4 | 4 << 12 | 1 << 8,
384 Instruction::IF_EQ, 5,
385 Instruction::ADD_INT, 1 << 8,
386 Instruction::GOTO | 0x300,
387 Instruction::ADD_INT, 1 << 8,
Nicolas Geoffraya3c00e52014-11-25 11:18:37 +0000388 Instruction::RETURN);
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100389
390 ArenaPool pool;
391 ArenaAllocator allocator(&pool);
392 HGraph* graph = BuildGraph(data, &allocator);
Calin Juravlecd6dffe2015-01-08 17:35:35 +0000393 x86::CodeGeneratorX86 codegen(graph, CompilerOptions());
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100394 SsaLivenessAnalysis liveness(*graph, &codegen);
395 liveness.Analyze();
396
397 // Test for the 0 constant.
398 LiveInterval* interval = liveness.GetInstructionFromSsaIndex(0)->GetLiveInterval();
399 LiveRange* range = interval->GetFirstRange();
400 ASSERT_EQ(2u, range->GetStart());
401 ASSERT_EQ(16u, range->GetEnd());
402 range = range->GetNext();
403 ASSERT_TRUE(range != nullptr);
404 ASSERT_EQ(20u, range->GetStart());
405 ASSERT_EQ(22u, range->GetEnd());
406 ASSERT_TRUE(range->GetNext() == nullptr);
407
408 // Test for the 4 constant.
409 interval = liveness.GetInstructionFromSsaIndex(1)->GetLiveInterval();
410 range = interval->GetFirstRange();
411 ASSERT_EQ(4u, range->GetStart());
Nicolas Geoffraya3c00e52014-11-25 11:18:37 +0000412 ASSERT_EQ(17u, range->GetEnd());
413 range = range->GetNext();
414 ASSERT_EQ(20u, range->GetStart());
415 ASSERT_EQ(23u, range->GetEnd());
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100416 ASSERT_TRUE(range->GetNext() == nullptr);
417
418 // Test for the first add.
419 HAdd* add = liveness.GetInstructionFromSsaIndex(2)->AsAdd();
420 interval = add->GetLiveInterval();
421 range = interval->GetFirstRange();
422 ASSERT_EQ(16u, range->GetStart());
423 ASSERT_EQ(20u, range->GetEnd());
424 ASSERT_TRUE(range->GetNext() == nullptr);
425
426 // Test for the second add.
427 add = liveness.GetInstructionFromSsaIndex(3)->AsAdd();
428 interval = add->GetLiveInterval();
429 range = interval->GetFirstRange();
430 ASSERT_EQ(22u, range->GetStart());
431 ASSERT_EQ(26u, range->GetEnd());
432 ASSERT_TRUE(range->GetNext() == nullptr);
433
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100434 HPhi* phi = liveness.GetInstructionFromSsaIndex(4)->AsPhi();
David Brazdilea55b932015-01-27 17:12:29 +0000435 ASSERT_TRUE(phi->GetUses().HasOnlyOneUse());
Nicolas Geoffray8ddb00c2014-09-29 12:00:40 +0100436 interval = phi->GetLiveInterval();
437 range = interval->GetFirstRange();
438 ASSERT_EQ(26u, range->GetStart());
439 ASSERT_EQ(28u, range->GetEnd());
440 ASSERT_TRUE(range->GetNext() == nullptr);
441}
442
Nicolas Geoffrayddb311f2014-05-16 09:28:54 +0100443} // namespace art