1 /* 2 * Copyright (C) 2016 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 // Test on loop unrolling. Removes loop control overhead (including suspend 19 // checks) and exposes more opportunities for constant folding. 20 // 21 public class Main { 22 23 static int sA = 0; 24 25 /// CHECK-START: void Main.unroll() loop_optimization (before) 26 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 27 /// CHECK-DAG: StaticFieldSet loop:<<Loop>> 28 // 29 /// CHECK-START: void Main.unroll() loop_optimization (after) 30 /// CHECK-DAG: StaticFieldSet loop:none 31 // 32 /// CHECK-START: void Main.unroll() instruction_simplifier$after_bce (after) 33 /// CHECK-DAG: <<Int:i\d+>> IntConstant 68 loop:none 34 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int>>] loop:none 35 // 36 /// CHECK-START: void Main.unroll() loop_optimization (after) 37 /// CHECK-NOT: Phi unroll()38 public static void unroll() { 39 for (int i = 4; i < 5; i++) { 40 sA = 17 * i; 41 } 42 } 43 44 /// CHECK-START: int Main.unrollLV() loop_optimization (before) 45 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> 46 /// CHECK-DAG: StaticFieldSet loop:<<Loop>> 47 /// CHECK-DAG: Return [<<Phi>>] loop:none 48 // 49 /// CHECK-START: int Main.unrollLV() loop_optimization (after) 50 /// CHECK-DAG: StaticFieldSet loop:none 51 // 52 /// CHECK-START: int Main.unrollLV() instruction_simplifier$after_bce (after) 53 /// CHECK-DAG: <<Int1:i\d+>> IntConstant 187 loop:none 54 /// CHECK-DAG: <<Int2:i\d+>> IntConstant 12 loop:none 55 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int1>>] loop:none 56 /// CHECK-DAG: Return [<<Int2>>] loop:none 57 // 58 /// CHECK-START: int Main.unrollLV() loop_optimization (after) 59 /// CHECK-NOT: Phi unrollLV()60 public static int unrollLV() { 61 int i; 62 for (i = 11; i < 12; i++) { 63 sA = 17 * i; 64 } 65 return i; 66 } 67 68 /// CHECK-START: void Main.unrollNest() loop_optimization (before) 69 /// CHECK-DAG: SuspendCheck loop:none 70 /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none 71 /// CHECK-DAG: SuspendCheck loop:<<Loop1>> outer_loop:none 72 /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 73 /// CHECK-DAG: SuspendCheck loop:<<Loop2>> outer_loop:<<Loop1>> 74 /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 75 /// CHECK-DAG: SuspendCheck loop:<<Loop3>> outer_loop:<<Loop2>> 76 /// CHECK-DAG: StaticFieldSet loop:<<Loop3>> outer_loop:<<Loop2>> 77 // 78 /// CHECK-START: void Main.unrollNest() loop_optimization (after) 79 /// CHECK-DAG: StaticFieldSet loop:none 80 /// CHECK-DAG: SuspendCheck loop:none 81 /// CHECK-NOT: SuspendCheck 82 // 83 /// CHECK-START: void Main.unrollNest() instruction_simplifier$after_bce (after) 84 /// CHECK-DAG: <<Int:i\d+>> IntConstant 6 loop:none 85 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int>>] loop:none 86 // 87 /// CHECK-START: void Main.unrollNest() loop_optimization (after) 88 /// CHECK-NOT: Phi unrollNest()89 public static void unrollNest() { 90 // Unrolling each loop in turn ultimately removes the complete nest! 91 for (int i = 4; i < 5; i++) { 92 for (int j = 5; j < 6; j++) { 93 for (int k = 6; k < 7; k++) { 94 sA = k; 95 } 96 } 97 } 98 } 99 100 // 101 // Verifier. 102 // 103 main(String[] args)104 public static void main(String[] args) { 105 unroll(); 106 expectEquals(68, sA); 107 expectEquals(12, unrollLV()); 108 expectEquals(187, sA); 109 unrollNest(); 110 expectEquals(6, sA); 111 System.out.println("passed"); 112 } 113 expectEquals(int expected, int result)114 private static void expectEquals(int expected, int result) { 115 if (expected != result) { 116 throw new Error("Expected: " + expected + ", found: " + result); 117 } 118 } 119 } 120