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