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