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