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