/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // // Test on loop unrolling. Removes loop control overhead (including suspend // checks) and exposes more opportunities for constant folding. // public class Main { static int sA = 0; /// CHECK-START: void Main.unroll() loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: StaticFieldSet loop:<<Loop>> // /// CHECK-START: void Main.unroll() loop_optimization (after) /// CHECK-DAG: StaticFieldSet loop:none // /// CHECK-START: void Main.unroll() instruction_simplifier$after_bce (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 68 loop:none /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int>>] loop:none // /// CHECK-START: void Main.unroll() loop_optimization (after) /// CHECK-NOT: Phi public static void unroll() { for (int i = 4; i < 5; i++) { sA = 17 * i; } } /// CHECK-START: int Main.unrollLV() loop_optimization (before) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> /// CHECK-DAG: StaticFieldSet loop:<<Loop>> /// CHECK-DAG: Return [<<Phi>>] loop:none // /// CHECK-START: int Main.unrollLV() loop_optimization (after) /// CHECK-DAG: StaticFieldSet loop:none // /// CHECK-START: int Main.unrollLV() instruction_simplifier$after_bce (after) /// CHECK-DAG: <<Int1:i\d+>> IntConstant 187 loop:none /// CHECK-DAG: <<Int2:i\d+>> IntConstant 12 loop:none /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int1>>] loop:none /// CHECK-DAG: Return [<<Int2>>] loop:none // /// CHECK-START: int Main.unrollLV() loop_optimization (after) /// CHECK-NOT: Phi public static int unrollLV() { int i; for (i = 11; i < 12; i++) { sA = 17 * i; } return i; } /// CHECK-START: void Main.unrollNest() loop_optimization (before) /// CHECK-DAG: SuspendCheck loop:none /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none /// CHECK-DAG: SuspendCheck loop:<<Loop1>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> /// CHECK-DAG: SuspendCheck loop:<<Loop2>> outer_loop:<<Loop1>> /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> /// CHECK-DAG: SuspendCheck loop:<<Loop3>> outer_loop:<<Loop2>> /// CHECK-DAG: StaticFieldSet loop:<<Loop3>> outer_loop:<<Loop2>> // /// CHECK-START: void Main.unrollNest() loop_optimization (after) /// CHECK-DAG: StaticFieldSet loop:none /// CHECK-DAG: SuspendCheck loop:none /// CHECK-NOT: SuspendCheck // /// CHECK-START: void Main.unrollNest() instruction_simplifier$after_bce (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 6 loop:none /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<Int>>] loop:none // /// CHECK-START: void Main.unrollNest() loop_optimization (after) /// CHECK-NOT: Phi public static void unrollNest() { // Unrolling each loop in turn ultimately removes the complete nest! for (int i = 4; i < 5; i++) { for (int j = 5; j < 6; j++) { for (int k = 6; k < 7; k++) { sA = k; } } } } // // Verifier. // public static void main(String[] args) { unroll(); expectEquals(68, sA); expectEquals(12, unrollLV()); expectEquals(187, sA); unrollNest(); expectEquals(6, sA); System.out.println("passed"); } private static void expectEquals(int expected, int result) { if (expected != result) { throw new Error("Expected: " + expected + ", found: " + result); } } }