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