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 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 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 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 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 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 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 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 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 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 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