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   /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier (before)
     20   /// CHECK:         NullCheck
     21   /// CHECK:         InvokeStaticOrDirect
     22 
     23   /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier (after)
     24   /// CHECK:         NullCheck
     25   /// CHECK:         InvokeStaticOrDirect
     26   public Main keepTest(Main m) {
     27     return m.g();
     28   }
     29 
     30   /// CHECK-START: Main Main.thisTest() builder (after)
     31   /// CHECK-NOT:     NullCheck
     32   /// CHECK:         InvokeStaticOrDirect
     33   public Main thisTest() {
     34     return g();
     35   }
     36 
     37   /// CHECK-START: Main Main.newInstanceRemoveTest() builder (after)
     38   /// CHECK:         NewInstance
     39   /// CHECK:         InvokeStaticOrDirect
     40   /// CHECK:         InvokeStaticOrDirect
     41 
     42   /// CHECK-START: Main Main.newInstanceRemoveTest() builder (after)
     43   /// CHECK-NOT:     NullCheck
     44   public Main newInstanceRemoveTest() {
     45     Main m = new Main();
     46     return m.g();
     47   }
     48 
     49   /// CHECK-START: Main Main.newArrayRemoveTest() builder (after)
     50   /// CHECK:         NewArray
     51   /// CHECK:         ArrayGet
     52 
     53   /// CHECK-START: Main Main.newArrayRemoveTest() builder (after)
     54   /// CHECK-NOT:     NullCheck
     55   public Main newArrayRemoveTest() {
     56     Main[] ms = new Main[1];
     57     return ms[0];
     58   }
     59 
     60   /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier (before)
     61   /// CHECK:         NewInstance
     62   /// CHECK:         NullCheck
     63 
     64   /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier (after)
     65   /// CHECK:         NewInstance
     66   /// CHECK-NOT:     NullCheck
     67   public Main ifRemoveTest(boolean flag) {
     68     Main m = null;
     69     if (flag) {
     70       m = new Main();
     71     } else {
     72       m = new Main(1);
     73     }
     74     return m.g();
     75   }
     76 
     77   /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier (before)
     78   /// CHECK:         NewInstance
     79   /// CHECK:         NullCheck
     80 
     81   /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier (after)
     82   /// CHECK:         NewInstance
     83   /// CHECK:         NullCheck
     84   public Main ifKeepTest(boolean flag) {
     85     Main m = null;
     86     if (flag) {
     87       m = new Main(1);
     88     }
     89     return m.g();
     90   }
     91 
     92   /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier (before)
     93   /// CHECK:         NullCheck
     94 
     95   /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier (after)
     96   /// CHECK-NOT:     NullCheck
     97   public Main forRemoveTest(int count) {
     98     Main a = new Main();
     99     Main m = new Main();
    100     for (int i = 0; i < count; i++) {
    101       if (i % 2 == 0) {
    102         m = a;
    103       }
    104     }
    105     return m.g();
    106   }
    107 
    108   /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier (before)
    109   /// CHECK:         NullCheck
    110 
    111   /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier (after)
    112   /// CHECK:         NullCheck
    113   public Main forKeepTest(int count) {
    114     Main a = new Main();
    115     Main m = new Main();
    116     for (int i = 0; i < count; i++) {
    117       if (i % 2 == 0) {
    118         m = a;
    119       } else {
    120         m = null;
    121       }
    122     }
    123     return m.g();
    124   }
    125 
    126   /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier (before)
    127   /// CHECK:         NullCheck
    128 
    129   /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier (after)
    130   /// CHECK-NOT:     NullCheck
    131   public Main phiFlowRemoveTest(int count) {
    132     Main a = new Main();
    133     Main m = new Main();
    134     for (int i = 0; i < count; i++) {
    135       if (i % 2 == 0) {
    136         m = a;
    137       }
    138     }
    139     Main n = new Main();
    140     for (int i = 0; i < count; i++) {
    141       if (i % 3 == 0) {
    142         n = m;
    143       }
    144     }
    145     return n.g();
    146   }
    147 
    148   /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier (before)
    149   /// CHECK:         NullCheck
    150 
    151   /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier (after)
    152   /// CHECK:         NullCheck
    153   public Main phiFlowKeepTest(int count) {
    154     Main a = new Main();
    155     Main m = new Main();
    156     for (int i = 0; i < count; i++) {
    157       if (i % 2 == 0) {
    158         m = a;
    159       } else {
    160         m = null;
    161       }
    162     }
    163     Main n = new Main();
    164     for (int i = 0; i < count; i++) {
    165       if (i % 3 == 0) {
    166         n = m;
    167       }
    168     }
    169     return n.g();
    170   }
    171 
    172   /// CHECK-START: Main Main.scopeRemoveTest(int, Main) builder (after)
    173   /// CHECK-NOT:     NullCheck
    174   public Main scopeRemoveTest(int count, Main a) {
    175     Main m = null;
    176     for (int i = 0; i < count; i++) {
    177       if (i % 2 == 0) {
    178         m = new Main();
    179         m.g();
    180       } else {
    181         m = a;
    182       }
    183     }
    184     return m;
    185   }
    186 
    187   /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier (before)
    188   /// CHECK:         NullCheck
    189 
    190   /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier (after)
    191   /// CHECK:         NullCheck
    192   public Main scopeKeepTest(int count, Main a) {
    193     Main m = new Main();
    194     for (int i = 0; i < count; i++) {
    195       if (i % 2 == 0) {
    196         m = a;
    197       } else {
    198         m = a;
    199         m.g();
    200       }
    201     }
    202     return m;
    203   }
    204 
    205   /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier (before)
    206   /// CHECK:         NullCheck
    207 
    208   /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier (after)
    209   /// CHECK-NOT:     NullCheck
    210   public Main scopeIfNotNullRemove(Main m) {
    211     if (m != null) {
    212       return m.g();
    213     }
    214     return m;
    215   }
    216 
    217   /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier (before)
    218   /// CHECK:         NullCheck
    219 
    220   /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier (after)
    221   /// CHECK:         NullCheck
    222   public Main scopeIfKeep(Main m) {
    223     if (m == null) {
    224       m = new Main();
    225     }
    226     return m.g();
    227   }
    228 
    229   public Main() {}
    230   public Main(int dummy) {}
    231 
    232   private Main g() {
    233     // avoids inlining
    234     throw new RuntimeException();
    235   }
    236 
    237   public static void main(String[] args) {
    238     new Main();
    239   }
    240 
    241 }
    242 
    243 // Regression for when we created and kept equivalent phis with the same type.
    244 // The phi used in comparison would be different then the one used for access
    245 // so we could not safely discard it.
    246 class ListElement {
    247   private ListElement next;
    248 
    249   /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier (before)
    250   /// CHECK:         NullCheck
    251   /// CHECK:         NullCheck
    252 
    253   /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier (after)
    254   /// CHECK-NOT:     NullCheck
    255   static boolean isShorter(ListElement x, ListElement y) {
    256     ListElement xTail = x;
    257     ListElement yTail = y;
    258     while (yTail != null) {
    259       if (xTail == null) return true;
    260       xTail = xTail.next;
    261       yTail = yTail.next;
    262     }
    263     return false;
    264   }
    265 }
    266