blob: 6ef386b4a539d367856786f7c2875f2be2705f08 [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
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070017#include "pretty_printer.h"
18
Mathieu Chartierb666f482015-02-18 14:33:14 -080019#include "base/arena_allocator.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000020#include "builder.h"
David Sehr9e734c72018-01-04 17:56:19 -080021#include "dex/dex_file.h"
22#include "dex/dex_instruction.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000023#include "nodes.h"
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000024#include "optimizing_unit_test.h"
Nicolas Geoffray818f2102014-02-18 16:43:35 +000025
26#include "gtest/gtest.h"
27
28namespace art {
29
Vladimir Markoca6fff82017-10-03 14:49:14 +010030class PrettyPrinterTest : public OptimizingUnitTest {
31 protected:
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -080032 void TestCode(const std::vector<uint16_t>& data, const char* expected);
Vladimir Markoca6fff82017-10-03 14:49:14 +010033};
34
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -080035void PrettyPrinterTest::TestCode(const std::vector<uint16_t>& data, const char* expected) {
Vladimir Markoca6fff82017-10-03 14:49:14 +010036 HGraph* graph = CreateCFG(data);
Nicolas Geoffray818f2102014-02-18 16:43:35 +000037 StringPrettyPrinter printer(graph);
38 printer.VisitInsertionOrder();
39 ASSERT_STREQ(expected, printer.str().c_str());
Nicolas Geoffray818f2102014-02-18 16:43:35 +000040}
41
David Brazdilbadd8262016-02-02 16:28:56 +000042TEST_F(PrettyPrinterTest, ReturnVoid) {
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -080043 const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000044 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000045
46 const char* expected =
47 "BasicBlock 0, succ: 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000048 " 0: SuspendCheck\n"
49 " 1: Goto 1\n"
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000050 "BasicBlock 1, pred: 0, succ: 2\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000051 " 2: ReturnVoid\n"
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000052 "BasicBlock 2, pred: 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +000053 " 3: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000054
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000055 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000056}
57
David Brazdilbadd8262016-02-02 16:28:56 +000058TEST_F(PrettyPrinterTest, CFG1) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000059 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +000060 "BasicBlock 0, succ: 1\n"
61 " 0: SuspendCheck\n"
62 " 1: Goto 1\n"
63 "BasicBlock 1, pred: 0, succ: 2\n"
64 " 2: Goto 2\n"
65 "BasicBlock 2, pred: 1, succ: 3\n"
66 " 3: ReturnVoid\n"
67 "BasicBlock 3, pred: 2\n"
68 " 4: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000069
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -080070 const std::vector<uint16_t> data =
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000071 ZERO_REGISTER_CODE_ITEM(
72 Instruction::GOTO | 0x100,
73 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000074
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000075 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000076}
77
David Brazdilbadd8262016-02-02 16:28:56 +000078TEST_F(PrettyPrinterTest, CFG2) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000079 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +000080 "BasicBlock 0, succ: 1\n"
81 " 0: SuspendCheck\n"
82 " 1: Goto 1\n"
83 "BasicBlock 1, pred: 0, succ: 2\n"
84 " 2: Goto 2\n"
85 "BasicBlock 2, pred: 1, succ: 3\n"
86 " 3: Goto 3\n"
87 "BasicBlock 3, pred: 2, succ: 4\n"
88 " 4: ReturnVoid\n"
89 "BasicBlock 4, pred: 3\n"
90 " 5: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000091
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -080092 const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000093 Instruction::GOTO | 0x100,
94 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000095 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000096
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +000097 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +000098}
99
David Brazdilbadd8262016-02-02 16:28:56 +0000100TEST_F(PrettyPrinterTest, CFG3) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000101 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000102 "BasicBlock 0, succ: 1\n"
103 " 0: SuspendCheck\n"
104 " 1: Goto 1\n"
105 "BasicBlock 1, pred: 0, succ: 3\n"
106 " 2: Goto 3\n"
107 "BasicBlock 2, pred: 3, succ: 4\n"
David Brazdildee58d62016-04-07 09:54:26 +0000108 " 4: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000109 "BasicBlock 3, pred: 1, succ: 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000110 " 3: Goto 2\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000111 "BasicBlock 4, pred: 2\n"
112 " 5: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000113
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800114 const std::vector<uint16_t> data1 = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000115 Instruction::GOTO | 0x200,
116 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000117 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000118
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000119 TestCode(data1, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000120
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800121 const std::vector<uint16_t> data2 = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000122 Instruction::GOTO_16, 3,
123 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000124 Instruction::GOTO_16, 0xFFFF);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000125
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000126 TestCode(data2, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000127
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800128 const std::vector<uint16_t> data3 = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000129 Instruction::GOTO_32, 4, 0,
130 Instruction::RETURN_VOID,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000131 Instruction::GOTO_32, 0xFFFF, 0xFFFF);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000132
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000133 TestCode(data3, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000134}
135
David Brazdilbadd8262016-02-02 16:28:56 +0000136TEST_F(PrettyPrinterTest, CFG4) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000137 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000138 "BasicBlock 0, succ: 3\n"
David Brazdil60328912016-04-04 17:47:42 +0000139 " 1: SuspendCheck\n"
David Brazdildee58d62016-04-07 09:54:26 +0000140 " 2: Goto 3\n"
141 "BasicBlock 1, pred: 3, 1, succ: 1\n"
142 " 3: SuspendCheck\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000143 " 4: Goto 1\n"
144 "BasicBlock 3, pred: 0, succ: 1\n"
145 " 0: Goto 1\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000146
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800147 const std::vector<uint16_t> data1 = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000148 Instruction::NOP,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000149 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000150
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000151 TestCode(data1, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000152
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800153 const std::vector<uint16_t> data2 = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000154 Instruction::GOTO_32, 0, 0);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000155
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000156 TestCode(data2, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000157}
158
David Brazdilbadd8262016-02-02 16:28:56 +0000159TEST_F(PrettyPrinterTest, CFG5) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000160 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000161 "BasicBlock 0, succ: 1\n"
162 " 0: SuspendCheck\n"
163 " 1: Goto 1\n"
164 "BasicBlock 1, pred: 0, succ: 3\n"
165 " 2: ReturnVoid\n"
166 "BasicBlock 3, pred: 1\n"
167 " 3: Exit\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000168
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800169 const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000170 Instruction::RETURN_VOID,
171 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000172 Instruction::GOTO | 0xFE00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000173
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000174 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000175}
176
David Brazdilbadd8262016-02-02 16:28:56 +0000177TEST_F(PrettyPrinterTest, CFG6) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000178 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000179 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000180 " 3: IntConstant [4, 4]\n"
181 " 1: SuspendCheck\n"
182 " 2: Goto 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000183 "BasicBlock 1, pred: 0, succ: 5, 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000184 " 4: Equal(3, 3) [5]\n"
185 " 5: If(4)\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000186 "BasicBlock 2, pred: 1, succ: 3\n"
David Brazdildee58d62016-04-07 09:54:26 +0000187 " 6: Goto 3\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000188 "BasicBlock 3, pred: 5, 2, succ: 4\n"
David Brazdildee58d62016-04-07 09:54:26 +0000189 " 7: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000190 "BasicBlock 4, pred: 3\n"
David Brazdildee58d62016-04-07 09:54:26 +0000191 " 8: Exit\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000192 "BasicBlock 5, pred: 1, succ: 3\n"
193 " 0: Goto 3\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000194
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800195 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000196 Instruction::CONST_4 | 0 | 0,
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000197 Instruction::IF_EQ, 3,
198 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000199 Instruction::RETURN_VOID);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000200
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000201 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000202}
203
David Brazdilbadd8262016-02-02 16:28:56 +0000204TEST_F(PrettyPrinterTest, CFG7) {
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000205 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000206 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000207 " 4: IntConstant [5, 5]\n"
David Brazdil60328912016-04-04 17:47:42 +0000208 " 2: SuspendCheck\n"
David Brazdildee58d62016-04-07 09:54:26 +0000209 " 3: Goto 1\n"
210 "BasicBlock 1, pred: 0, succ: 5, 6\n"
211 " 5: Equal(4, 4) [6]\n"
212 " 6: If(5)\n"
213 "BasicBlock 2, pred: 6, 3, succ: 3\n"
214 " 11: Goto 3\n"
215 "BasicBlock 3, pred: 5, 2, succ: 2\n"
216 " 8: SuspendCheck\n"
217 " 9: Goto 2\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000218 "BasicBlock 5, pred: 1, succ: 3\n"
219 " 0: Goto 3\n"
220 "BasicBlock 6, pred: 1, succ: 2\n"
221 " 1: Goto 2\n";
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000222
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800223 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000224 Instruction::CONST_4 | 0 | 0,
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000225 Instruction::IF_EQ, 3,
226 Instruction::GOTO | 0x100,
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000227 Instruction::GOTO | 0xFF00);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000228
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000229 TestCode(data, expected);
230}
231
David Brazdilbadd8262016-02-02 16:28:56 +0000232TEST_F(PrettyPrinterTest, IntConstant) {
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000233 const char* expected =
David Brazdil86ea7ee2016-02-16 09:26:07 +0000234 "BasicBlock 0, succ: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000235 " 2: IntConstant\n"
236 " 0: SuspendCheck\n"
237 " 1: Goto 1\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000238 "BasicBlock 1, pred: 0, succ: 2\n"
David Brazdildee58d62016-04-07 09:54:26 +0000239 " 3: ReturnVoid\n"
David Brazdil86ea7ee2016-02-16 09:26:07 +0000240 "BasicBlock 2, pred: 1\n"
David Brazdildee58d62016-04-07 09:54:26 +0000241 " 4: Exit\n";
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000242
Mathieu Chartierfa3db3d2018-01-12 14:42:18 -0800243 const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
Nicolas Geoffray3ff386a2014-03-04 14:46:47 +0000244 Instruction::CONST_4 | 0 | 0,
245 Instruction::RETURN_VOID);
246
247 TestCode(data, expected);
Nicolas Geoffraybe9a92a2014-02-25 14:22:56 +0000248}
Nicolas Geoffray818f2102014-02-18 16:43:35 +0000249} // namespace art