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 
     18 public class Main {
     19 
     20   /// CHECK-START: void Main.loop1(boolean) liveness (after)
     21   /// CHECK:         <<Arg:z\d+>>  ParameterValue  liveness:<<ArgLiv:\d+>>  ranges:{[<<ArgLiv>>,<<ArgLoopUse:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse>>]
     22   /// CHECK:                       If [<<Arg>>]    liveness:<<IfLiv:\d+>>
     23   /// CHECK:                       Goto            liveness:<<GotoLiv:\d+>>
     24   /// CHECK:                       Exit
     25   /// CHECK-EVAL:    <<IfLiv>> + 1 == <<ArgUse>>
     26   /// CHECK-EVAL:    <<GotoLiv>> + 2 == <<ArgLoopUse>>
     27 
     28   public static void loop1(boolean incoming) {
     29     while (incoming) {}
     30   }
     31 
     32   /// CHECK-START: void Main.loop2(boolean) liveness (after)
     33   /// CHECK:         <<Arg:z\d+>>  ParameterValue  liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse2:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse1:\d+>>,<<ArgLoopUse2>>]
     34   /// CHECK:                       If [<<Arg>>]    liveness:<<IfLiv:\d+>>
     35   /// CHECK:                       Goto            liveness:<<GotoLiv1:\d+>>
     36   /// CHECK:                       Goto            liveness:<<GotoLiv2:\d+>>
     37   /// CHECK-EVAL:    <<IfLiv>> + 1 == <<ArgUse>>
     38   /// CHECK-EVAL:    <<GotoLiv1>> < <<GotoLiv2>>
     39   /// CHECK-EVAL:    <<GotoLiv1>> + 2 == <<ArgLoopUse1>>
     40   /// CHECK-EVAL:    <<GotoLiv2>> + 2 == <<ArgLoopUse2>>
     41 
     42   public static void loop2(boolean incoming) {
     43     // Add some code at entry to avoid having the entry block be a pre header.
     44     // This avoids having to create a synthesized block.
     45     System.out.println("Enter");
     46     while (true) {
     47       System.out.println("foo");
     48       while (incoming) {}
     49     }
     50   }
     51 
     52   /// CHECK-START: void Main.loop3(boolean) liveness (after)
     53   /// CHECK:         <<Arg:z\d+>>  ParameterValue  liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse>>]
     54   /// CHECK:                       Goto            liveness:<<GotoLiv1:\d+>>
     55   /// CHECK:                       InvokeVirtual   [{{l\d+}},<<Arg>>] method_name:java.io.PrintStream.println liveness:<<InvokeLiv:\d+>>
     56   /// CHECK:                       Goto            liveness:<<GotoLiv2:\d+>>
     57   /// CHECK-EVAL:    <<InvokeLiv>> == <<ArgUse>>
     58   /// CHECK-EVAL:    <<GotoLiv1>> < <<GotoLiv2>>
     59   /// CHECK-EVAL:    <<GotoLiv2>> + 2 == <<ArgLoopUse>>
     60 
     61   public static void loop3(boolean incoming) {
     62     // 'incoming' only needs a use at the outer loop's back edge.
     63     while (System.currentTimeMillis() != 42) {
     64       while (Runtime.getRuntime() != null) {}
     65       System.out.println(incoming);
     66     }
     67   }
     68 
     69   /// CHECK-START: void Main.loop4(boolean) liveness (after)
     70   /// CHECK:         <<Arg:z\d+>> ParameterValue  liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgUse:\d+>>)} uses:[<<ArgUse>>]
     71   /// CHECK:                      InvokeVirtual   [{{l\d+}},<<Arg>>] method_name:java.io.PrintStream.println liveness:<<InvokeLiv:\d+>>
     72   /// CHECK-EVAL:    <<InvokeLiv>> == <<ArgUse>>
     73 
     74   public static void loop4(boolean incoming) {
     75     // 'incoming' has no loop use, so should not have back edge uses.
     76     System.out.println(incoming);
     77     while (System.currentTimeMillis() != 42) {
     78       while (Runtime.getRuntime() != null) {}
     79     }
     80   }
     81 
     82   /// CHECK-START: void Main.loop5(boolean) liveness (after)
     83   /// CHECK:         <<Arg:z\d+>>  ParameterValue  liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse2:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse1:\d+>>,<<ArgLoopUse2>>]
     84   /// CHECK:                       InvokeVirtual   [{{l\d+}},<<Arg>>] method_name:java.io.PrintStream.println liveness:<<InvokeLiv:\d+>>
     85   /// CHECK:                       Goto            liveness:<<GotoLiv1:\d+>>
     86   /// CHECK:                       Goto            liveness:<<GotoLiv2:\d+>>
     87   /// CHECK:                       Exit
     88   /// CHECK-EVAL:    <<InvokeLiv>> == <<ArgUse>>
     89   /// CHECK-EVAL:    <<GotoLiv1>> < <<GotoLiv2>>
     90   /// CHECK-EVAL:    <<GotoLiv1>> + 2 == <<ArgLoopUse1>>
     91   /// CHECK-EVAL:    <<GotoLiv2>> + 2 == <<ArgLoopUse2>>
     92 
     93   public static void loop5(boolean incoming) {
     94     // 'incoming' must have a use at both back edges.
     95     for (long i = System.nanoTime(); i < 42; ++i) {
     96       for (long j = System.currentTimeMillis(); j != 42; ++j) {
     97         System.out.println(incoming);
     98       }
     99     }
    100   }
    101 
    102   /// CHECK-START: void Main.loop6(boolean) liveness (after)
    103   /// CHECK:         <<Arg:z\d+>>  ParameterValue  liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse>>]
    104   /// CHECK:                       InvokeVirtual   [{{l\d+}},<<Arg>>] method_name:java.io.PrintStream.println liveness:<<InvokeLiv:\d+>>
    105   /// CHECK:                       Add
    106   /// CHECK:                       Goto            liveness:<<GotoLiv1:\d+>>
    107   /// CHECK:                       Add
    108   /// CHECK:                       Goto            liveness:<<GotoLiv2:\d+>>
    109   /// CHECK:                       Exit
    110   /// CHECK-EVAL:    <<InvokeLiv>> == <<ArgUse>>
    111   /// CHECK-EVAL:    <<GotoLiv1>> < <<GotoLiv2>>
    112   /// CHECK-EVAL:    <<GotoLiv2>> + 2 == <<ArgLoopUse>>
    113 
    114   public static void loop6(boolean incoming) {
    115     // 'incoming' must have a use only at the first loop's back edge.
    116     for (long i = System.nanoTime(); i < 42; ++i) {
    117       System.out.println(incoming);
    118       for (long j = System.currentTimeMillis(); j != 42; ++j) {
    119         System.out.print(j);  // non-empty body
    120       }
    121     }
    122   }
    123 
    124   /// CHECK-START: void Main.loop7(boolean) liveness (after)
    125   /// CHECK:         <<Arg:z\d+>>  ParameterValue  liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse2:\d+>>)} uses:[<<ArgUse1:\d+>>,<<ArgUse2:\d+>>,<<ArgLoopUse1:\d+>>,<<ArgLoopUse2>>]
    126   /// CHECK:                       InvokeVirtual   [{{l\d+}},<<Arg>>] method_name:java.io.PrintStream.println liveness:<<InvokeLiv:\d+>>
    127   /// CHECK:                       If              [<<Arg>>] liveness:<<IfLiv:\d+>>
    128   /// CHECK:                       Goto            liveness:<<GotoLiv1:\d+>>
    129   /// CHECK:                       Goto            liveness:<<GotoLiv2:\d+>>
    130   /// CHECK:                       Exit
    131   /// CHECK-EVAL:    <<InvokeLiv>> == <<ArgUse1>>
    132   /// CHECK-EVAL:    <<IfLiv>> + 1 == <<ArgUse2>>
    133   /// CHECK-EVAL:    <<GotoLiv1>> < <<GotoLiv2>>
    134   /// CHECK-EVAL:    <<GotoLiv1>> + 2 == <<ArgLoopUse1>>
    135   /// CHECK-EVAL:    <<GotoLiv2>> + 2 == <<ArgLoopUse2>>
    136 
    137   public static void loop7(boolean incoming) {
    138     // 'incoming' must have a use at both back edges.
    139     while (Runtime.getRuntime() != null) {
    140       System.out.println(incoming);
    141       while (incoming) {}
    142       System.nanoTime();  // beat back edge splitting
    143     }
    144   }
    145 
    146   /// CHECK-START: void Main.loop8() liveness (after)
    147   /// CHECK:         <<Arg:z\d+>>  StaticFieldGet  liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse2:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse1:\d+>>,<<ArgLoopUse2>>]
    148   /// CHECK:                       If [<<Arg>>]    liveness:<<IfLiv:\d+>>
    149   /// CHECK:                       Goto            liveness:<<GotoLiv1:\d+>>
    150   /// CHECK:                       Goto            liveness:<<GotoLiv2:\d+>>
    151   /// CHECK:                       Exit
    152   /// CHECK-EVAL:    <<IfLiv>> + 1 == <<ArgUse>>
    153   /// CHECK-EVAL:    <<GotoLiv1>> < <<GotoLiv2>>
    154   /// CHECK-EVAL:    <<GotoLiv1>> + 2 == <<ArgLoopUse1>>
    155   /// CHECK-EVAL:    <<GotoLiv2>> + 2 == <<ArgLoopUse2>>
    156 
    157   public static void loop8() {
    158     // 'incoming' must have a use at both back edges.
    159     boolean incoming = field;
    160     while (Runtime.getRuntime() != null) {
    161       System.nanoTime();  // beat pre-header creation
    162       while (incoming) {}
    163       System.nanoTime();  // beat back edge splitting
    164     }
    165   }
    166 
    167 
    168   static boolean $opt$noinline$ensureSideEffects() {
    169     if (doThrow) throw new Error("");
    170     return true;
    171   }
    172 
    173   /// CHECK-START: void Main.loop9() liveness (after)
    174   /// CHECK:         <<Arg:z\d+>>  StaticFieldGet  liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse>>]
    175   /// CHECK:                       If [<<Arg>>]    liveness:<<IfLiv:\d+>>
    176   /// CHECK:                       Goto            liveness:<<GotoLiv1:\d+>>
    177   /// CHECK-DAG:                   Goto            liveness:<<GotoLiv2:\d+>>
    178   /// CHECK-DAG:                   Exit
    179   /// CHECK-EVAL:    <<IfLiv>> + 1 == <<ArgUse>>
    180   /// CHECK-EVAL:    <<GotoLiv1>> < <<GotoLiv2>>
    181   /// CHECK-EVAL:    <<GotoLiv1>> + 2 == <<ArgLoopUse>>
    182 
    183   public static void loop9() {
    184     // Add some code at entry to avoid having the entry block be a pre header.
    185     // This avoids having to create a synthesized block.
    186     System.out.println("Enter");
    187     while ($opt$noinline$ensureSideEffects()) {
    188       // 'incoming' must only have a use in the inner loop.
    189       boolean incoming = field;
    190       while (incoming) {}
    191     }
    192   }
    193 
    194   public static void main(String[] args) {
    195   }
    196 
    197   static boolean field;
    198   static boolean doThrow = false;
    199 }
    200