/*
|
* 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);
|
}
|
}
|
}
|