blob: 951cdfbd8b7efaef5c7cab1648b5ce887d0ae142 [file] [log] [blame]
Nicolas Geoffray818f2102014-02-18 16:43:35 +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
Mathieu Chartierb666f482015-02-18 14:33:14 -080017#include "base/arena_allocator.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000018#include "base/stringprintf.h"
19#include "builder.h"
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000020#include "dex_file.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000021#include "dex_instruction.h"
22#include "nodes.h"
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000023#include "optimizing_unit_test.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000024#include "pretty_printer.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000025
26#include "gtest/gtest.h"
27
28namespace art {
29
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000030static void TestCode(const uint16_t* data, const char* expected) {
Nicolas Geoffray818f2102014-02-18 16:43:35 +000031 ArenaPool pool;
32 ArenaAllocator allocator(&pool);
David Brazdilbadd8262016-02-02 16:28:56 +000033 HGraph* graph = CreateCFG(&allocator, data);
Nicolas Geoffray818f2102014-02-18 16:43:35 +000034 StringPrettyPrinter printer(graph);
35 printer.VisitInsertionOrder();
36 ASSERT_STREQ(expected, printer.str().c_str());
Nicolas Geoffray818f2102014-02-18 16:43:35 +000037}
38
David Brazdilbadd8262016-02-02 16:28:56 +000039class PrettyPrinterTest : public CommonCompilerTest {};
40
41TEST_F(PrettyPrinterTest, ReturnVoid) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000042 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
43 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000044
45 const char* expected =
46 "BasicBlock 0, succ: 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000047 " 0: SuspendCheck\n"
48 " 1: Goto 1\n"
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000049 "BasicBlock 1, pred: 0, succ: 2\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000050 " 2: ReturnVoid\n"
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000051 "BasicBlock 2, pred: 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000052 " 3: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000053
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000054 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000055}
56
David Brazdilbadd8262016-02-02 16:28:56 +000057TEST_F(PrettyPrinterTest, CFG1) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000058 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +000059 "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";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000068
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000069 const uint16_t data[] =
70 ZERO_REGISTER_CODE_ITEM(
71 Instruction::GOTO | 0x100,
72 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000073
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000074 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000075}
76
David Brazdilbadd8262016-02-02 16:28:56 +000077TEST_F(PrettyPrinterTest, CFG2) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000078 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +000079 "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";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000090
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000091 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000092 Instruction::GOTO | 0x100,
93 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000094 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000095
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000096 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000097}
98
David Brazdilbadd8262016-02-02 16:28:56 +000099TEST_F(PrettyPrinterTest, CFG3) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000100 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000101 "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"
David Brazdildee58d62016-04-07 09:54:26 +0000107 " 4: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000108 "BasicBlock 3, pred: 1, succ: 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000109 " 3: Goto 2\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000110 "BasicBlock 4, pred: 2\n"
111 " 5: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000112
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000113 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000114 Instruction::GOTO | 0x200,
115 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000116 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000117
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000118 TestCode(data1, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000119
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000120 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000121 Instruction::GOTO_16, 3,
122 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000123 Instruction::GOTO_16, 0xFFFF);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000124
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000125 TestCode(data2, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000126
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000127 const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000128 Instruction::GOTO_32, 4, 0,
129 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000130 Instruction::GOTO_32, 0xFFFF, 0xFFFF);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000131
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000132 TestCode(data3, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000133}
134
David Brazdilbadd8262016-02-02 16:28:56 +0000135TEST_F(PrettyPrinterTest, CFG4) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000136 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000137 "BasicBlock 0, succ: 3\n"
David Brazdil60328912016-04-04 17:47:42 +0000138 " 1: SuspendCheck\n"
David Brazdildee58d62016-04-07 09:54:26 +0000139 " 2: Goto 3\n"
140 "BasicBlock 1, pred: 3, 1, succ: 1\n"
141 " 3: SuspendCheck\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000142 " 4: Goto 1\n"
143 "BasicBlock 3, pred: 0, succ: 1\n"
144 " 0: Goto 1\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000145
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000146 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000147 Instruction::NOP,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000148 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000149
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000150 TestCode(data1, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000151
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000152 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
153 Instruction::GOTO_32, 0, 0);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000154
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000155 TestCode(data2, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000156}
157
David Brazdilbadd8262016-02-02 16:28:56 +0000158TEST_F(PrettyPrinterTest, CFG5) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000159 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000160 "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";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000167
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000168 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000169 Instruction::RETURN_VOID,
170 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000171 Instruction::GOTO | 0xFE00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000172
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000173 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000174}
175
David Brazdilbadd8262016-02-02 16:28:56 +0000176TEST_F(PrettyPrinterTest, CFG6) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000177 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000178 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000179 " 3: IntConstant [4, 4]\n"
180 " 1: SuspendCheck\n"
181 " 2: Goto 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000182 "BasicBlock 1, pred: 0, succ: 5, 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000183 " 4: Equal(3, 3) [5]\n"
184 " 5: If(4)\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000185 "BasicBlock 2, pred: 1, succ: 3\n"
David Brazdildee58d62016-04-07 09:54:26 +0000186 " 6: Goto 3\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000187 "BasicBlock 3, pred: 5, 2, succ: 4\n"
David Brazdildee58d62016-04-07 09:54:26 +0000188 " 7: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000189 "BasicBlock 4, pred: 3\n"
David Brazdildee58d62016-04-07 09:54:26 +0000190 " 8: Exit\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000191 "BasicBlock 5, pred: 1, succ: 3\n"
192 " 0: Goto 3\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000193
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000194 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
195 Instruction::CONST_4 | 0 | 0,
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000196 Instruction::IF_EQ, 3,
197 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000198 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000199
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000200 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000201}
202
David Brazdilbadd8262016-02-02 16:28:56 +0000203TEST_F(PrettyPrinterTest, CFG7) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000204 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000205 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000206 " 4: IntConstant [5, 5]\n"
David Brazdil60328912016-04-04 17:47:42 +0000207 " 2: SuspendCheck\n"
David Brazdildee58d62016-04-07 09:54:26 +0000208 " 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"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000217 "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";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000221
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000222 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
223 Instruction::CONST_4 | 0 | 0,
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000224 Instruction::IF_EQ, 3,
225 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000226 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000227
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000228 TestCode(data, expected);
229}
230
David Brazdilbadd8262016-02-02 16:28:56 +0000231TEST_F(PrettyPrinterTest, IntConstant) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000232 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000233 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000234 " 2: IntConstant\n"
235 " 0: SuspendCheck\n"
236 " 1: Goto 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000237 "BasicBlock 1, pred: 0, succ: 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000238 " 3: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000239 "BasicBlock 2, pred: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000240 " 4: Exit\n";
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000241
242 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
243 Instruction::CONST_4 | 0 | 0,
244 Instruction::RETURN_VOID);
245
246 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000247}
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000248} // namespace art