Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2015 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 public class Main {
     18 
     19   public static void assertIntEquals(int expected, int result) {
     20     if (expected != result) {
     21       throw new Error("Expected: " + expected + ", found: " + result);
     22     }
     23   }
     24 
     25   public static boolean inlineTrue() {
     26     return true;
     27   }
     28 
     29   public static boolean inlineFalse() {
     30     return false;
     31   }
     32 
     33   /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (before)
     34   /// CHECK-DAG:     <<ArgX:i\d+>>    ParameterValue
     35   /// CHECK-DAG:     <<ArgY:i\d+>>    ParameterValue
     36   /// CHECK-DAG:                      If
     37   /// CHECK-DAG:     <<Add:i\d+>>     Add [<<ArgX>>,<<ArgY>>]
     38   /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<ArgX>>,<<ArgY>>]
     39   /// CHECK-DAG:     <<Phi:i\d+>>     Phi [<<Add>>,<<Sub>>]
     40   /// CHECK-DAG:                      Return [<<Phi>>]
     41 
     42   /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
     43   /// CHECK-DAG:     <<ArgX:i\d+>>    ParameterValue
     44   /// CHECK-DAG:     <<ArgY:i\d+>>    ParameterValue
     45   /// CHECK-DAG:     <<Add:i\d+>>     Add [<<ArgX>>,<<ArgY>>]
     46   /// CHECK-DAG:                      Return [<<Add>>]
     47 
     48   /// CHECK-START: int Main.testTrueBranch(int, int) dead_code_elimination_final (after)
     49   /// CHECK-NOT:                      If
     50   /// CHECK-NOT:                      Sub
     51   /// CHECK-NOT:                      Phi
     52 
     53   public static int testTrueBranch(int x, int y) {
     54     int z;
     55     if (inlineTrue()) {
     56       z = x + y;
     57     } else {
     58       z = x - y;
     59       // Prevent HSelect simplification by having a branch with multiple instructions.
     60       System.nanoTime();
     61     }
     62     return z;
     63   }
     64 
     65   /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (before)
     66   /// CHECK-DAG:     <<ArgX:i\d+>>    ParameterValue
     67   /// CHECK-DAG:     <<ArgY:i\d+>>    ParameterValue
     68   /// CHECK-DAG:                      If
     69   /// CHECK-DAG:     <<Add:i\d+>>     Add [<<ArgX>>,<<ArgY>>]
     70   /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<ArgX>>,<<ArgY>>]
     71   /// CHECK-DAG:     <<Phi:i\d+>>     Phi [<<Add>>,<<Sub>>]
     72   /// CHECK-DAG:                      Return [<<Phi>>]
     73 
     74   /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
     75   /// CHECK-DAG:     <<ArgX:i\d+>>    ParameterValue
     76   /// CHECK-DAG:     <<ArgY:i\d+>>    ParameterValue
     77   /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<ArgX>>,<<ArgY>>]
     78   /// CHECK-DAG:                      Return [<<Sub>>]
     79 
     80   /// CHECK-START: int Main.testFalseBranch(int, int) dead_code_elimination_final (after)
     81   /// CHECK-NOT:                      If
     82   /// CHECK-NOT:                      Add
     83   /// CHECK-NOT:                      Phi
     84 
     85   public static int testFalseBranch(int x, int y) {
     86     int z;
     87     if (inlineFalse()) {
     88       z = x + y;
     89     } else {
     90       z = x - y;
     91       // Prevent HSelect simplification by having a branch with multiple instructions.
     92       System.nanoTime();
     93     }
     94     return z;
     95   }
     96 
     97   /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (before)
     98   /// CHECK:                          Mul
     99 
    100   /// CHECK-START: int Main.testRemoveLoop(int) dead_code_elimination_final (after)
    101   /// CHECK-NOT:                      Mul
    102 
    103   public static int testRemoveLoop(int x) {
    104     if (inlineFalse()) {
    105       for (int i = 0; i < x; ++i) {
    106         x *= x;
    107       }
    108     }
    109     return x;
    110   }
    111 
    112   /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (before)
    113   /// CHECK-DAG:                      Return
    114   /// CHECK-DAG:                      Exit
    115 
    116   /// CHECK-START: int Main.testInfiniteLoop(int) dead_code_elimination_final (after)
    117   /// CHECK-NOT:                      Return
    118   /// CHECK-NOT:                      Exit
    119 
    120   public static int testInfiniteLoop(int x) {
    121     while (inlineTrue()) {
    122       x++;
    123     }
    124     return x;
    125   }
    126 
    127   /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (before)
    128   /// CHECK-DAG:                      If
    129   /// CHECK-DAG:                      Add
    130 
    131   /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
    132   /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
    133   /// CHECK-DAG:                      Return [<<Arg>>]
    134 
    135   /// CHECK-START: int Main.testDeadLoop(int) dead_code_elimination_final (after)
    136   /// CHECK-NOT:                      If
    137   /// CHECK-NOT:                      Add
    138 
    139   public static int testDeadLoop(int x) {
    140     while (inlineFalse()) {
    141       x++;
    142     }
    143     return x;
    144   }
    145 
    146   /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (before)
    147   /// CHECK-DAG:                      If
    148   /// CHECK-DAG:                      If
    149   /// CHECK-DAG:                      Add
    150 
    151   /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
    152   /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
    153   /// CHECK-DAG:                      Return [<<Arg>>]
    154 
    155   /// CHECK-START: int Main.testUpdateLoopInformation(int) dead_code_elimination_final (after)
    156   /// CHECK-NOT:                      If
    157   /// CHECK-NOT:                      Add
    158 
    159   public static int testUpdateLoopInformation(int x) {
    160     // Use of Or in the condition generates a dead loop where not all of its
    161     // blocks are removed. This forces DCE to update their loop information.
    162     while (inlineFalse() || !inlineTrue()) {
    163       x++;
    164     }
    165     return x;
    166   }
    167 
    168   /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (before)
    169   /// CHECK:                          SuspendCheck
    170   /// CHECK:                          SuspendCheck
    171   /// CHECK:                          SuspendCheck
    172   /// CHECK-NOT:                      SuspendCheck
    173 
    174   /// CHECK-START: int Main.testRemoveSuspendCheck(int, int) dead_code_elimination_final (after)
    175   /// CHECK:                          SuspendCheck
    176   /// CHECK:                          SuspendCheck
    177   /// CHECK-NOT:                      SuspendCheck
    178 
    179   public static int testRemoveSuspendCheck(int x, int y) {
    180     // Inner loop will leave behind the header with its SuspendCheck. DCE must
    181     // remove it, otherwise the outer loop would end up with two.
    182     while (y > 0) {
    183       while (inlineFalse() || !inlineTrue()) {
    184         x++;
    185       }
    186       y--;
    187     }
    188     return x;
    189   }
    190 
    191   public static void main(String[] args) {
    192     assertIntEquals(7, testTrueBranch(4, 3));
    193     assertIntEquals(1, testFalseBranch(4, 3));
    194     assertIntEquals(42, testRemoveLoop(42));
    195     assertIntEquals(23, testUpdateLoopInformation(23));
    196     assertIntEquals(12, testRemoveSuspendCheck(12, 5));
    197   }
    198 }
    199