1 /*
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 "base/arena_allocator.h"
18 #include "base/stringprintf.h"
19 #include "builder.h"
20 #include "dex_file.h"
21 #include "dex_instruction.h"
22 #include "nodes.h"
23 #include "optimizing_unit_test.h"
24 #include "pretty_printer.h"
25
26 #include "gtest/gtest.h"
27
28 namespace art {
29
TestCode(const uint16_t * data,const char * expected)30 static void TestCode(const uint16_t* data, const char* expected) {
31 ArenaPool pool;
32 ArenaAllocator allocator(&pool);
33 HGraph* graph = CreateGraph(&allocator);
34 HGraphBuilder builder(graph);
35 const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
36 bool graph_built = builder.BuildGraph(*item);
37 ASSERT_TRUE(graph_built);
38 StringPrettyPrinter printer(graph);
39 printer.VisitInsertionOrder();
40 ASSERT_STREQ(expected, printer.str().c_str());
41 }
42
TEST(PrettyPrinterTest,ReturnVoid)43 TEST(PrettyPrinterTest, ReturnVoid) {
44 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
45 Instruction::RETURN_VOID);
46
47 const char* expected =
48 "BasicBlock 0, succ: 1\n"
49 " 2: SuspendCheck\n"
50 " 3: Goto 1\n"
51 "BasicBlock 1, pred: 0, succ: 2\n"
52 " 0: ReturnVoid\n"
53 "BasicBlock 2, pred: 1\n"
54 " 1: Exit\n";
55
56 TestCode(data, expected);
57 }
58
TEST(PrettyPrinterTest,CFG1)59 TEST(PrettyPrinterTest, CFG1) {
60 const char* expected =
61 "BasicBlock 0, succ: 1\n"
62 " 3: SuspendCheck\n"
63 " 4: Goto 1\n"
64 "BasicBlock 1, pred: 0, succ: 2\n"
65 " 0: Goto 2\n"
66 "BasicBlock 2, pred: 1, succ: 3\n"
67 " 1: ReturnVoid\n"
68 "BasicBlock 3, pred: 2\n"
69 " 2: Exit\n";
70
71 const uint16_t data[] =
72 ZERO_REGISTER_CODE_ITEM(
73 Instruction::GOTO | 0x100,
74 Instruction::RETURN_VOID);
75
76 TestCode(data, expected);
77 }
78
TEST(PrettyPrinterTest,CFG2)79 TEST(PrettyPrinterTest, CFG2) {
80 const char* expected =
81 "BasicBlock 0, succ: 1\n"
82 " 4: SuspendCheck\n"
83 " 5: Goto 1\n"
84 "BasicBlock 1, pred: 0, succ: 2\n"
85 " 0: Goto 2\n"
86 "BasicBlock 2, pred: 1, succ: 3\n"
87 " 1: Goto 3\n"
88 "BasicBlock 3, pred: 2, succ: 4\n"
89 " 2: ReturnVoid\n"
90 "BasicBlock 4, pred: 3\n"
91 " 3: Exit\n";
92
93 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
94 Instruction::GOTO | 0x100,
95 Instruction::GOTO | 0x100,
96 Instruction::RETURN_VOID);
97
98 TestCode(data, expected);
99 }
100
TEST(PrettyPrinterTest,CFG3)101 TEST(PrettyPrinterTest, CFG3) {
102 const char* expected =
103 "BasicBlock 0, succ: 1\n"
104 " 4: SuspendCheck\n"
105 " 5: Goto 1\n"
106 "BasicBlock 1, pred: 0, succ: 3\n"
107 " 0: Goto 3\n"
108 "BasicBlock 2, pred: 3, succ: 4\n"
109 " 1: ReturnVoid\n"
110 "BasicBlock 3, pred: 1, succ: 2\n"
111 " 2: Goto 2\n"
112 "BasicBlock 4, pred: 2\n"
113 " 3: Exit\n";
114
115 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
116 Instruction::GOTO | 0x200,
117 Instruction::RETURN_VOID,
118 Instruction::GOTO | 0xFF00);
119
120 TestCode(data1, expected);
121
122 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
123 Instruction::GOTO_16, 3,
124 Instruction::RETURN_VOID,
125 Instruction::GOTO_16, 0xFFFF);
126
127 TestCode(data2, expected);
128
129 const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM(
130 Instruction::GOTO_32, 4, 0,
131 Instruction::RETURN_VOID,
132 Instruction::GOTO_32, 0xFFFF, 0xFFFF);
133
134 TestCode(data3, expected);
135 }
136
TEST(PrettyPrinterTest,CFG4)137 TEST(PrettyPrinterTest, CFG4) {
138 const char* expected =
139 "BasicBlock 0, succ: 1\n"
140 " 3: SuspendCheck\n"
141 " 4: Goto 1\n"
142 "BasicBlock 1, pred: 0, 1, succ: 1\n"
143 " 0: SuspendCheck\n"
144 " 1: Goto 1\n"
145 "BasicBlock 2\n"
146 " 2: Exit\n";
147
148 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
149 Instruction::NOP,
150 Instruction::GOTO | 0xFF00);
151
152 TestCode(data1, expected);
153
154 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
155 Instruction::GOTO_32, 0, 0);
156
157 TestCode(data2, expected);
158 }
159
TEST(PrettyPrinterTest,CFG5)160 TEST(PrettyPrinterTest, CFG5) {
161 const char* expected =
162 "BasicBlock 0, succ: 1\n"
163 " 3: SuspendCheck\n"
164 " 4: Goto 1\n"
165 "BasicBlock 1, pred: 0, 2, succ: 3\n"
166 " 0: ReturnVoid\n"
167 "BasicBlock 2, succ: 1\n"
168 " 1: Goto 1\n"
169 "BasicBlock 3, pred: 1\n"
170 " 2: Exit\n";
171
172 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
173 Instruction::RETURN_VOID,
174 Instruction::GOTO | 0x100,
175 Instruction::GOTO | 0xFE00);
176
177 TestCode(data, expected);
178 }
179
TEST(PrettyPrinterTest,CFG6)180 TEST(PrettyPrinterTest, CFG6) {
181 const char* expected =
182 "BasicBlock 0, succ: 1\n"
183 " 0: Local [4, 3, 2]\n"
184 " 1: IntConstant [2]\n"
185 " 10: SuspendCheck\n"
186 " 11: Goto 1\n"
187 "BasicBlock 1, pred: 0, succ: 3, 2\n"
188 " 2: StoreLocal(0, 1)\n"
189 " 3: LoadLocal(0) [5]\n"
190 " 4: LoadLocal(0) [5]\n"
191 " 5: Equal(3, 4) [6]\n"
192 " 6: If(5)\n"
193 "BasicBlock 2, pred: 1, succ: 3\n"
194 " 7: Goto 3\n"
195 "BasicBlock 3, pred: 1, 2, succ: 4\n"
196 " 8: ReturnVoid\n"
197 "BasicBlock 4, pred: 3\n"
198 " 9: Exit\n";
199
200 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
201 Instruction::CONST_4 | 0 | 0,
202 Instruction::IF_EQ, 3,
203 Instruction::GOTO | 0x100,
204 Instruction::RETURN_VOID);
205
206 TestCode(data, expected);
207 }
208
TEST(PrettyPrinterTest,CFG7)209 TEST(PrettyPrinterTest, CFG7) {
210 const char* expected =
211 "BasicBlock 0, succ: 1\n"
212 " 0: Local [4, 3, 2]\n"
213 " 1: IntConstant [2]\n"
214 " 11: SuspendCheck\n"
215 " 12: Goto 1\n"
216 "BasicBlock 1, pred: 0, succ: 3, 2\n"
217 " 2: StoreLocal(0, 1)\n"
218 " 3: LoadLocal(0) [5]\n"
219 " 4: LoadLocal(0) [5]\n"
220 " 5: Equal(3, 4) [6]\n"
221 " 6: If(5)\n"
222 "BasicBlock 2, pred: 1, 3, succ: 3\n"
223 " 7: Goto 3\n"
224 "BasicBlock 3, pred: 1, 2, succ: 2\n"
225 " 8: SuspendCheck\n"
226 " 9: Goto 2\n"
227 "BasicBlock 4\n"
228 " 10: Exit\n";
229
230 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
231 Instruction::CONST_4 | 0 | 0,
232 Instruction::IF_EQ, 3,
233 Instruction::GOTO | 0x100,
234 Instruction::GOTO | 0xFF00);
235
236 TestCode(data, expected);
237 }
238
TEST(PrettyPrinterTest,IntConstant)239 TEST(PrettyPrinterTest, IntConstant) {
240 const char* expected =
241 "BasicBlock 0, succ: 1\n"
242 " 0: Local [2]\n"
243 " 1: IntConstant [2]\n"
244 " 5: SuspendCheck\n"
245 " 6: Goto 1\n"
246 "BasicBlock 1, pred: 0, succ: 2\n"
247 " 2: StoreLocal(0, 1)\n"
248 " 3: ReturnVoid\n"
249 "BasicBlock 2, pred: 1\n"
250 " 4: Exit\n";
251
252 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
253 Instruction::CONST_4 | 0 | 0,
254 Instruction::RETURN_VOID);
255
256 TestCode(data, expected);
257 }
258 } // namespace art
259