blob: 6374d0b14c9dfb97d681cd02f20ae23901257735 [file] [log] [blame]
// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize.loops;
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class LoopWith0Iterations extends TestBase {
private final TestParameters parameters;
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public LoopWith0Iterations(TestParameters parameters) {
this.parameters = parameters;
}
@Test
public void testLoopRemoved() throws Exception {
testForR8(parameters.getBackend())
.setMinApi(parameters)
.addProgramClasses(Main.class)
.addKeepMainRule(Main.class)
.enableInliningAnnotations()
.compile()
.inspect(this::assertLoopRemoved)
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines(
"loop0fori",
"loop0for",
"loop0foriAbstractValue",
"loop0forAbstractValue",
"loop0foriArgument",
"loop0forArgument");
}
private void assertLoopRemoved(CodeInspector inspector) {
inspector
.clazz(Main.class)
.allMethods(m -> !m.getOriginalMethodName().contains("Argument"))
.forEach(
m ->
assertTrue(
m.streamInstructions()
.noneMatch(i -> i.isArrayLength() || i.isGoto() || i.isIf())));
}
public static class Main {
public static void main(String[] args) {
loop0fori();
loop0for();
loop0foriAbstractValue();
loop0forAbstractValue();
loop0foriArgument(new Object[0]);
loop0forArgument(new Object[0]);
}
@NeverInline
public static void loop0fori() {
Object[] objects = new Object[0];
for (int i = 0; i < objects.length; i++) {
System.out.println("object");
}
System.out.println("loop0fori");
}
@NeverInline
public static void loop0for() {
Object[] objects = new Object[0];
for (Object object : objects) {
System.out.println("object");
}
System.out.println("loop0for");
}
@NeverInline
public static Object[] getObjectArray0() {
return new Object[0];
}
@NeverInline
public static void loop0foriAbstractValue() {
Object[] objects = getObjectArray0();
for (int i = 0; i < objects.length; i++) {
System.out.println("object");
}
System.out.println("loop0foriAbstractValue");
}
@NeverInline
public static void loop0forAbstractValue() {
Object[] objects = getObjectArray0();
for (Object object : objects) {
System.out.println("object");
}
System.out.println("loop0forAbstractValue");
}
@NeverInline
public static void loop0foriArgument(Object[] objects) {
for (int i = 0; i < objects.length; i++) {
System.out.println("object");
}
System.out.println("loop0foriArgument");
}
@NeverInline
public static void loop0forArgument(Object[] objects) {
for (Object object : objects) {
System.out.println("object");
}
System.out.println("loop0forArgument");
}
}
}