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 "pretty_printer.h"
     18 
     19 #include "base/arena_allocator.h"
     20 #include "builder.h"
     21 #include "dex/dex_file.h"
     22 #include "dex/dex_instruction.h"
     23 #include "nodes.h"
     24 #include "optimizing_unit_test.h"
     25 
     26 #include "gtest/gtest.h"
     27 
     28 namespace art {
     29 
     30 class PrettyPrinterTest : public OptimizingUnitTest {
     31  protected:
     32   void TestCode(const std::vector<uint16_t>& data, const char* expected);
     33 };
     34 
     35 void PrettyPrinterTest::TestCode(const std::vector<uint16_t>& data, const char* expected) {
     36   HGraph* graph = CreateCFG(data);
     37   StringPrettyPrinter printer(graph);
     38   printer.VisitInsertionOrder();
     39   ASSERT_STREQ(expected, printer.str().c_str());
     40 }
     41 
     42 TEST_F(PrettyPrinterTest, ReturnVoid) {
     43   const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
     44       Instruction::RETURN_VOID);
     45 
     46   const char* expected =
     47       "BasicBlock 0, succ: 1\n"
     48       "  0: SuspendCheck\n"
     49       "  1: Goto 1\n"
     50       "BasicBlock 1, pred: 0, succ: 2\n"
     51       "  2: ReturnVoid\n"
     52       "BasicBlock 2, pred: 1\n"
     53       "  3: Exit\n";
     54 
     55   TestCode(data, expected);
     56 }
     57 
     58 TEST_F(PrettyPrinterTest, CFG1) {
     59   const char* expected =
     60       "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";
     69 
     70   const std::vector<uint16_t> data =
     71     ZERO_REGISTER_CODE_ITEM(
     72       Instruction::GOTO | 0x100,
     73       Instruction::RETURN_VOID);
     74 
     75   TestCode(data, expected);
     76 }
     77 
     78 TEST_F(PrettyPrinterTest, CFG2) {
     79   const char* expected =
     80       "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";
     91 
     92   const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
     93     Instruction::GOTO | 0x100,
     94     Instruction::GOTO | 0x100,
     95     Instruction::RETURN_VOID);
     96 
     97   TestCode(data, expected);
     98 }
     99 
    100 TEST_F(PrettyPrinterTest, CFG3) {
    101   const char* expected =
    102       "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"
    108       "  4: ReturnVoid\n"
    109       "BasicBlock 3, pred: 1, succ: 2\n"
    110       "  3: Goto 2\n"
    111       "BasicBlock 4, pred: 2\n"
    112       "  5: Exit\n";
    113 
    114   const std::vector<uint16_t> data1 = ZERO_REGISTER_CODE_ITEM(
    115     Instruction::GOTO | 0x200,
    116     Instruction::RETURN_VOID,
    117     Instruction::GOTO | 0xFF00);
    118 
    119   TestCode(data1, expected);
    120 
    121   const std::vector<uint16_t> data2 = ZERO_REGISTER_CODE_ITEM(
    122     Instruction::GOTO_16, 3,
    123     Instruction::RETURN_VOID,
    124     Instruction::GOTO_16, 0xFFFF);
    125 
    126   TestCode(data2, expected);
    127 
    128   const std::vector<uint16_t> data3 = ZERO_REGISTER_CODE_ITEM(
    129     Instruction::GOTO_32, 4, 0,
    130     Instruction::RETURN_VOID,
    131     Instruction::GOTO_32, 0xFFFF, 0xFFFF);
    132 
    133   TestCode(data3, expected);
    134 }
    135 
    136 TEST_F(PrettyPrinterTest, CFG4) {
    137   const char* expected =
    138       "BasicBlock 0, succ: 3\n"
    139       "  1: SuspendCheck\n"
    140       "  2: Goto 3\n"
    141       "BasicBlock 1, pred: 3, 1, succ: 1\n"
    142       "  3: SuspendCheck\n"
    143       "  4: Goto 1\n"
    144       "BasicBlock 3, pred: 0, succ: 1\n"
    145       "  0: Goto 1\n";
    146 
    147   const std::vector<uint16_t> data1 = ZERO_REGISTER_CODE_ITEM(
    148     Instruction::NOP,
    149     Instruction::GOTO | 0xFF00);
    150 
    151   TestCode(data1, expected);
    152 
    153   const std::vector<uint16_t> data2 = ZERO_REGISTER_CODE_ITEM(
    154     Instruction::GOTO_32, 0, 0);
    155 
    156   TestCode(data2, expected);
    157 }
    158 
    159 TEST_F(PrettyPrinterTest, CFG5) {
    160   const char* expected =
    161       "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";
    168 
    169   const std::vector<uint16_t> data = ZERO_REGISTER_CODE_ITEM(
    170     Instruction::RETURN_VOID,
    171     Instruction::GOTO | 0x100,
    172     Instruction::GOTO | 0xFE00);
    173 
    174   TestCode(data, expected);
    175 }
    176 
    177 TEST_F(PrettyPrinterTest, CFG6) {
    178   const char* expected =
    179       "BasicBlock 0, succ: 1\n"
    180       "  3: IntConstant [4, 4]\n"
    181       "  1: SuspendCheck\n"
    182       "  2: Goto 1\n"
    183       "BasicBlock 1, pred: 0, succ: 5, 2\n"
    184       "  4: Equal(3, 3) [5]\n"
    185       "  5: If(4)\n"
    186       "BasicBlock 2, pred: 1, succ: 3\n"
    187       "  6: Goto 3\n"
    188       "BasicBlock 3, pred: 5, 2, succ: 4\n"
    189       "  7: ReturnVoid\n"
    190       "BasicBlock 4, pred: 3\n"
    191       "  8: Exit\n"
    192       "BasicBlock 5, pred: 1, succ: 3\n"
    193       "  0: Goto 3\n";
    194 
    195   const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
    196     Instruction::CONST_4 | 0 | 0,
    197     Instruction::IF_EQ, 3,
    198     Instruction::GOTO | 0x100,
    199     Instruction::RETURN_VOID);
    200 
    201   TestCode(data, expected);
    202 }
    203 
    204 TEST_F(PrettyPrinterTest, CFG7) {
    205   const char* expected =
    206       "BasicBlock 0, succ: 1\n"
    207       "  4: IntConstant [5, 5]\n"
    208       "  2: SuspendCheck\n"
    209       "  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"
    218       "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";
    222 
    223   const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
    224     Instruction::CONST_4 | 0 | 0,
    225     Instruction::IF_EQ, 3,
    226     Instruction::GOTO | 0x100,
    227     Instruction::GOTO | 0xFF00);
    228 
    229   TestCode(data, expected);
    230 }
    231 
    232 TEST_F(PrettyPrinterTest, IntConstant) {
    233   const char* expected =
    234       "BasicBlock 0, succ: 1\n"
    235       "  2: IntConstant\n"
    236       "  0: SuspendCheck\n"
    237       "  1: Goto 1\n"
    238       "BasicBlock 1, pred: 0, succ: 2\n"
    239       "  3: ReturnVoid\n"
    240       "BasicBlock 2, pred: 1\n"
    241       "  4: Exit\n";
    242 
    243   const std::vector<uint16_t> data = ONE_REGISTER_CODE_ITEM(
    244     Instruction::CONST_4 | 0 | 0,
    245     Instruction::RETURN_VOID);
    246 
    247   TestCode(data, expected);
    248 }
    249 }  // namespace art
    250