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 28namespace art { 29 30static 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 39class PrettyPrinterTest : public CommonCompilerTest {}; 40 41TEST_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 57TEST_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 77TEST_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 99TEST_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 135TEST_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 158TEST_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 176TEST_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 203TEST_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 231TEST_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