1 /* 2 * Copyright (C) 2018 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 import java.lang.reflect.Method; 18 19 // 20 // Test loop optimizations, in particular scalar loop peeling and unrolling. 21 public class Main { 22 23 static final int LENGTH = 4 * 1024; 24 int[] a = new int[LENGTH]; 25 int[] b = new int[LENGTH]; 26 27 private static final int LENGTH_A = LENGTH; 28 private static final int LENGTH_B = 16; 29 private static final int RESULT_POS = 4; 30 31 double[][] mA; 32 double[][] mB; 33 double[][] mC; 34 Main()35 public Main() { 36 mA = new double[LENGTH_A][]; 37 mB = new double[LENGTH_B][]; 38 mC = new double[LENGTH_B][]; 39 for (int i = 0; i < LENGTH_A; i++) { 40 mA[i] = new double[LENGTH_B]; 41 } 42 43 for (int i = 0; i < LENGTH_B; i++) { 44 mB[i] = new double[LENGTH_A]; 45 mC[i] = new double[LENGTH_B]; 46 } 47 } 48 initMatrix(double[][] m)49 private static final void initMatrix(double[][] m) { 50 for (int i = 0; i < m.length; i++) { 51 for (int j = 0; j < m[i].length; j++) { 52 m[i][j] = (double) (i * LENGTH / (j + 1)); 53 } 54 } 55 } 56 initIntArray(int[] a)57 private static final void initIntArray(int[] a) { 58 for (int i = 0; i < a.length; i++) { 59 a[i] = i % 4; 60 } 61 } 62 initDoubleArray(double[] a)63 private static final void initDoubleArray(double[] a) { 64 for (int i = 0; i < a.length; i++) { 65 a[i] = (double)(i % 4); 66 } 67 } 68 69 /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (before) 70 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 71 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 72 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 73 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 74 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 75 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 76 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none 77 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 78 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 79 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none 80 /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none 81 // 82 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none 83 /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none 84 85 /// CHECK-START: void Main.unrollingLoadStoreElimination(int[]) loop_optimization (after) 86 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 87 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 88 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 89 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 90 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 91 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 92 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 93 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none 94 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 95 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 96 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none 97 /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none 98 // 99 /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<IndAdd>>,<<Limit>>] loop:<<Loop>> outer_loop:none 100 /// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none 101 /// CHECK-DAG: <<Get0A:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 102 /// CHECK-DAG: <<IndAddA:i\d+>> Add [<<IndAdd>>,<<Const1>>] loop:<<Loop>> outer_loop:none 103 /// CHECK-DAG: <<Get1A:i\d+>> ArrayGet [<<Array>>,<<IndAddA>>] loop:<<Loop>> outer_loop:none 104 /// CHECK-DAG: <<AddA:i\d+>> Add [<<Get0A>>,<<Get1A>>] loop:<<Loop>> outer_loop:none 105 /// CHECK-DAG: ArraySet [<<Array>>,<<IndAdd>>,<<AddA>>] loop:<<Loop>> outer_loop:none 106 // 107 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none 108 /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none unrollingLoadStoreElimination(int[] a)109 private static final void unrollingLoadStoreElimination(int[] a) { 110 for (int i = 0; i < LENGTH - 2; i++) { 111 a[i] += a[i + 1]; 112 } 113 } 114 115 // Simple check that loop unrolling has happened. 116 // 117 /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (before) 118 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 119 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 120 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4096 loop:none 121 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 122 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 123 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 124 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 125 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 126 /// CHECK-DAG: Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 127 // 128 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none 129 /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none 130 131 /// CHECK-START: void Main.unrollingSwitch(int[]) loop_optimization (after) 132 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 133 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 134 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4096 loop:none 135 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 136 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 137 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 138 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 139 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 140 /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 141 // 142 /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<AddI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 143 /// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none 144 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 145 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 146 /// CHECK-DAG: Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 147 // 148 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none 149 /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none unrollingSwitch(int[] a)150 private static final void unrollingSwitch(int[] a) { 151 for (int i = 0; i < LENGTH; i++) { 152 switch (i % 3) { 153 case 2: 154 a[i]++; 155 break; 156 default: 157 break; 158 } 159 } 160 } 161 162 // Simple check that loop unrolling has happened. 163 // 164 /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (before) 165 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 166 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 167 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 168 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 169 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 170 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 171 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 172 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 173 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 174 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 175 /// CHECK-DAG: Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 176 // 177 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none 178 /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none 179 180 /// CHECK-START: void Main.unrollingSwapElements(int[]) loop_optimization (after) 181 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 182 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 183 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 184 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 185 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 186 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 187 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 188 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 189 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 190 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 191 /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 192 // 193 /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<AddI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 194 /// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none 195 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 196 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 197 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 198 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 199 /// CHECK-DAG: Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 200 // 201 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none 202 /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none unrollingSwapElements(int[] array)203 private static final void unrollingSwapElements(int[] array) { 204 for (int i = 0; i < LENGTH - 2; i++) { 205 if (array[i] > array[i + 1]) { 206 int temp = array[i + 1]; 207 array[i + 1] = array[i]; 208 array[i] = temp; 209 } 210 } 211 } 212 213 // Simple check that loop unrolling has happened. 214 // 215 /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (before) 216 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 217 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 218 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 16 loop:none 219 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 220 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 221 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 222 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 223 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 224 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 225 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 226 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 227 /// CHECK-DAG: Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 228 // 229 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none 230 /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none 231 232 /// CHECK-START: void Main.unrollingRInnerproduct(double[][], double[][], double[][], int, int) loop_optimization (after) 233 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 234 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 235 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 16 loop:none 236 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 237 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 238 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 239 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 240 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 241 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 242 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 243 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 244 /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 245 // 246 /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<AddI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 247 /// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none 248 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 249 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 250 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 251 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 252 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 253 /// CHECK-DAG: Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 254 // 255 /// CHECK-NOT: ArrayGet loop:<<Loop>> outer_loop:none 256 /// CHECK-NOT: ArraySet loop:<<Loop>> outer_loop:none unrollingRInnerproduct(double[][] result, double[][] a, double[][] b, int row, int column)257 private static final void unrollingRInnerproduct(double[][] result, 258 double[][] a, 259 double[][] b, 260 int row, 261 int column) { 262 // computes the inner product of A[row,*] and B[*,column] 263 int i; 264 result[row][column] = 0.0f; 265 for (i = 0; i < LENGTH_B; i++) { 266 result[row][column] = result[row][column] + a[row][i] * b[i][column]; 267 } 268 } 269 270 // nested loop 271 // [[[]]] 272 273 /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (before) 274 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 275 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 276 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 277 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 278 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 279 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 280 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>> 281 /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>> 282 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 283 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 284 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 285 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 286 /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>> 287 // 288 /// CHECK-NOT: ArrayGet 289 /// CHECK-NOT: ArraySet 290 /// CHECK-NOT: If 291 292 /// CHECK-START: void Main.unrollingInTheNest(int[], int[], int) loop_optimization (after) 293 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 294 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 295 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 296 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 297 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 298 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 299 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>> 300 /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>> 301 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 302 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 303 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 304 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 305 /// CHECK-DAG: <<AddI:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>> 306 // 307 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop2>> 308 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 309 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 310 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 311 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 312 // 313 /// CHECK-NOT: ArrayGet 314 /// CHECK-NOT: ArraySet 315 /// CHECK-NOT: If unrollingInTheNest(int[] a, int[] b, int x)316 private static final void unrollingInTheNest(int[] a, int[] b, int x) { 317 for (int k = 0; k < 16; k++) { 318 for (int j = 0; j < 16; j++) { 319 for (int i = 0; i < 128; i++) { 320 b[x]++; 321 a[i] = a[i] + 1; 322 } 323 } 324 } 325 } 326 327 // nested loop: 328 // [ 329 // if [] else [] 330 // ] 331 332 /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before) 333 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 334 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 335 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 336 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 337 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 338 // 339 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 340 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 341 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 342 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 343 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 344 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 345 // 346 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 347 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 348 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 349 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 350 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 351 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 352 // 353 /// CHECK-NOT: ArrayGet 354 /// CHECK-NOT: ArraySet 355 /// CHECK-NOT: If 356 357 /// CHECK-START: void Main.unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after) 358 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 359 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 360 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 361 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 362 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 363 // 364 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 365 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 366 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 367 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 368 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 369 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 370 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop2>> outer_loop:<<Loop1>> 371 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 372 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 373 /// CHECK-DAG: Add [<<AddI2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 374 // 375 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 376 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 377 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 378 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 379 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 380 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 381 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop1>> 382 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 383 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 384 /// CHECK-DAG: Add [<<AddI3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 385 // 386 /// CHECK-NOT: ArrayGet 387 /// CHECK-NOT: ArraySet 388 /// CHECK-NOT: If unrollingTwoLoopsInTheNest(int[] a, int[] b, int x)389 private static final void unrollingTwoLoopsInTheNest(int[] a, int[] b, int x) { 390 for (int k = 0; k < 128; k++) { 391 if (x > 100) { 392 for (int j = 0; j < 128; j++) { 393 a[x]++; 394 } 395 } else { 396 for (int i = 0; i < 128; i++) { 397 b[x]++; 398 } 399 } 400 } 401 } 402 403 /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (before) 404 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 405 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 406 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 407 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 408 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 409 /// CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 410 /// CHECK-DAG: <<PhiT:i\d+>> Phi [<<Const2>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 411 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 412 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 413 /// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none 414 /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 415 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<AddI>>] loop:<<Loop>> outer_loop:none 416 /// CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Get0>>] loop:<<Loop>> outer_loop:none 417 /// CHECK-DAG: <<AddT:i\d+>> Mul [<<PhiT>>,<<Get0>>] loop:<<Loop>> outer_loop:none 418 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<PhiI>>] loop:<<Loop>> outer_loop:none 419 /// CHECK-DAG: <<AddArr:i\d+>> Add [<<AddS>>,<<Get1>>] loop:<<Loop>> outer_loop:none 420 /// CHECK-DAG: ArraySet [<<Array>>,<<PhiI>>,<<AddArr>>] loop:<<Loop>> outer_loop:none 421 // 422 /// CHECK-DAG: <<STAdd:i\d+>> Add [<<PhiS>>,<<PhiT>>] loop:none 423 /// CHECK-DAG: <<ZCheck:i\d+>> DivZeroCheck [<<STAdd>>] env:[[<<PhiS>>,<<PhiT>>,<<STAdd>>,<<Const1>>,_,<<Array>>]] loop:none 424 /// CHECK-DAG: <<Div:i\d+>> Div [<<Const1>>,<<ZCheck>>] loop:none 425 /// CHECK-DAG: Return [<<Div>>] loop:none 426 /// CHECK-NOT: ArrayGet 427 /// CHECK-NOT: ArraySet 428 429 /// CHECK-START: int Main.unrollingSimpleLiveOuts(int[]) loop_optimization (after) 430 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 431 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 432 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 433 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 434 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 435 /// CHECK-DAG: <<PhiS:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 436 /// CHECK-DAG: <<PhiT:i\d+>> Phi [<<Const2>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 437 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 438 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 439 /// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none 440 /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 441 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<AddI>>] loop:<<Loop>> outer_loop:none 442 /// CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Get0>>] loop:<<Loop>> outer_loop:none 443 /// CHECK-DAG: <<AddT:i\d+>> Mul [<<PhiT>>,<<Get0>>] loop:<<Loop>> outer_loop:none 444 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<PhiI>>] loop:<<Loop>> outer_loop:none 445 /// CHECK-DAG: <<AddArr:i\d+>> Add [<<AddS>>,<<Get1>>] loop:<<Loop>> outer_loop:none 446 /// CHECK-DAG: ArraySet [<<Array>>,<<PhiI>>,<<AddArr>>] loop:<<Loop>> outer_loop:none 447 // 448 /// CHECK-DAG: GreaterThanOrEqual [<<AddI>>,<<Limit>>] loop:<<Loop>> outer_loop:none 449 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop>> outer_loop:none 450 /// CHECK-DAG: <<AddIA:i\d+>> Add [<<AddI>>,<<Const1>>] loop:<<Loop>> outer_loop:none 451 /// CHECK-DAG: <<Get0A:i\d+>> ArrayGet [<<Array>>,<<AddIA>>] loop:<<Loop>> outer_loop:none 452 /// CHECK-DAG: <<AddSA:i\d+>> Add [<<AddS>>,<<Get0A>>] loop:<<Loop>> outer_loop:none 453 /// CHECK-DAG: <<AddTA:i\d+>> Mul [<<AddT>>,<<Get0A>>] loop:<<Loop>> outer_loop:none 454 /// CHECK-DAG: <<Get1A:i\d+>> ArrayGet [<<Array>>,<<AddI>>] loop:<<Loop>> outer_loop:none 455 /// CHECK-DAG: <<AddArrA:i\d+>> Add [<<AddSA>>,<<Get1A>>] loop:<<Loop>> outer_loop:none 456 /// CHECK-DAG: ArraySet [<<Array>>,<<AddI>>,<<AddArrA>>] loop:<<Loop>> outer_loop:none 457 // 458 /// CHECK-DAG: <<RetPhiS:i\d+>> Phi [<<PhiS>>,<<AddS>>] loop:none 459 /// CHECK-DAG: <<RetPhiT:i\d+>> Phi [<<PhiT>>,<<AddT>>] loop:none 460 /// CHECK-DAG: <<STAdd:i\d+>> Add [<<RetPhiS>>,<<RetPhiT>>] loop:none 461 /// CHECK-DAG: <<ZCheck:i\d+>> DivZeroCheck [<<STAdd>>] env:[[<<RetPhiS>>,<<RetPhiT>>,<<STAdd>>,<<Const1>>,_,<<Array>>]] loop:none 462 /// CHECK-DAG: <<Div:i\d+>> Div [<<Const1>>,<<ZCheck>>] loop:none 463 /// CHECK-DAG: Return [<<Div>>] loop:none 464 // 465 /// CHECK-NOT: ArrayGet 466 /// CHECK-NOT: ArraySet unrollingSimpleLiveOuts(int[] a)467 private static final int unrollingSimpleLiveOuts(int[] a) { 468 int s = 1; 469 int t = 2; 470 for (int i = 0; i < LENGTH - 2; i++) { 471 int temp = a[i + 1]; 472 s += temp; 473 t *= temp; 474 a[i] += s; 475 } 476 477 return 1 / (s + t); 478 } 479 480 /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (before) 481 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 482 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 483 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 484 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 485 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 486 // 487 /// CHECK-DAG: <<OutPhiJ:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop0:B\d+>> outer_loop:none 488 /// CHECK-DAG: <<OutPhiS:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop0>> outer_loop:none 489 /// CHECK-DAG: <<OutPhiT:i\d+>> Phi [<<Const2>>,{{i\d+}}] loop:<<Loop0>> outer_loop:none 490 // 491 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:<<Loop0>> 492 /// CHECK-DAG: <<PhiS:i\d+>> Phi [<<OutPhiS>>,{{i\d+}}] loop:<<Loop1>> outer_loop:<<Loop0>> 493 /// CHECK-DAG: <<PhiT:i\d+>> Phi [<<OutPhiT>>,{{i\d+}}] loop:<<Loop1>> outer_loop:<<Loop0>> 494 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop1>> outer_loop:<<Loop0>> 495 /// CHECK-DAG: If [<<Check>>] loop:<<Loop1>> outer_loop:<<Loop0>> 496 /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop1>> outer_loop:<<Loop0>> 497 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<AddI>>] loop:<<Loop1>> outer_loop:<<Loop0>> 498 /// CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Get0>>] loop:<<Loop1>> outer_loop:<<Loop0>> 499 /// CHECK-DAG: <<AddT:i\d+>> Mul [<<PhiT>>,<<Get0>>] loop:<<Loop1>> outer_loop:<<Loop0>> 500 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<PhiI>>] loop:<<Loop1>> outer_loop:<<Loop0>> 501 /// CHECK-DAG: <<AddArr:i\d+>> Add [<<AddS>>,<<Get1>>] loop:<<Loop1>> outer_loop:<<Loop0>> 502 /// CHECK-DAG: ArraySet [<<Array>>,<<PhiI>>,<<AddArr>>] loop:<<Loop1>> outer_loop:<<Loop0>> 503 // 504 /// CHECK-DAG: Add [<<OutPhiJ>>,<<Const1>>] loop:<<Loop0>> outer_loop:none 505 // 506 /// CHECK-NOT: ArrayGet 507 /// CHECK-NOT: ArraySet 508 509 /// CHECK-START: int Main.unrollingLiveOutsNested(int[]) loop_optimization (after) 510 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 511 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 512 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 513 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 514 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 515 // 516 /// CHECK-DAG: <<OutPhiJ:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop0:B\d+>> outer_loop:none 517 /// CHECK-DAG: <<OutPhiS:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop0>> outer_loop:none 518 /// CHECK-DAG: <<OutPhiT:i\d+>> Phi [<<Const2>>,{{i\d+}}] loop:<<Loop0>> outer_loop:none 519 // 520 /// CHECK-DAG: <<PhiI:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:<<Loop0>> 521 /// CHECK-DAG: <<PhiS:i\d+>> Phi [<<OutPhiS>>,{{i\d+}}] loop:<<Loop1>> outer_loop:<<Loop0>> 522 /// CHECK-DAG: <<PhiT:i\d+>> Phi [<<OutPhiT>>,{{i\d+}}] loop:<<Loop1>> outer_loop:<<Loop0>> 523 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<PhiI>>,<<Limit>>] loop:<<Loop1>> outer_loop:<<Loop0>> 524 /// CHECK-DAG: If [<<Check>>] loop:<<Loop1>> outer_loop:<<Loop0>> 525 /// CHECK-DAG: <<AddI:i\d+>> Add [<<PhiI>>,<<Const1>>] loop:<<Loop1>> outer_loop:<<Loop0>> 526 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<AddI>>] loop:<<Loop1>> outer_loop:<<Loop0>> 527 /// CHECK-DAG: <<AddS:i\d+>> Add [<<PhiS>>,<<Get0>>] loop:<<Loop1>> outer_loop:<<Loop0>> 528 /// CHECK-DAG: <<AddT:i\d+>> Mul [<<PhiT>>,<<Get0>>] loop:<<Loop1>> outer_loop:<<Loop0>> 529 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<PhiI>>] loop:<<Loop1>> outer_loop:<<Loop0>> 530 /// CHECK-DAG: <<AddArr:i\d+>> Add [<<AddS>>,<<Get1>>] loop:<<Loop1>> outer_loop:<<Loop0>> 531 /// CHECK-DAG: ArraySet [<<Array>>,<<PhiI>>,<<AddArr>>] loop:<<Loop1>> outer_loop:<<Loop0>> 532 // 533 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop1>> outer_loop:<<Loop0>> 534 /// CHECK-DAG: <<AddIA:i\d+>> Add [<<AddI>>,<<Const1>>] loop:<<Loop1>> outer_loop:<<Loop0>> 535 /// CHECK-DAG: <<Get0A:i\d+>> ArrayGet [<<Array>>,<<AddIA>>] loop:<<Loop1>> outer_loop:<<Loop0>> 536 /// CHECK-DAG: <<AddSA:i\d+>> Add [<<AddS>>,<<Get0A>>] loop:<<Loop1>> outer_loop:<<Loop0>> 537 /// CHECK-DAG: <<AddTA:i\d+>> Mul [<<AddT>>,<<Get0A>>] loop:<<Loop1>> outer_loop:<<Loop0>> 538 /// CHECK-DAG: <<Get1A:i\d+>> ArrayGet [<<Array>>,<<AddI>>] loop:<<Loop1>> outer_loop:<<Loop0>> 539 /// CHECK-DAG: <<AddArrA:i\d+>> Add [<<AddSA>>,<<Get1A>>] loop:<<Loop1>> outer_loop:<<Loop0>> 540 /// CHECK-DAG: ArraySet [<<Array>>,<<AddI>>,<<AddArrA>>] loop:<<Loop1>> outer_loop:<<Loop0>> 541 // 542 /// CHECK-DAG: <<RetPhiS:i\d+>> Phi [<<PhiS>>,<<AddS>>] loop:<<Loop0>> outer_loop:none 543 /// CHECK-DAG: <<RetPhiT:i\d+>> Phi [<<PhiT>>,<<AddT>>] loop:<<Loop0>> outer_loop:none 544 /// CHECK-DAG: Add [<<OutPhiJ>>,<<Const1>>] loop:<<Loop0>> outer_loop:none 545 // 546 /// CHECK-DAG: <<RetAdd:i\d+>> Add [<<OutPhiS>>,<<OutPhiT>>] loop:none 547 /// CHECK-DAG: Return [<<RetAdd>>] loop:none 548 // 549 /// CHECK-NOT: ArrayGet 550 /// CHECK-NOT: ArraySet unrollingLiveOutsNested(int[] a)551 private static final int unrollingLiveOutsNested(int[] a) { 552 int s = 1; 553 int t = 2; 554 for (int j = 0; j < 16; j++) { 555 for (int i = 0; i < LENGTH - 2; i++) { 556 int temp = a[i + 1]; 557 s += temp; 558 t *= temp; 559 a[i] += s; 560 } 561 } 562 return s + t; 563 } 564 565 /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (before) 566 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 567 /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 568 /// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none 569 // 570 /// CHECK-NOT: InstanceOf 571 572 /// CHECK-START: void Main.unrollingInstanceOf(int[], java.lang.Object[]) loop_optimization (after) 573 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 574 /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 575 /// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none 576 /// CHECK-DAG: InstanceOf loop:<<Loop>> outer_loop:none 577 // 578 /// CHECK-NOT: InstanceOf unrollingInstanceOf(int[] a, Object[] obj_array)579 public void unrollingInstanceOf(int[] a, Object[] obj_array) { 580 for (int i = 0; i < LENGTH_B; i++) { 581 if (obj_array[i] instanceof Integer) { 582 a[i] += 1; 583 } 584 } 585 } 586 587 /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (before) 588 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 589 /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 590 /// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none 591 // 592 /// CHECK-NOT: DivZeroCheck 593 594 /// CHECK-START: void Main.unrollingDivZeroCheck(int[], int) loop_optimization (after) 595 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 596 /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 597 /// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none 598 /// CHECK-DAG: DivZeroCheck loop:<<Loop>> outer_loop:none 599 // 600 /// CHECK-NOT: DivZeroCheck unrollingDivZeroCheck(int[] a, int r)601 public void unrollingDivZeroCheck(int[] a, int r) { 602 for (int i = 0; i < LENGTH_B; i++) { 603 a[i] += a[i] / r; 604 } 605 } 606 607 /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (before) 608 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 609 /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 610 /// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none 611 // 612 /// CHECK-NOT: TypeConversion 613 614 /// CHECK-START: void Main.unrollingTypeConversion(int[], double[]) loop_optimization (after) 615 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 616 /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 617 /// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none 618 /// CHECK-DAG: TypeConversion loop:<<Loop>> outer_loop:none 619 // 620 /// CHECK-NOT: TypeConversion unrollingTypeConversion(int[] a, double[] b)621 public void unrollingTypeConversion(int[] a, double[] b) { 622 for (int i = 0; i < LENGTH_B; i++) { 623 a[i] = (int) b[i]; 624 } 625 } 626 627 interface Itf { 628 } 629 630 class SubMain extends Main implements Itf { 631 } 632 633 /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (before) 634 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 635 /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 636 /// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none 637 // 638 /// CHECK-NOT: CheckCast 639 640 /// CHECK-START: void Main.unrollingCheckCast(int[], java.lang.Object) loop_optimization (after) 641 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 642 /// CHECK-DAG: Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 643 /// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none 644 /// CHECK-DAG: CheckCast loop:<<Loop>> outer_loop:none 645 // 646 /// CHECK-NOT: CheckCast unrollingCheckCast(int[] a, Object o)647 public void unrollingCheckCast(int[] a, Object o) { 648 for (int i = 0; i < LENGTH_B; i++) { 649 if (((SubMain)o) == o) { 650 a[i] = i; 651 } 652 } 653 } 654 655 /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (before) 656 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 657 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 658 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4095 loop:none 659 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 660 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 661 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 662 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none 663 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 664 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 665 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none 666 /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none 667 // 668 /// CHECK-NOT: Phi 669 /// CHECK-NOT: If 670 /// CHECK-NOT: ArrayGet 671 /// CHECK-NOT: ArraySet 672 673 /// CHECK-START: void Main.noUnrollingOddTripCount(int[]) loop_optimization (after) 674 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 675 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 676 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 677 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 678 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 679 // 680 /// CHECK-NOT: Phi 681 /// CHECK-NOT: If 682 /// CHECK-NOT: ArrayGet 683 /// CHECK-NOT: ArraySet noUnrollingOddTripCount(int[] a)684 private static final void noUnrollingOddTripCount(int[] a) { 685 for (int i = 0; i < LENGTH - 1; i++) { 686 a[i] += a[i + 1]; 687 } 688 } 689 690 /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (before) 691 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 692 /// CHECK-DAG: <<Limit:i\d+>> ParameterValue loop:none 693 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 694 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 695 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 696 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 697 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none 698 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 699 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 700 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none 701 /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none 702 // 703 /// CHECK-NOT: Phi 704 /// CHECK-NOT: ArrayGet 705 /// CHECK-NOT: ArraySet 706 707 /// CHECK-START: void Main.noUnrollingNotKnownTripCount(int[], int) loop_optimization (after) 708 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 709 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 710 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 711 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 712 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 713 // 714 /// CHECK-NOT: Phi 715 /// CHECK-NOT: ArrayGet 716 /// CHECK-NOT: ArraySet noUnrollingNotKnownTripCount(int[] a, int n)717 private static final void noUnrollingNotKnownTripCount(int[] a, int n) { 718 for (int i = 0; i < n; i++) { 719 a[i] += a[i + 1]; 720 } 721 } 722 723 /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (before) 724 /// CHECK-DAG: <<Param:z\d+>> ParameterValue loop:none 725 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 726 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 727 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4096 loop:none 728 /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 729 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 730 /// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none 731 /// CHECK-DAG: If [<<Param>>] loop:<<Loop>> outer_loop:none 732 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 733 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 734 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 735 // 736 /// CHECK-NOT: If 737 /// CHECK-NOT: ArraySet 738 739 /// CHECK-START: void Main.peelingSimple(int[], boolean) loop_optimization (after) 740 /// CHECK-DAG: <<Param:z\d+>> ParameterValue loop:none 741 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 742 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 743 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4096 loop:none 744 /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<Const0>>,<<Limit>>] loop:none 745 /// CHECK-DAG: If [<<CheckA>>] loop:none 746 /// CHECK-DAG: If [<<Param>>] loop:none 747 /// CHECK-DAG: ArrayGet loop:none 748 /// CHECK-DAG: ArraySet loop:none 749 /// CHECK-DAG: <<IndAddA:i\d+>> Add [<<Const0>>,<<Const1>>] loop:none 750 /// CHECK-DAG: <<Phi:i\d+>> Phi [<<IndAddA>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 751 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 752 /// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none 753 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop>> outer_loop:none 754 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 755 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 756 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 757 // 758 /// CHECK-NOT: If 759 /// CHECK-NOT: ArraySet 760 761 /// CHECK-START: void Main.peelingSimple(int[], boolean) dead_code_elimination$final (after) 762 /// CHECK-DAG: <<Param:z\d+>> ParameterValue loop:none 763 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 764 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 765 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4096 loop:none 766 /// CHECK-DAG: If [<<Param>>] loop:none 767 /// CHECK-DAG: ArrayGet loop:none 768 /// CHECK-DAG: ArraySet loop:none 769 /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 770 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 771 /// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none 772 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 773 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 774 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 775 // 776 /// CHECK-NOT: GreaterThanOrEqual 777 /// CHECK-NOT: If 778 /// CHECK-NOT: ArrayGet 779 /// CHECK-NOT: ArraySet peelingSimple(int[] a, boolean f)780 private static final void peelingSimple(int[] a, boolean f) { 781 for (int i = 0; i < LENGTH; i++) { 782 if (f) { 783 break; 784 } 785 a[i] += 1; 786 } 787 } 788 789 // Often used idiom that, when not hoisted, prevents BCE and vectorization. 790 // 791 /// CHECK-START: void Main.peelingAddInts(int[]) loop_optimization (before) 792 /// CHECK-DAG: <<Param:l\d+>> ParameterValue loop:none 793 /// CHECK-DAG: <<ConstNull:l\d+>> NullConstant loop:none 794 /// CHECK-DAG: <<Eq:z\d+>> Equal [<<Param>>,<<ConstNull>>] loop:none 795 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 796 /// CHECK-DAG: If [<<Eq>>] loop:<<Loop>> outer_loop:none 797 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 798 /// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none 799 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 800 801 /// CHECK-START: void Main.peelingAddInts(int[]) dead_code_elimination$final (after) 802 /// CHECK-DAG: <<Param:l\d+>> ParameterValue loop:none 803 /// CHECK-DAG: <<ConstNull:l\d+>> NullConstant loop:none 804 /// CHECK-DAG: <<Eq:z\d+>> Equal [<<Param>>,<<ConstNull>>] loop:none 805 /// CHECK-DAG: If [<<Eq>>] loop:none 806 /// CHECK-DAG: ArraySet loop:none 807 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 808 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 809 /// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none 810 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 811 // 812 /// CHECK-NOT: If [<<Eq>>] loop:<<Loop>> outer_loop:none peelingAddInts(int[] a)813 private static final void peelingAddInts(int[] a) { 814 for (int i = 0; a != null && i < a.length; i++) { 815 a[i] += 1; 816 } 817 } 818 819 /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) loop_optimization (before) 820 /// CHECK-DAG: <<Param:z\d+>> ParameterValue loop:none 821 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 822 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 823 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4096 loop:none 824 /// CHECK-DAG: <<Phi0:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop0:B\d+>> outer_loop:none 825 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:<<Loop0>> 826 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi1>>,<<Limit>>] loop:<<Loop1>> outer_loop:<<Loop0>> 827 /// CHECK-DAG: If [<<Check>>] loop:<<Loop1>> outer_loop:<<Loop0>> 828 /// CHECK-DAG: If [<<Param>>] loop:<<Loop1>> outer_loop:<<Loop0>> 829 /// CHECK-DAG: ArrayGet loop:<<Loop1>> outer_loop:<<Loop0>> 830 /// CHECK-DAG: ArraySet loop:<<Loop1>> outer_loop:<<Loop0>> 831 /// CHECK-DAG: <<IndAdd1:i\d+>> Add [<<Phi1>>,<<Const1>>] loop:<<Loop1>> outer_loop:<<Loop0>> 832 /// CHECK-DAG: <<IndAdd0:i\d+>> Add [<<Phi0>>,<<Const1>>] loop:<<Loop0>> outer_loop:none 833 // 834 /// CHECK-NOT: If 835 /// CHECK-NOT: ArraySet 836 837 /// CHECK-START: void Main.peelingBreakFromNest(int[], boolean) dead_code_elimination$final (after) 838 /// CHECK-DAG: <<Param:z\d+>> ParameterValue loop:none 839 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 840 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 841 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4096 loop:none 842 /// CHECK-DAG: <<Phi0:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop0:B\d+>> outer_loop:none 843 /// CHECK-DAG: If [<<Param>>] loop:<<Loop0>> outer_loop:none 844 /// CHECK-DAG: ArrayGet loop:<<Loop0>> outer_loop:none 845 /// CHECK-DAG: ArraySet loop:<<Loop0>> outer_loop:none 846 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:<<Loop0>> 847 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi1>>,<<Limit>>] loop:<<Loop1>> outer_loop:<<Loop0>> 848 /// CHECK-DAG: If [<<Check>>] loop:<<Loop1>> outer_loop:<<Loop0>> 849 /// CHECK-DAG: ArrayGet loop:<<Loop1>> outer_loop:<<Loop0>> 850 /// CHECK-DAG: ArraySet loop:<<Loop1>> outer_loop:<<Loop0>> 851 /// CHECK-DAG: <<IndAdd1:i\d+>> Add [<<Phi1>>,<<Const1>>] loop:<<Loop1>> outer_loop:<<Loop0>> 852 /// CHECK-DAG: <<IndAdd0:i\d+>> Add [<<Phi0>>,<<Const1>>] loop:<<Loop0>> outer_loop:none 853 // 854 /// CHECK-NOT: If 855 /// CHECK-NOT: ArraySet peelingBreakFromNest(int[] a, boolean f)856 private static final void peelingBreakFromNest(int[] a, boolean f) { 857 outer: 858 for (int i = 1; i < 32; i++) { 859 for (int j = 0; j < LENGTH; j++) { 860 if (f) { 861 break outer; 862 } 863 a[j] += 1; 864 } 865 } 866 } 867 868 /// CHECK-START: int Main.peelingHoistOneControl(int) loop_optimization (before) 869 /// CHECK-DAG: <<Param:i\d+>> ParameterValue loop:none 870 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 871 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 872 /// CHECK-DAG: <<Check:z\d+>> NotEqual [<<Param>>,<<Const0>>] loop:none 873 /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 874 /// CHECK-DAG: If [<<Check>>] loop:<<Loop>> outer_loop:none 875 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 876 // 877 /// CHECK-NOT: If 878 879 /// CHECK-START: int Main.peelingHoistOneControl(int) dead_code_elimination$final (after) 880 /// CHECK-DAG: <<Param:i\d+>> ParameterValue loop:none 881 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 882 /// CHECK-DAG: <<Check:z\d+>> NotEqual [<<Param>>,<<Const0>>] loop:none 883 /// CHECK-DAG: If [<<Check>>] loop:none 884 /// CHECK-DAG: SuspendCheck loop:<<Loop:B\d+>> outer_loop:none 885 /// CHECK-DAG: Goto loop:<<Loop>> outer_loop:none 886 // 887 // Check that the loop has no instruction except SuspendCheck and Goto (indefinite loop). 888 /// CHECK-NOT: loop:<<Loop>> outer_loop:none 889 /// CHECK-NOT: If 890 /// CHECK-NOT: Phi 891 /// CHECK-NOT: Add peelingHoistOneControl(int x)892 private static final int peelingHoistOneControl(int x) { 893 int i = 0; 894 while (true) { 895 if (x == 0) 896 return 1; 897 i++; 898 } 899 } 900 901 /// CHECK-START: int Main.peelingHoistOneControl(int, int) loop_optimization (before) 902 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 903 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 904 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 905 // 906 /// CHECK-START: int Main.peelingHoistOneControl(int, int) dead_code_elimination$final (after) 907 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 908 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 909 /// CHECK-NOT: If loop:<<Loop>> outer_loop:none peelingHoistOneControl(int x, int y)910 private static final int peelingHoistOneControl(int x, int y) { 911 while (true) { 912 if (x == 0) 913 return 1; 914 if (y == 0) // no longer invariant 915 return 2; 916 y--; 917 } 918 } 919 920 /// CHECK-START: int Main.peelingHoistTwoControl(int, int, int) loop_optimization (before) 921 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 922 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 923 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 924 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 925 // 926 /// CHECK-START: int Main.peelingHoistTwoControl(int, int, int) dead_code_elimination$final (after) 927 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 928 /// CHECK-DAG: If loop:<<Loop>> outer_loop:none 929 /// CHECK-NOT: If loop:<<Loop>> outer_loop:none peelingHoistTwoControl(int x, int y, int z)930 private static final int peelingHoistTwoControl(int x, int y, int z) { 931 while (true) { 932 if (x == 0) 933 return 1; 934 if (y == 0) 935 return 2; 936 if (z == 0) // no longer invariant 937 return 3; 938 z--; 939 } 940 } 941 942 /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (before) 943 /// CHECK-DAG: <<Param:l\d+>> ParameterValue loop:none 944 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 945 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 946 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 2 loop:none 947 /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 948 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 949 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 950 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 951 // 952 /// CHECK-NOT: ArrayGet 953 /// CHECK-NOT: ArraySet 954 955 /// CHECK-START: void Main.unrollingFull(int[]) loop_optimization (after) 956 /// CHECK-DAG: <<Param:l\d+>> ParameterValue loop:none 957 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 958 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 959 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 2 loop:none 960 // Two peeled iterations 961 /// CHECK-DAG: ArrayGet loop:none 962 /// CHECK-DAG: ArrayGet loop:none 963 /// CHECK-DAG: ArraySet loop:none 964 /// CHECK-DAG: ArrayGet loop:none 965 /// CHECK-DAG: ArrayGet loop:none 966 /// CHECK-DAG: ArraySet loop:none 967 // Loop 968 /// CHECK-DAG: <<Phi:i\d+>> Phi [{{i\d+}},{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 969 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 970 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 971 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 972 /// CHECK-DAG: If [<<Const1>>] loop:<<Loop>> outer_loop:none 973 // 974 /// CHECK-NOT: ArrayGet 975 /// CHECK-NOT: ArraySet unrollingFull(int[] a)976 private static final void unrollingFull(int[] a) { 977 for (int i = 0; i < 2; i++) { 978 a[i] += a[i + 1]; 979 } 980 } 981 expectEquals(int expected, int result)982 private static void expectEquals(int expected, int result) { 983 if (expected != result) { 984 throw new Error("Expected: " + expected + ", found: " + result); 985 } 986 } 987 verifyUnrolling()988 public void verifyUnrolling() throws Exception { 989 initIntArray(a); 990 initIntArray(b); 991 992 initMatrix(mA); 993 initMatrix(mB); 994 initMatrix(mC); 995 996 int expected = 174291515; 997 int found = 0; 998 999 double[] doubleArray = new double[LENGTH_B]; 1000 initDoubleArray(doubleArray); 1001 1002 unrollingInstanceOf(a, new Integer[LENGTH_B]); 1003 unrollingDivZeroCheck(a, 15); 1004 unrollingTypeConversion(a, doubleArray); 1005 unrollingCheckCast(a, new SubMain()); 1006 1007 // Call unrollingWhile(a); 1008 Class<?> c = Class.forName("PeelUnroll"); 1009 Method m = c.getMethod("unrollingWhile", Class.forName("[I")); 1010 Object[] arguments = { a }; 1011 m.invoke(null, arguments); 1012 1013 unrollingLoadStoreElimination(a); 1014 unrollingSwitch(a); 1015 unrollingSwapElements(a); 1016 unrollingRInnerproduct(mC, mA, mB, RESULT_POS, RESULT_POS); 1017 unrollingInTheNest(a, b, RESULT_POS); 1018 unrollingTwoLoopsInTheNest(a, b, RESULT_POS); 1019 1020 noUnrollingOddTripCount(b); 1021 noUnrollingNotKnownTripCount(b, 128); 1022 1023 for (int i = 0; i < LENGTH; i++) { 1024 found += a[i]; 1025 found += b[i]; 1026 } 1027 found += (int)mC[RESULT_POS][RESULT_POS]; 1028 1029 expectEquals(expected, found); 1030 } 1031 verifyPeeling()1032 public void verifyPeeling() throws Exception { 1033 expectEquals(1, peelingHoistOneControl(0)); // anything else loops 1034 expectEquals(1, peelingHoistOneControl(0, 0)); 1035 expectEquals(1, peelingHoistOneControl(0, 1)); 1036 expectEquals(2, peelingHoistOneControl(1, 0)); 1037 expectEquals(2, peelingHoistOneControl(1, 1)); 1038 expectEquals(1, peelingHoistTwoControl(0, 0, 0)); 1039 expectEquals(1, peelingHoistTwoControl(0, 0, 1)); 1040 expectEquals(1, peelingHoistTwoControl(0, 1, 0)); 1041 expectEquals(1, peelingHoistTwoControl(0, 1, 1)); 1042 expectEquals(2, peelingHoistTwoControl(1, 0, 0)); 1043 expectEquals(2, peelingHoistTwoControl(1, 0, 1)); 1044 expectEquals(3, peelingHoistTwoControl(1, 1, 0)); 1045 expectEquals(3, peelingHoistTwoControl(1, 1, 1)); 1046 1047 initIntArray(a); 1048 peelingSimple(a, false); 1049 peelingSimple(a, true); 1050 peelingAddInts(a); 1051 peelingAddInts(null); // okay 1052 peelingBreakFromNest(a, false); 1053 peelingBreakFromNest(a, true); 1054 1055 unrollingSimpleLiveOuts(a); 1056 1057 // Call unrollingWhileLiveOuts(a); 1058 Class<?> c = Class.forName("PeelUnroll"); 1059 Method m = c.getMethod("unrollingWhileLiveOuts", Class.forName("[I")); 1060 Object[] arguments = { a }; 1061 m.invoke(null, arguments); 1062 1063 unrollingLiveOutsNested(a); 1064 1065 int expected = 51565978; 1066 int found = 0; 1067 for (int i = 0; i < a.length; i++) { 1068 found += a[i]; 1069 } 1070 1071 expectEquals(expected, found); 1072 } 1073 main(String[] args)1074 public static void main(String[] args) throws Exception { 1075 Main obj = new Main(); 1076 1077 obj.verifyUnrolling(); 1078 obj.verifyPeeling(); 1079 1080 System.out.println("passed"); 1081 } 1082 } 1083