blob: 9b685352682b2ca7ac7ee164779a9c366ca68d34 [file] [log] [blame]
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +00001/*
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_instruction.h"
19#include "nodes.h"
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000020#include "optimizing_unit_test.h"
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000021#include "utils/arena_allocator.h"
22
23#include "gtest/gtest.h"
24
25namespace art {
26
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000027static void TestCode(const uint16_t* data, const int* blocks, size_t blocks_length) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000028 ArenaPool pool;
29 ArenaAllocator allocator(&pool);
30 HGraphBuilder builder(&allocator);
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000031 const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
32 HGraph* graph = builder.BuildGraph(*item);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000033 ASSERT_NE(graph, nullptr);
34 graph->BuildDominatorTree();
35 ASSERT_EQ(graph->blocks()->Size(), blocks_length);
36 for (size_t i = 0; i < blocks_length; i++) {
37 if (blocks[i] == -1) {
38 ASSERT_EQ(nullptr, graph->blocks()->Get(i)->dominator());
39 } else {
40 ASSERT_NE(nullptr, graph->blocks()->Get(i)->dominator());
41 ASSERT_EQ(blocks[i], graph->blocks()->Get(i)->dominator()->block_id());
42 }
43 }
44}
45
46TEST(OptimizerTest, ReturnVoid) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000047 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
48 Instruction::RETURN_VOID); // Block number 1
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000049
50 const int dominators[] = {
51 -1,
52 0,
53 1
54 };
55
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000056 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000057}
58
59TEST(OptimizerTest, CFG1) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000060 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000061 Instruction::GOTO | 0x100, // Block number 1
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000062 Instruction::RETURN_VOID); // Block number 2
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000063
64 const int dominators[] = {
65 -1,
66 0,
67 1,
68 2
69 };
70
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000071 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000072}
73
74TEST(OptimizerTest, CFG2) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000075 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000076 Instruction::GOTO | 0x100, // Block number 1
77 Instruction::GOTO | 0x100, // Block number 2
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000078 Instruction::RETURN_VOID); // Block number 3
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000079
80 const int dominators[] = {
81 -1,
82 0,
83 1,
84 2,
85 3
86 };
87
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000088 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000089}
90
91TEST(OptimizerTest, CFG3) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000092 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
93 Instruction::GOTO | 0x200, // Block number 1
94 Instruction::RETURN_VOID, // Block number 2
95 Instruction::GOTO | 0xFF00); // Block number 3
96
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000097 const int dominators[] = {
98 -1,
99 0,
100 3,
101 1,
102 2
103 };
104
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000105 TestCode(data1, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000106
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000107 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000108 Instruction::GOTO_16, 3,
109 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000110 Instruction::GOTO_16, 0xFFFF);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000111
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000112 TestCode(data2, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000113
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000114 const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000115 Instruction::GOTO_32, 4, 0,
116 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000117 Instruction::GOTO_32, 0xFFFF, 0xFFFF);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000118
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000119 TestCode(data3, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000120}
121
122TEST(OptimizerTest, CFG4) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000123 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000124 Instruction::NOP,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000125 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000126
127 const int dominators[] = {
128 -1,
129 0,
130 -1
131 };
132
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000133 TestCode(data1, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000134
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000135 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
136 Instruction::GOTO_32, 0, 0);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000137
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000138 TestCode(data2, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000139}
140
141TEST(OptimizerTest, CFG5) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000142 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
143 Instruction::RETURN_VOID, // Block number 1
144 Instruction::GOTO | 0x100, // Dead block
145 Instruction::GOTO | 0xFE00); // Block number 2
146
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000147
148 const int dominators[] = {
149 -1,
150 0,
151 -1,
152 1
153 };
154
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000155 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000156}
157
158TEST(OptimizerTest, CFG6) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000159 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
160 Instruction::CONST_4 | 0 | 0,
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000161 Instruction::IF_EQ, 3,
162 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000163 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000164
165 const int dominators[] = {
166 -1,
167 0,
168 1,
169 1,
170 3
171 };
172
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000173 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000174}
175
176TEST(OptimizerTest, CFG7) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000177 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
178 Instruction::CONST_4 | 0 | 0,
179 Instruction::IF_EQ, 3, // Block number 1
180 Instruction::GOTO | 0x100, // Block number 2
181 Instruction::GOTO | 0xFF00); // Block number 3
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000182
183 const int dominators[] = {
184 -1,
185 0,
186 1,
187 1,
188 -1 // exit block is not dominated by any block due to the spin loop.
189 };
190
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000191 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000192}
193
194TEST(OptimizerTest, CFG8) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000195 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
196 Instruction::CONST_4 | 0 | 0,
197 Instruction::IF_EQ, 3, // Block number 1
198 Instruction::GOTO | 0x200, // Block number 2
199 Instruction::GOTO | 0x100, // Block number 3
200 Instruction::GOTO | 0xFF00); // Block number 4
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000201
202 const int dominators[] = {
203 -1,
204 0,
205 1,
206 1,
207 1,
208 -1 // exit block is not dominated by any block due to the spin loop.
209 };
210
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000211 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000212}
213
214TEST(OptimizerTest, CFG9) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000215 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
216 Instruction::CONST_4 | 0 | 0,
217 Instruction::IF_EQ, 3, // Block number 1
218 Instruction::GOTO | 0x200, // Block number 2
219 Instruction::GOTO | 0x100, // Block number 3
220 Instruction::GOTO | 0xFE00); // Block number 4
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000221
222 const int dominators[] = {
223 -1,
224 0,
225 1,
226 1,
227 1,
228 -1 // exit block is not dominated by any block due to the spin loop.
229 };
230
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000231 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000232}
233
234TEST(OptimizerTest, CFG10) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000235 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
236 Instruction::CONST_4 | 0 | 0,
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000237 Instruction::IF_EQ, 6, // Block number 1
238 Instruction::IF_EQ, 3, // Block number 2
239 Instruction::GOTO | 0x100, // Block number 3
240 Instruction::GOTO | 0x100, // Block number 4
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000241 Instruction::RETURN_VOID); // Block number 5
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000242
243 const int dominators[] = {
244 -1,
245 0,
246 1,
247 2,
248 2,
249 1,
250 5 // Block number 5 dominates exit block
251 };
252
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000253 TestCode(data, dominators, sizeof(dominators) / sizeof(int));
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000254}
255
256} // namespace art