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/stringprintf.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 #include "utils/arena_allocator.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   HGraphBuilder builder(&allocator);
     34   const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
     35   HGraph* graph = builder.BuildGraph(*item);
     36   ASSERT_NE(graph, nullptr);
     37   StringPrettyPrinter printer(graph);
     38   printer.VisitInsertionOrder();
     39   ASSERT_STREQ(expected, printer.str().c_str());
     40 }
     41 
     42 TEST(PrettyPrinterTest, ReturnVoid) {
     43   const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
     44       Instruction::RETURN_VOID);
     45 
     46   const char* expected =
     47       "BasicBlock 0, succ: 1\n"
     48       "  2: Goto 1\n"
     49       "BasicBlock 1, pred: 0, succ: 2\n"
     50       "  0: ReturnVoid\n"
     51       "BasicBlock 2, pred: 1\n"
     52       "  1: Exit\n";
     53 
     54   TestCode(data, expected);
     55 }
     56 
     57 TEST(PrettyPrinterTest, CFG1) {
     58   const char* expected =
     59     "BasicBlock 0, succ: 1\n"
     60     "  3: Goto 1\n"
     61     "BasicBlock 1, pred: 0, succ: 2\n"
     62     "  0: Goto 2\n"
     63     "BasicBlock 2, pred: 1, succ: 3\n"
     64     "  1: ReturnVoid\n"
     65     "BasicBlock 3, pred: 2\n"
     66     "  2: 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(PrettyPrinterTest, CFG2) {
     77   const char* expected =
     78     "BasicBlock 0, succ: 1\n"
     79     "  4: Goto 1\n"
     80     "BasicBlock 1, pred: 0, succ: 2\n"
     81     "  0: Goto 2\n"
     82     "BasicBlock 2, pred: 1, succ: 3\n"
     83     "  1: Goto 3\n"
     84     "BasicBlock 3, pred: 2, succ: 4\n"
     85     "  2: ReturnVoid\n"
     86     "BasicBlock 4, pred: 3\n"
     87     "  3: Exit\n";
     88 
     89   const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
     90     Instruction::GOTO | 0x100,
     91     Instruction::GOTO | 0x100,
     92     Instruction::RETURN_VOID);
     93 
     94   TestCode(data, expected);
     95 }
     96 
     97 TEST(PrettyPrinterTest, CFG3) {
     98   const char* expected =
     99     "BasicBlock 0, succ: 1\n"
    100     "  4: Goto 1\n"
    101     "BasicBlock 1, pred: 0, succ: 3\n"
    102     "  0: Goto 3\n"
    103     "BasicBlock 2, pred: 3, succ: 4\n"
    104     "  1: ReturnVoid\n"
    105     "BasicBlock 3, pred: 1, succ: 2\n"
    106     "  2: Goto 2\n"
    107     "BasicBlock 4, pred: 2\n"
    108     "  3: Exit\n";
    109 
    110   const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
    111     Instruction::GOTO | 0x200,
    112     Instruction::RETURN_VOID,
    113     Instruction::GOTO | 0xFF00);
    114 
    115   TestCode(data1, expected);
    116 
    117   const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
    118     Instruction::GOTO_16, 3,
    119     Instruction::RETURN_VOID,
    120     Instruction::GOTO_16, 0xFFFF);
    121 
    122   TestCode(data2, expected);
    123 
    124   const uint16_t data3[] = ZERO_REGISTER_CODE_ITEM(
    125     Instruction::GOTO_32, 4, 0,
    126     Instruction::RETURN_VOID,
    127     Instruction::GOTO_32, 0xFFFF, 0xFFFF);
    128 
    129   TestCode(data3, expected);
    130 }
    131 
    132 TEST(PrettyPrinterTest, CFG4) {
    133   const char* expected =
    134     "BasicBlock 0, succ: 1\n"
    135     "  2: Goto 1\n"
    136     "BasicBlock 1, pred: 0, 1, succ: 1\n"
    137     "  0: Goto 1\n"
    138     "BasicBlock 2\n"
    139     "  1: Exit\n";
    140 
    141   const uint16_t data1[] = ZERO_REGISTER_CODE_ITEM(
    142     Instruction::NOP,
    143     Instruction::GOTO | 0xFF00);
    144 
    145   TestCode(data1, expected);
    146 
    147   const uint16_t data2[] = ZERO_REGISTER_CODE_ITEM(
    148     Instruction::GOTO_32, 0, 0);
    149 
    150   TestCode(data2, expected);
    151 }
    152 
    153 TEST(PrettyPrinterTest, CFG5) {
    154   const char* expected =
    155     "BasicBlock 0, succ: 1\n"
    156     "  3: Goto 1\n"
    157     "BasicBlock 1, pred: 0, 2, succ: 3\n"
    158     "  0: ReturnVoid\n"
    159     "BasicBlock 2, succ: 1\n"
    160     "  1: Goto 1\n"
    161     "BasicBlock 3, pred: 1\n"
    162     "  2: Exit\n";
    163 
    164   const uint16_t data[] = ZERO_REGISTER_CODE_ITEM(
    165     Instruction::RETURN_VOID,
    166     Instruction::GOTO | 0x100,
    167     Instruction::GOTO | 0xFE00);
    168 
    169   TestCode(data, expected);
    170 }
    171 
    172 TEST(PrettyPrinterTest, CFG6) {
    173   const char* expected =
    174     "BasicBlock 0, succ: 1\n"
    175     "  0: Local [4, 3, 2]\n"
    176     "  1: IntConstant [2]\n"
    177     "  10: Goto 1\n"
    178     "BasicBlock 1, pred: 0, succ: 3, 2\n"
    179     "  2: StoreLocal(0, 1)\n"
    180     "  3: LoadLocal(0) [5]\n"
    181     "  4: LoadLocal(0) [5]\n"
    182     "  5: Equal(3, 4) [6]\n"
    183     "  6: If(5)\n"
    184     "BasicBlock 2, pred: 1, succ: 3\n"
    185     "  7: Goto 3\n"
    186     "BasicBlock 3, pred: 1, 2, succ: 4\n"
    187     "  8: ReturnVoid\n"
    188     "BasicBlock 4, pred: 3\n"
    189     "  9: Exit\n";
    190 
    191   const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    192     Instruction::CONST_4 | 0 | 0,
    193     Instruction::IF_EQ, 3,
    194     Instruction::GOTO | 0x100,
    195     Instruction::RETURN_VOID);
    196 
    197   TestCode(data, expected);
    198 }
    199 
    200 TEST(PrettyPrinterTest, CFG7) {
    201   const char* expected =
    202     "BasicBlock 0, succ: 1\n"
    203     "  0: Local [4, 3, 2]\n"
    204     "  1: IntConstant [2]\n"
    205     "  10: Goto 1\n"
    206     "BasicBlock 1, pred: 0, succ: 3, 2\n"
    207     "  2: StoreLocal(0, 1)\n"
    208     "  3: LoadLocal(0) [5]\n"
    209     "  4: LoadLocal(0) [5]\n"
    210     "  5: Equal(3, 4) [6]\n"
    211     "  6: If(5)\n"
    212     "BasicBlock 2, pred: 1, 3, succ: 3\n"
    213     "  7: Goto 3\n"
    214     "BasicBlock 3, pred: 1, 2, succ: 2\n"
    215     "  8: Goto 2\n"
    216     "BasicBlock 4\n"
    217     "  9: Exit\n";
    218 
    219   const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    220     Instruction::CONST_4 | 0 | 0,
    221     Instruction::IF_EQ, 3,
    222     Instruction::GOTO | 0x100,
    223     Instruction::GOTO | 0xFF00);
    224 
    225   TestCode(data, expected);
    226 }
    227 
    228 TEST(PrettyPrinterTest, IntConstant) {
    229   const char* expected =
    230     "BasicBlock 0, succ: 1\n"
    231     "  0: Local [2]\n"
    232     "  1: IntConstant [2]\n"
    233     "  5: Goto 1\n"
    234     "BasicBlock 1, pred: 0, succ: 2\n"
    235     "  2: StoreLocal(0, 1)\n"
    236     "  3: ReturnVoid\n"
    237     "BasicBlock 2, pred: 1\n"
    238     "  4: Exit\n";
    239 
    240   const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
    241     Instruction::CONST_4 | 0 | 0,
    242     Instruction::RETURN_VOID);
    243 
    244   TestCode(data, expected);
    245 }
    246 }  // namespace art
    247