Test NewArrayWithData length rewrite
Bug: 202365761
Change-Id: I9edee6852f119406f549a046d452fde9b81e4836
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 293635b..07ba0ce 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -189,7 +189,7 @@
this.appView = appView;
this.options = appView.options();
this.printer = printer;
- this.codeRewriter = new CodeRewriter(appView, this);
+ this.codeRewriter = new CodeRewriter(appView);
this.constantCanonicalizer = new ConstantCanonicalizer(codeRewriter);
this.classInitializerDefaultsOptimization =
new ClassInitializerDefaultsOptimization(appView, this);
@@ -1141,7 +1141,7 @@
String previous = printMethod(code, "Initial IR (SSA)", null);
if (options.testing.irModifier != null) {
- options.testing.irModifier.accept(code);
+ options.testing.irModifier.accept(code, appView);
}
if (options.canHaveArtStringNewInitBug()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 71a8249..cdc2c6e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -85,7 +85,6 @@
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.code.Xor;
-import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.conversion.MethodProcessor;
import com.android.tools.r8.ir.optimize.UtilityMethodsForCodeOptimizations.UtilityMethodForCodeOptimizations;
import com.android.tools.r8.ir.optimize.controlflow.SwitchCaseAnalyzer;
@@ -156,15 +155,12 @@
private static final int STOP_SHARED_CONSTANT_THRESHOLD = 50;
private static final int SELF_RECURSION_LIMIT = 4;
- public final IRConverter converter;
-
private final AppView<?> appView;
private final DexItemFactory dexItemFactory;
private final InternalOptions options;
- public CodeRewriter(AppView<?> appView, IRConverter converter) {
+ public CodeRewriter(AppView<?> appView) {
this.appView = appView;
- this.converter = converter;
this.options = appView.options();
this.dexItemFactory = appView.dexItemFactory();
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 1def57e..2605507 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1647,7 +1647,7 @@
public boolean noLocalsTableOnInput = false;
public boolean forceNameReflectionOptimization = false;
public boolean enableNarrowAndWideningingChecksInD8 = false;
- public Consumer<IRCode> irModifier = null;
+ public BiConsumer<IRCode, AppView<?>> irModifier = null;
public Consumer<IRCode> inlineeIrModifier = null;
public int basicBlockMuncherIterationLimit = NO_LIMIT;
public boolean dontReportFailingCheckDiscarded = false;
diff --git a/src/test/java/com/android/tools/r8/cf/TryRangeTestRunner.java b/src/test/java/com/android/tools/r8/cf/TryRangeTestRunner.java
index aec1329..8f5dc82 100644
--- a/src/test/java/com/android/tools/r8/cf/TryRangeTestRunner.java
+++ b/src/test/java/com/android/tools/r8/cf/TryRangeTestRunner.java
@@ -13,6 +13,7 @@
import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfStackInstruction;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
@@ -84,7 +85,7 @@
assert instructions.get(index + 4) instanceof CfStackInstruction;
}
- private void processIR(IRCode code) {
+ private void processIR(IRCode code, AppView<?> appView) {
if (!code.method().qualifiedName().equals(TryRangeTestLimitRange.class.getName() + ".main")) {
return;
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/ClassInlinerPhiDirectUserAfterInlineTest.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/ClassInlinerPhiDirectUserAfterInlineTest.java
index 6001549..5cea9fa 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/ClassInlinerPhiDirectUserAfterInlineTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/ClassInlinerPhiDirectUserAfterInlineTest.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
@@ -86,6 +87,10 @@
});
}
+ private void modifyIr(IRCode irCode, AppView<?> appView) {
+ modifyIr(irCode);
+ }
+
private void modifyIr(IRCode irCode) {
if (irCode.context().getReference().qualifiedName().equals(A.class.getTypeName() + ".foo")) {
assertEquals(7, irCode.blocks.size());
diff --git a/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayLengthRewriteTest.java b/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayLengthRewriteTest.java
index 87ae7f4..40d6dbf 100644
--- a/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayLengthRewriteTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayLengthRewriteTest.java
@@ -3,6 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.rewrite.arrays;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
@@ -17,10 +21,6 @@
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
-
@RunWith(Parameterized.class)
public class ArrayLengthRewriteTest extends TestBase {
@Parameters(name = "{0}, debug = {1}")
@@ -62,7 +62,7 @@
assumeTrue(parameters.isDexRuntime());
testForD8()
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.setMode(debugMode ? CompilationMode.DEBUG : CompilationMode.RELEASE)
.addProgramClasses(Main.class)
.run(parameters.getRuntime(), Main.class)
@@ -72,7 +72,7 @@
@Test public void r8() throws Exception {
testForR8(parameters.getBackend())
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.setMode(debugMode ? CompilationMode.DEBUG : CompilationMode.RELEASE)
.addProgramClasses(Main.class)
.addKeepMainRule(Main.class)
diff --git a/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayWithDataLengthRewriteTest.java b/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayWithDataLengthRewriteTest.java
new file mode 100644
index 0000000..4a76a6a
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/rewrite/arrays/ArrayWithDataLengthRewriteTest.java
@@ -0,0 +1,85 @@
+// 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.rewrite.arrays;
+
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.graph.AppView;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.optimize.CodeRewriter;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class ArrayWithDataLengthRewriteTest extends TestBase {
+ @Parameters(name = "{0}")
+ public static Iterable<?> data() {
+ return buildParameters(getTestParameters().withDexRuntimes().withAllApiLevels().build());
+ }
+
+ private final TestParameters parameters;
+
+ public ArrayWithDataLengthRewriteTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ private static final String[] expectedOutput = {"3"};
+
+ @Test
+ public void d8() throws Exception {
+ testForD8()
+ .setMinApi(parameters.getApiLevel())
+ .setMode(CompilationMode.RELEASE)
+ .addProgramClasses(Main.class)
+ .addOptionsModification(opt -> opt.testing.irModifier = this::transformArray)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(expectedOutput)
+ .inspect(this::assertNoArrayLength);
+ }
+
+ @Test
+ public void r8() throws Exception {
+ testForR8(parameters.getBackend())
+ .setMinApi(parameters.getRuntime())
+ .addProgramClasses(Main.class)
+ .addOptionsModification(opt -> opt.testing.irModifier = this::transformArray)
+ .addKeepMainRule(Main.class)
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(expectedOutput)
+ .inspect(this::assertNoArrayLength);
+ }
+
+ private void transformArray(IRCode irCode, AppView<?> appView) {
+ if (irCode.context().getReference().getName().toString().contains("main")) {
+ new CodeRewriter(appView).simplifyArrayConstruction(irCode);
+ assertTrue(irCode.streamInstructions().anyMatch(Instruction::isNewArrayFilledData));
+ }
+ }
+
+ private void assertNoArrayLength(CodeInspector inspector) {
+ ClassSubject mainClass = inspector.clazz(Main.class);
+ assertTrue(mainClass.isPresent());
+ assertTrue(
+ mainClass.mainMethod().streamInstructions().noneMatch(InstructionSubject::isArrayLength));
+ }
+
+ public static final class Main {
+ public static void main(String[] args) {
+ int[] ints = new int[3];
+ ints[0] = 5;
+ ints[1] = 6;
+ ints[2] = 1;
+ System.out.println(ints.length);
+ }
+ }
+}