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 } 120 } 121 122 /// CHECK-START: void Main.loop7(boolean) liveness (after) 123 /// CHECK: <<Arg:z\d+>> ParameterValue liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse2:\d+>>)} uses:[<<ArgUse1:\d+>>,<<ArgUse2:\d+>>,<<ArgLoopUse1:\d+>>,<<ArgLoopUse2>>] 124 /// CHECK: InvokeVirtual [{{l\d+}},<<Arg>>] method_name:java.io.PrintStream.println liveness:<<InvokeLiv:\d+>> 125 /// CHECK: If [<<Arg>>] liveness:<<IfLiv:\d+>> 126 /// CHECK: Goto liveness:<<GotoLiv1:\d+>> 127 /// CHECK: Goto liveness:<<GotoLiv2:\d+>> 128 /// CHECK: Exit 129 /// CHECK-EVAL: <<InvokeLiv>> == <<ArgUse1>> 130 /// CHECK-EVAL: <<IfLiv>> + 1 == <<ArgUse2>> 131 /// CHECK-EVAL: <<GotoLiv1>> < <<GotoLiv2>> 132 /// CHECK-EVAL: <<GotoLiv1>> + 2 == <<ArgLoopUse1>> 133 /// CHECK-EVAL: <<GotoLiv2>> + 2 == <<ArgLoopUse2>> 134 135 public static void loop7(boolean incoming) { 136 // 'incoming' must have a use at both back edges. 137 while (Runtime.getRuntime() != null) { 138 System.out.println(incoming); 139 while (incoming) {} 140 System.nanoTime(); // beat back edge splitting 141 } 142 } 143 144 /// CHECK-START: void Main.loop8() liveness (after) 145 /// CHECK: <<Arg:z\d+>> StaticFieldGet liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse2:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse1:\d+>>,<<ArgLoopUse2>>] 146 /// CHECK: If [<<Arg>>] liveness:<<IfLiv:\d+>> 147 /// CHECK: Goto liveness:<<GotoLiv1:\d+>> 148 /// CHECK: Goto liveness:<<GotoLiv2:\d+>> 149 /// CHECK: Exit 150 /// CHECK-EVAL: <<IfLiv>> + 1 == <<ArgUse>> 151 /// CHECK-EVAL: <<GotoLiv1>> < <<GotoLiv2>> 152 /// CHECK-EVAL: <<GotoLiv1>> + 2 == <<ArgLoopUse1>> 153 /// CHECK-EVAL: <<GotoLiv2>> + 2 == <<ArgLoopUse2>> 154 155 public static void loop8() { 156 // 'incoming' must have a use at both back edges. 157 boolean incoming = field; 158 while (Runtime.getRuntime() != null) { 159 System.nanoTime(); // beat pre-header creation 160 while (incoming) {} 161 System.nanoTime(); // beat back edge splitting 162 } 163 } 164 165 /// CHECK-START: void Main.loop9() liveness (after) 166 /// CHECK: <<Arg:z\d+>> StaticFieldGet liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopUse:\d+>>)} uses:[<<ArgUse:\d+>>,<<ArgLoopUse>>] 167 /// CHECK: If [<<Arg>>] liveness:<<IfLiv:\d+>> 168 /// CHECK: Goto liveness:<<GotoLiv1:\d+>> 169 /// CHECK: Exit 170 /// CHECK: Goto liveness:<<GotoLiv2:\d+>> 171 /// CHECK-EVAL: <<IfLiv>> + 1 == <<ArgUse>> 172 /// CHECK-EVAL: <<GotoLiv1>> < <<GotoLiv2>> 173 /// CHECK-EVAL: <<GotoLiv1>> + 2 == <<ArgLoopUse>> 174 175 public static void loop9() { 176 // Add some code at entry to avoid having the entry block be a pre header. 177 // This avoids having to create a synthesized block. 178 System.out.println("Enter"); 179 while (Runtime.getRuntime() != null) { 180 // 'incoming' must only have a use in the inner loop. 181 boolean incoming = field; 182 while (incoming) {} 183 } 184 } 185 186 public static void main(String[] args) { 187 } 188 189 static boolean field; 190 } 191