blob: 1af94f34451f7c6beb7f7a28f34501b1fee1b07e [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 "builder.h"
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000019#include "dex_file.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000020#include "dex_instruction.h"
21#include "nodes.h"
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000022#include "optimizing_unit_test.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000023#include "pretty_printer.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000024
25#include "gtest/gtest.h"
26
27namespace art {
28
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000029static void TestCode(const uint16_t* data, const char* expected) {
Nicolas Geoffray818f2102014-02-18 16:43:35 +000030 ArenaPool pool;
31 ArenaAllocator allocator(&pool);
David Brazdilbadd8262016-02-02 16:28:56 +000032 HGraph* graph = CreateCFG(&allocator, data);
Nicolas Geoffray818f2102014-02-18 16:43:35 +000033 StringPrettyPrinter printer(graph);
34 printer.VisitInsertionOrder();
35 ASSERT_STREQ(expected, printer.str().c_str());
Nicolas Geoffray818f2102014-02-18 16:43:35 +000036}
37
David Brazdilbadd8262016-02-02 16:28:56 +000038class PrettyPrinterTest : public CommonCompilerTest {};
39
40TEST_F(PrettyPrinterTest, ReturnVoid) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000041 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
42 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000043
44 const char* expected =
45 "BasicBlock 0, succ: 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000046 " 0: SuspendCheck\n"
47 " 1: Goto 1\n"
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000048 "BasicBlock 1, pred: 0, succ: 2\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000049 " 2: ReturnVoid\n"
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000050 "BasicBlock 2, pred: 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000051 " 3: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000052
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000053 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000054}
55
David Brazdilbadd8262016-02-02 16:28:56 +000056TEST_F(PrettyPrinterTest, CFG1) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000057 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +000058 "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";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000067
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000068 const uint16_t data[] =
69 ZERO_REGISTER_CODE_ITEM(
70 Instruction::GOTO | 0x100,
71 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000072
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000073 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000074}
75
David Brazdilbadd8262016-02-02 16:28:56 +000076TEST_F(PrettyPrinterTest, CFG2) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000077 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +000078 "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";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000089
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000090 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000091 Instruction::GOTO | 0x100,
92 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000093 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000094
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000095 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000096}
97
David Brazdilbadd8262016-02-02 16:28:56 +000098TEST_F(PrettyPrinterTest, CFG3) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000099 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000100 "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"
David Brazdildee58d62016-04-07 09:54:26 +0000106 " 4: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000107 "BasicBlock 3, pred: 1, succ: 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000108 " 3: Goto 2\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000109 "BasicBlock 4, pred: 2\n"
110 " 5: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000111
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000112 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000113 Instruction::GOTO | 0x200,
114 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000115 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000116
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000117 TestCode(data1, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000118
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000119 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000120 Instruction::GOTO_16, 3,
121 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000122 Instruction::GOTO_16, 0xFFFF);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000123
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000124 TestCode(data2, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000125
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000126 const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000127 Instruction::GOTO_32, 4, 0,
128 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000129 Instruction::GOTO_32, 0xFFFF, 0xFFFF);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000130
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000131 TestCode(data3, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000132}
133
David Brazdilbadd8262016-02-02 16:28:56 +0000134TEST_F(PrettyPrinterTest, CFG4) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000135 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000136 "BasicBlock 0, succ: 3\n"
David Brazdil60328912016-04-04 17:47:42 +0000137 " 1: SuspendCheck\n"
David Brazdildee58d62016-04-07 09:54:26 +0000138 " 2: Goto 3\n"
139 "BasicBlock 1, pred: 3, 1, succ: 1\n"
140 " 3: SuspendCheck\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000141 " 4: Goto 1\n"
142 "BasicBlock 3, pred: 0, succ: 1\n"
143 " 0: Goto 1\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000144
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000145 const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000146 Instruction::NOP,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000147 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000148
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000149 TestCode(data1, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000150
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000151 const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
152 Instruction::GOTO_32, 0, 0);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000153
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000154 TestCode(data2, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000155}
156
David Brazdilbadd8262016-02-02 16:28:56 +0000157TEST_F(PrettyPrinterTest, CFG5) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000158 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000159 "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";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000166
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000167 const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000168 Instruction::RETURN_VOID,
169 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000170 Instruction::GOTO | 0xFE00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000171
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000172 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000173}
174
David Brazdilbadd8262016-02-02 16:28:56 +0000175TEST_F(PrettyPrinterTest, CFG6) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000176 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000177 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000178 " 3: IntConstant [4, 4]\n"
179 " 1: SuspendCheck\n"
180 " 2: Goto 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000181 "BasicBlock 1, pred: 0, succ: 5, 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000182 " 4: Equal(3, 3) [5]\n"
183 " 5: If(4)\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000184 "BasicBlock 2, pred: 1, succ: 3\n"
David Brazdildee58d62016-04-07 09:54:26 +0000185 " 6: Goto 3\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000186 "BasicBlock 3, pred: 5, 2, succ: 4\n"
David Brazdildee58d62016-04-07 09:54:26 +0000187 " 7: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000188 "BasicBlock 4, pred: 3\n"
David Brazdildee58d62016-04-07 09:54:26 +0000189 " 8: Exit\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000190 "BasicBlock 5, pred: 1, succ: 3\n"
191 " 0: Goto 3\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000192
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000193 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
194 Instruction::CONST_4 | 0 | 0,
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000195 Instruction::IF_EQ, 3,
196 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000197 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000198
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000199 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000200}
201
David Brazdilbadd8262016-02-02 16:28:56 +0000202TEST_F(PrettyPrinterTest, CFG7) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000203 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000204 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000205 " 4: IntConstant [5, 5]\n"
David Brazdil60328912016-04-04 17:47:42 +0000206 " 2: SuspendCheck\n"
David Brazdildee58d62016-04-07 09:54:26 +0000207 " 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"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000216 "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";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000220
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000221 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
222 Instruction::CONST_4 | 0 | 0,
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000223 Instruction::IF_EQ, 3,
224 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000225 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000226
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000227 TestCode(data, expected);
228}
229
David Brazdilbadd8262016-02-02 16:28:56 +0000230TEST_F(PrettyPrinterTest, IntConstant) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000231 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000232 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000233 " 2: IntConstant\n"
234 " 0: SuspendCheck\n"
235 " 1: Goto 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000236 "BasicBlock 1, pred: 0, succ: 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000237 " 3: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000238 "BasicBlock 2, pred: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000239 " 4: Exit\n";
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000240
241 const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
242 Instruction::CONST_4 | 0 | 0,
243 Instruction::RETURN_VOID);
244
245 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000246}
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000247} // namespace art