blob: 0dbe3227d81419b247739eae002c536ce9ddd24a [file] [log] [blame]
Nicolas Geoffray804d0932014-05-02 08:46:00 +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"
18#include "dex_file.h"
19#include "dex_instruction.h"
20#include "nodes.h"
21#include "optimizing_unit_test.h"
22#include "ssa_liveness_analysis.h"
23#include "utils/arena_allocator.h"
24
25#include "gtest/gtest.h"
26
27namespace art {
28
29static void TestCode(const uint16_t* data, const char* expected) {
30 ArenaPool pool;
31 ArenaAllocator allocator(&pool);
32 HGraphBuilder builder(&allocator);
33 const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
34 HGraph* graph = builder.BuildGraph(*item);
35 ASSERT_NE(graph, nullptr);
36 graph->BuildDominatorTree();
37 graph->TransformToSSA();
Nicolas Geoffray0d3f5782014-05-14 09:43:38 +010038 graph->FindNaturalLoops();
Nicolas Geoffray804d0932014-05-02 08:46:00 +010039 SsaLivenessAnalysis liveness(*graph);
40 liveness.Analyze();
41
42 std::ostringstream buffer;
43 for (HInsertionOrderIterator it(*graph); !it.Done(); it.Advance()) {
44 HBasicBlock* block = it.Current();
45 buffer << "Block " << block->GetBlockId() << std::endl;
46 BitVector* live_in = liveness.GetLiveInSet(*block);
47 live_in->Dump(buffer, " live in: ");
48 BitVector* live_out = liveness.GetLiveOutSet(*block);
49 live_out->Dump(buffer, " live out: ");
50 BitVector* kill = liveness.GetKillSet(*block);
51 kill->Dump(buffer, " kill: ");
52 }
53 ASSERT_STREQ(expected, buffer.str().c_str());
54}
55
56TEST(LivenessTest, CFG1) {
57 const char* expected =
58 "Block 0\n"
59 " live in: ()\n"
60 " live out: ()\n"
61 " kill: ()\n"
62 "Block 1\n"
63 " live in: ()\n"
64 " live out: ()\n"
65 " kill: ()\n"
66 "Block 2\n"
67 " live in: ()\n"
68 " live out: ()\n"
69 " kill: ()\n";
70
71 // Constant is not used.
72 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
73 Instruction::CONST_4 | 0 | 0,
74 Instruction::RETURN_VOID);
75
76 TestCode(data, expected);
77}
78
79TEST(LivenessTest, CFG2) {
80 const char* expected =
81 "Block 0\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -070082 " live in: (00000000000000000000000000000000)\n"
83 " live out: (10000000000000000000000000000000)\n"
84 " kill: (10000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +010085 "Block 1\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -070086 " live in: (10000000000000000000000000000000)\n"
87 " live out: (00000000000000000000000000000000)\n"
88 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +010089 "Block 2\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -070090 " live in: (00000000000000000000000000000000)\n"
91 " live out: (00000000000000000000000000000000)\n"
92 " kill: (00000000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +010093
94 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
95 Instruction::CONST_4 | 0 | 0,
96 Instruction::RETURN);
97
98 TestCode(data, expected);
99}
100
101TEST(LivenessTest, CFG3) {
102 const char* expected =
103 "Block 0\n" // entry block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700104 " live in: (00000000000000000000000000000000)\n"
105 " live out: (11000000000000000000000000000000)\n"
106 " kill: (11000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100107 "Block 1\n" // block with add
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700108 " live in: (11000000000000000000000000000000)\n"
109 " live out: (00100000000000000000000000000000)\n"
110 " kill: (00100000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100111 "Block 2\n" // block with return
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700112 " live in: (00100000000000000000000000000000)\n"
113 " live out: (00000000000000000000000000000000)\n"
114 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100115 "Block 3\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700116 " live in: (00000000000000000000000000000000)\n"
117 " live out: (00000000000000000000000000000000)\n"
118 " kill: (00000000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100119
120 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
121 Instruction::CONST_4 | 3 << 12 | 0,
122 Instruction::CONST_4 | 4 << 12 | 1 << 8,
123 Instruction::ADD_INT_2ADDR | 1 << 12,
124 Instruction::GOTO | 0x100,
125 Instruction::RETURN);
126
127 TestCode(data, expected);
128}
129
130TEST(LivenessTest, CFG4) {
131 // var a;
132 // if (0 == 0) {
133 // a = 5;
134 // } else {
135 // a = 4;
136 // }
137 // return a;
138 //
139 // Bitsets are made of:
140 // (constant0, constant4, constant5, phi, equal test)
141 const char* expected =
142 "Block 0\n" // entry block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700143 " live in: (00000000000000000000000000000000)\n"
144 " live out: (11100000000000000000000000000000)\n"
145 " kill: (11100000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100146 "Block 1\n" // block with if
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700147 " live in: (11100000000000000000000000000000)\n"
148 " live out: (01100000000000000000000000000000)\n"
149 " kill: (00010000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100150 "Block 2\n" // else block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700151 " live in: (01000000000000000000000000000000)\n"
152 " live out: (00000000000000000000000000000000)\n"
153 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100154 "Block 3\n" // then block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700155 " live in: (00100000000000000000000000000000)\n"
156 " live out: (00000000000000000000000000000000)\n"
157 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100158 "Block 4\n" // return block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700159 " live in: (00000000000000000000000000000000)\n"
160 " live out: (00000000000000000000000000000000)\n"
161 " kill: (00001000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100162 "Block 5\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700163 " live in: (00000000000000000000000000000000)\n"
164 " live out: (00000000000000000000000000000000)\n"
165 " kill: (00000000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100166
167 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
168 Instruction::CONST_4 | 0 | 0,
169 Instruction::IF_EQ, 4,
170 Instruction::CONST_4 | 4 << 12 | 0,
171 Instruction::GOTO | 0x200,
172 Instruction::CONST_4 | 5 << 12 | 0,
173 Instruction::RETURN | 0 << 8);
174
175 TestCode(data, expected);
176}
177
178TEST(LivenessTest, CFG5) {
179 // var a = 0;
180 // if (0 == 0) {
181 // } else {
182 // a = 4;
183 // }
184 // return a;
185 const char* expected =
186 "Block 0\n" // entry block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700187 " live in: (00000000000000000000000000000000)\n"
188 " live out: (11000000000000000000000000000000)\n"
189 " kill: (11000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100190 "Block 1\n" // block with if
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700191 " live in: (11000000000000000000000000000000)\n"
192 " live out: (11000000000000000000000000000000)\n"
193 " kill: (00100000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100194 "Block 2\n" // else block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700195 " live in: (01000000000000000000000000000000)\n"
196 " live out: (00000000000000000000000000000000)\n"
197 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100198 "Block 3\n" // return block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700199 " live in: (00000000000000000000000000000000)\n"
200 " live out: (00000000000000000000000000000000)\n"
201 " kill: (00010000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100202 "Block 4\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700203 " live in: (00000000000000000000000000000000)\n"
204 " live out: (00000000000000000000000000000000)\n"
205 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray622d9c32014-05-12 16:11:02 +0100206 "Block 5\n" // block to avoid critical edge. Predecessor is 1, successor is 3.
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700207 " live in: (10000000000000000000000000000000)\n"
208 " live out: (00000000000000000000000000000000)\n"
209 " kill: (00000000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100210
211 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
212 Instruction::CONST_4 | 0 | 0,
213 Instruction::IF_EQ, 3,
214 Instruction::CONST_4 | 4 << 12 | 0,
215 Instruction::RETURN | 0 << 8);
216
217 TestCode(data, expected);
218}
219
220TEST(LivenessTest, Loop1) {
221 // Simple loop with one preheader and one back edge.
222 // var a = 0;
223 // while (a == a) {
224 // a = 4;
225 // }
226 // return;
227 const char* expected =
228 "Block 0\n" // entry block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700229 " live in: (00000000000000000000000000000000)\n"
230 " live out: (11000000000000000000000000000000)\n"
231 " kill: (11000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100232 "Block 1\n" // pre header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700233 " live in: (11000000000000000000000000000000)\n"
234 " live out: (01000000000000000000000000000000)\n"
235 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100236 "Block 2\n" // loop header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700237 " live in: (01000000000000000000000000000000)\n"
238 " live out: (01000000000000000000000000000000)\n"
239 " kill: (00110000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100240 "Block 3\n" // back edge
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700241 " live in: (01000000000000000000000000000000)\n"
242 " live out: (01000000000000000000000000000000)\n"
243 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100244 "Block 4\n" // return block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700245 " live in: (00000000000000000000000000000000)\n"
246 " live out: (00000000000000000000000000000000)\n"
247 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100248 "Block 5\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700249 " live in: (00000000000000000000000000000000)\n"
250 " live out: (00000000000000000000000000000000)\n"
251 " kill: (00000000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100252
253
254 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
255 Instruction::CONST_4 | 0 | 0,
256 Instruction::IF_EQ, 4,
257 Instruction::CONST_4 | 4 << 12 | 0,
258 Instruction::GOTO | 0xFD00,
259 Instruction::RETURN_VOID);
260
261 TestCode(data, expected);
262}
263
264TEST(LivenessTest, Loop3) {
265 // Test that the returned value stays live in a preceding loop.
266 // var a = 0;
267 // while (a == a) {
268 // a = 4;
269 // }
270 // return 5;
271 const char* expected =
272 "Block 0\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700273 " live in: (00000000000000000000000000000000)\n"
274 " live out: (11100000000000000000000000000000)\n"
275 " kill: (11100000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100276 "Block 1\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700277 " live in: (11100000000000000000000000000000)\n"
278 " live out: (01100000000000000000000000000000)\n"
279 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100280 "Block 2\n" // loop header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700281 " live in: (01100000000000000000000000000000)\n"
282 " live out: (01100000000000000000000000000000)\n"
283 " kill: (00011000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100284 "Block 3\n" // back edge
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700285 " live in: (01100000000000000000000000000000)\n"
286 " live out: (01100000000000000000000000000000)\n"
287 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100288 "Block 4\n" // return block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700289 " live in: (00100000000000000000000000000000)\n"
290 " live out: (00000000000000000000000000000000)\n"
291 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100292 "Block 5\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700293 " live in: (00000000000000000000000000000000)\n"
294 " live out: (00000000000000000000000000000000)\n"
295 " kill: (00000000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100296
297 const uint16_t data[] = TWO_REGISTERS_CODE_ITEM(
298 Instruction::CONST_4 | 0 | 0,
299 Instruction::IF_EQ, 4,
300 Instruction::CONST_4 | 4 << 12 | 0,
301 Instruction::GOTO | 0xFD00,
302 Instruction::CONST_4 | 5 << 12 | 1 << 8,
303 Instruction::RETURN | 1 << 8);
304
305 TestCode(data, expected);
306}
307
308
309TEST(LivenessTest, Loop4) {
310 // Make sure we support a preheader of a loop not being the first predecessor
311 // in the predecessor list of the header.
312 // var a = 0;
313 // while (a == a) {
314 // a = 4;
315 // }
316 // return a;
317 // Bitsets are made of:
318 // (constant0, constant4, phi, equal test)
319 const char* expected =
320 "Block 0\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700321 " live in: (00000000000000000000000000000000)\n"
322 " live out: (11000000000000000000000000000000)\n"
323 " kill: (11000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100324 "Block 1\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700325 " live in: (11000000000000000000000000000000)\n"
326 " live out: (11000000000000000000000000000000)\n"
327 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100328 "Block 2\n" // loop header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700329 " live in: (01000000000000000000000000000000)\n"
330 " live out: (01100000000000000000000000000000)\n"
331 " kill: (00110000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100332 "Block 3\n" // back edge
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700333 " live in: (01000000000000000000000000000000)\n"
334 " live out: (01000000000000000000000000000000)\n"
335 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100336 "Block 4\n" // pre loop header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700337 " live in: (11000000000000000000000000000000)\n"
338 " live out: (01000000000000000000000000000000)\n"
339 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100340 "Block 5\n" // return block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700341 " live in: (00100000000000000000000000000000)\n"
342 " live out: (00000000000000000000000000000000)\n"
343 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100344 "Block 6\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700345 " live in: (00000000000000000000000000000000)\n"
346 " live out: (00000000000000000000000000000000)\n"
347 " kill: (00000000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100348
349 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
350 Instruction::CONST_4 | 0 | 0,
351 Instruction::GOTO | 0x500,
352 Instruction::IF_EQ, 5,
353 Instruction::CONST_4 | 4 << 12 | 0,
354 Instruction::GOTO | 0xFD00,
355 Instruction::GOTO | 0xFC00,
356 Instruction::RETURN | 0 << 8);
357
358 TestCode(data, expected);
359}
360
361TEST(LivenessTest, Loop5) {
362 // Make sure we create a preheader of a loop when a header originally has two
363 // incoming blocks and one back edge.
364 // Bitsets are made of:
365 // (constant0, constant4, constant5, equal in block 1, phi in block 8, phi in block 4,
366 // equal in block 4)
367 const char* expected =
368 "Block 0\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700369 " live in: (00000000000000000000000000000000)\n"
370 " live out: (11100000000000000000000000000000)\n"
371 " kill: (11100000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100372 "Block 1\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700373 " live in: (11100000000000000000000000000000)\n"
374 " live out: (01100000000000000000000000000000)\n"
375 " kill: (00010000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100376 "Block 2\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700377 " live in: (01000000000000000000000000000000)\n"
378 " live out: (00000000000000000000000000000000)\n"
379 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100380 "Block 3\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700381 " live in: (00100000000000000000000000000000)\n"
382 " live out: (00000000000000000000000000000000)\n"
383 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100384 "Block 4\n" // loop header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700385 " live in: (00000000000000000000000000000000)\n"
386 " live out: (00000100000000000000000000000000)\n"
387 " kill: (00000110000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100388 "Block 5\n" // back edge
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700389 " live in: (00000100000000000000000000000000)\n"
390 " live out: (00000000000000000000000000000000)\n"
391 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100392 "Block 6\n" // return block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700393 " live in: (00000100000000000000000000000000)\n"
394 " live out: (00000000000000000000000000000000)\n"
395 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100396 "Block 7\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700397 " live in: (00000000000000000000000000000000)\n"
398 " live out: (00000000000000000000000000000000)\n"
399 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100400 "Block 8\n" // synthesized pre header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700401 " live in: (00000000000000000000000000000000)\n"
402 " live out: (00000000000000000000000000000000)\n"
403 " kill: (00001000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100404
405 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
406 Instruction::CONST_4 | 0 | 0,
407 Instruction::IF_EQ, 4,
408 Instruction::CONST_4 | 4 << 12 | 0,
409 Instruction::GOTO | 0x200,
410 Instruction::CONST_4 | 5 << 12 | 0,
411 Instruction::IF_EQ, 3,
412 Instruction::GOTO | 0xFE00,
413 Instruction::RETURN | 0 << 8);
414
415 TestCode(data, expected);
416}
417
418TEST(LivenessTest, Loop6) {
419 // Bitsets are made of:
Nicolas Geoffray622d9c32014-05-12 16:11:02 +0100420 // (constant0, constant4, constant5, phi in block 2, equal in block 2, equal in block 3,
421 // phi in block 8)
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100422 const char* expected =
423 "Block 0\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700424 " live in: (00000000000000000000000000000000)\n"
425 " live out: (11100000000000000000000000000000)\n"
426 " kill: (11100000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100427 "Block 1\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700428 " live in: (11100000000000000000000000000000)\n"
429 " live out: (01100000000000000000000000000000)\n"
430 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100431 "Block 2\n" // loop header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700432 " live in: (01100000000000000000000000000000)\n"
433 " live out: (01110000000000000000000000000000)\n"
434 " kill: (00011000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100435 "Block 3\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700436 " live in: (01100000000000000000000000000000)\n"
437 " live out: (01100000000000000000000000000000)\n"
438 " kill: (00000100000000000000000000000000)\n"
Nicolas Geoffray622d9c32014-05-12 16:11:02 +0100439 "Block 4\n" // original back edge
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700440 " live in: (01100000000000000000000000000000)\n"
441 " live out: (01100000000000000000000000000000)\n"
442 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray622d9c32014-05-12 16:11:02 +0100443 "Block 5\n" // original back edge
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700444 " live in: (01100000000000000000000000000000)\n"
445 " live out: (01100000000000000000000000000000)\n"
446 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100447 "Block 6\n" // return block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700448 " live in: (00010000000000000000000000000000)\n"
449 " live out: (00000000000000000000000000000000)\n"
450 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100451 "Block 7\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700452 " live in: (00000000000000000000000000000000)\n"
453 " live out: (00000000000000000000000000000000)\n"
454 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray622d9c32014-05-12 16:11:02 +0100455 "Block 8\n" // synthesized back edge
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700456 " live in: (01100000000000000000000000000000)\n"
457 " live out: (01100000000000000000000000000000)\n"
458 " kill: (00000010000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100459
460 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
461 Instruction::CONST_4 | 0 | 0,
462 Instruction::IF_EQ, 8,
463 Instruction::CONST_4 | 4 << 12 | 0,
464 Instruction::IF_EQ, 4,
465 Instruction::CONST_4 | 5 << 12 | 0,
466 Instruction::GOTO | 0xFA00,
467 Instruction::GOTO | 0xF900,
468 Instruction::RETURN | 0 << 8);
469
470 TestCode(data, expected);
471}
472
473
474TEST(LivenessTest, Loop7) {
475 // Bitsets are made of:
476 // (constant0, constant4, constant5, phi in block 2, equal in block 2, equal in block 3,
477 // phi in block 6)
478 const char* expected =
479 "Block 0\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700480 " live in: (00000000000000000000000000000000)\n"
481 " live out: (11100000000000000000000000000000)\n"
482 " kill: (11100000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100483 "Block 1\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700484 " live in: (11100000000000000000000000000000)\n"
485 " live out: (01100000000000000000000000000000)\n"
486 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100487 "Block 2\n" // loop header
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700488 " live in: (01100000000000000000000000000000)\n"
489 " live out: (01110000000000000000000000000000)\n"
490 " kill: (00011000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100491 "Block 3\n"
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700492 " live in: (01100000000000000000000000000000)\n"
493 " live out: (01100000000000000000000000000000)\n"
494 " kill: (00000100000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100495 "Block 4\n" // loop exit
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700496 " live in: (00100000000000000000000000000000)\n"
497 " live out: (00000000000000000000000000000000)\n"
498 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100499 "Block 5\n" // back edge
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700500 " live in: (01100000000000000000000000000000)\n"
501 " live out: (01100000000000000000000000000000)\n"
502 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100503 "Block 6\n" // return block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700504 " live in: (00000000000000000000000000000000)\n"
505 " live out: (00000000000000000000000000000000)\n"
506 " kill: (00000010000000000000000000000000)\n"
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100507 "Block 7\n" // exit block
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700508 " live in: (00000000000000000000000000000000)\n"
509 " live out: (00000000000000000000000000000000)\n"
510 " kill: (00000000000000000000000000000000)\n"
Nicolas Geoffray622d9c32014-05-12 16:11:02 +0100511 "Block 8\n" // synthesized block to avoid critical edge.
Jean Christophe Beyler014d77a2014-06-02 11:21:21 -0700512 " live in: (00010000000000000000000000000000)\n"
513 " live out: (00000000000000000000000000000000)\n"
514 " kill: (00000000000000000000000000000000)\n";
Nicolas Geoffray804d0932014-05-02 08:46:00 +0100515
516 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
517 Instruction::CONST_4 | 0 | 0,
518 Instruction::IF_EQ, 8,
519 Instruction::CONST_4 | 4 << 12 | 0,
520 Instruction::IF_EQ, 4,
521 Instruction::CONST_4 | 5 << 12 | 0,
522 Instruction::GOTO | 0x0200,
523 Instruction::GOTO | 0xF900,
524 Instruction::RETURN | 0 << 8);
525
526 TestCode(data, expected);
527}
528
529} // namespace art