blob: 30f288ff54dd8b32a592eac9bd64a2088c339d52 [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"
20#include "utils/arena_allocator.h"
21
22#include "gtest/gtest.h"
23
24namespace art {
25
26static void TestCode(const uint16_t* data, int length, const int* blocks, size_t blocks_length) {
27 ArenaPool pool;
28 ArenaAllocator allocator(&pool);
29 HGraphBuilder builder(&allocator);
30 HGraph* graph = builder.BuildGraph(data, data + length);
31 ASSERT_NE(graph, nullptr);
32 graph->BuildDominatorTree();
33 ASSERT_EQ(graph->blocks()->Size(), blocks_length);
34 for (size_t i = 0; i < blocks_length; i++) {
35 if (blocks[i] == -1) {
36 ASSERT_EQ(nullptr, graph->blocks()->Get(i)->dominator());
37 } else {
38 ASSERT_NE(nullptr, graph->blocks()->Get(i)->dominator());
39 ASSERT_EQ(blocks[i], graph->blocks()->Get(i)->dominator()->block_id());
40 }
41 }
42}
43
44TEST(OptimizerTest, ReturnVoid) {
45 const uint16_t data[] = {
46 Instruction::RETURN_VOID // Block number 1
47 };
48
49 const int dominators[] = {
50 -1,
51 0,
52 1
53 };
54
55 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
56}
57
58TEST(OptimizerTest, CFG1) {
59 const uint16_t data[] = {
60 Instruction::GOTO | 0x100, // Block number 1
61 Instruction::RETURN_VOID // Block number 2
62 };
63
64 const int dominators[] = {
65 -1,
66 0,
67 1,
68 2
69 };
70
71 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
72}
73
74TEST(OptimizerTest, CFG2) {
75 const uint16_t data[] = {
76 Instruction::GOTO | 0x100, // Block number 1
77 Instruction::GOTO | 0x100, // Block number 2
78 Instruction::RETURN_VOID // Block number 3
79 };
80
81 const int dominators[] = {
82 -1,
83 0,
84 1,
85 2,
86 3
87 };
88
89 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
90}
91
92TEST(OptimizerTest, CFG3) {
93 const uint16_t data1[] = {
94 Instruction::GOTO | 0x200, // Block number 1
95 Instruction::RETURN_VOID, // Block number 2
96 Instruction::GOTO | 0xFF00 // Block number 3
97 };
98 const int dominators[] = {
99 -1,
100 0,
101 3,
102 1,
103 2
104 };
105
106 TestCode(data1, sizeof(data1) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
107
108 const uint16_t data2[] = {
109 Instruction::GOTO_16, 3,
110 Instruction::RETURN_VOID,
111 Instruction::GOTO_16, 0xFFFF
112 };
113
114 TestCode(data2, sizeof(data2) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
115
116 const uint16_t data3[] = {
117 Instruction::GOTO_32, 4, 0,
118 Instruction::RETURN_VOID,
119 Instruction::GOTO_32, 0xFFFF, 0xFFFF
120 };
121
122 TestCode(data3, sizeof(data3) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
123}
124
125TEST(OptimizerTest, CFG4) {
126 const uint16_t data1[] = {
127 Instruction::NOP,
128 Instruction::GOTO | 0xFF00
129 };
130
131 const int dominators[] = {
132 -1,
133 0,
134 -1
135 };
136
137 TestCode(data1, sizeof(data1) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
138
139 const uint16_t data2[] = {
140 Instruction::GOTO_32, 0, 0
141 };
142
143 TestCode(data2, sizeof(data2) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
144}
145
146TEST(OptimizerTest, CFG5) {
147 const uint16_t data[] = {
148 Instruction::RETURN_VOID, // Block number 1
149 Instruction::GOTO | 0x100, // Dead block
150 Instruction::GOTO | 0xFE00 // Block number 2
151 };
152
153 const int dominators[] = {
154 -1,
155 0,
156 -1,
157 1
158 };
159
160 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
161}
162
163TEST(OptimizerTest, CFG6) {
164 const uint16_t data[] = {
165 Instruction::IF_EQ, 3,
166 Instruction::GOTO | 0x100,
167 Instruction::RETURN_VOID
168 };
169
170 const int dominators[] = {
171 -1,
172 0,
173 1,
174 1,
175 3
176 };
177
178 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
179}
180
181TEST(OptimizerTest, CFG7) {
182 const uint16_t data[] = {
183 Instruction::IF_EQ, 3, // Block number 1
184 Instruction::GOTO | 0x100, // Block number 2
185 Instruction::GOTO | 0xFF00 // Block number 3
186 };
187
188 const int dominators[] = {
189 -1,
190 0,
191 1,
192 1,
193 -1 // exit block is not dominated by any block due to the spin loop.
194 };
195
196 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
197}
198
199TEST(OptimizerTest, CFG8) {
200 const uint16_t data[] = {
201 Instruction::IF_EQ, 3, // Block number 1
202 Instruction::GOTO | 0x200, // Block number 2
203 Instruction::GOTO | 0x100, // Block number 3
204 Instruction::GOTO | 0xFF00 // Block number 4
205 };
206
207 const int dominators[] = {
208 -1,
209 0,
210 1,
211 1,
212 1,
213 -1 // exit block is not dominated by any block due to the spin loop.
214 };
215
216 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
217}
218
219TEST(OptimizerTest, CFG9) {
220 const uint16_t data[] = {
221 Instruction::IF_EQ, 3, // Block number 1
222 Instruction::GOTO | 0x200, // Block number 2
223 Instruction::GOTO | 0x100, // Block number 3
224 Instruction::GOTO | 0xFE00 // Block number 4
225 };
226
227 const int dominators[] = {
228 -1,
229 0,
230 1,
231 1,
232 1,
233 -1 // exit block is not dominated by any block due to the spin loop.
234 };
235
236 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
237}
238
239TEST(OptimizerTest, CFG10) {
240 const uint16_t data[] = {
241 Instruction::IF_EQ, 6, // Block number 1
242 Instruction::IF_EQ, 3, // Block number 2
243 Instruction::GOTO | 0x100, // Block number 3
244 Instruction::GOTO | 0x100, // Block number 4
245 Instruction::RETURN_VOID // Block number 5
246 };
247
248 const int dominators[] = {
249 -1,
250 0,
251 1,
252 2,
253 2,
254 1,
255 5 // Block number 5 dominates exit block
256 };
257
258 TestCode(data, sizeof(data) / sizeof(uint16_t), dominators, sizeof(dominators) / sizeof(int));
259}
260
261} // namespace art