From 146d12f68d3d0d4a9d5cb35eef6085c8b200670b Mon Sep 17 00:00:00 2001 From: mikaelpeltier Date: Tue, 7 Jul 2015 10:11:25 +0200 Subject: Remove unused definition only for synthetic variables Bug: 18911912 Change-Id: I2530afc929431ccc4229daac5cbd218fc1b499b0 (cherry picked from commit d4f6789ff777d219c3411aec1104df17dba85eba) --- jack-tests/tests/com/android/jack/AllTests.java | 2 + .../optimizations/unuseddef/UnusedDefTest.java | 71 ++++++++++++++++++++++ .../unuseddef/test001/jack/Test001.java | 29 +++++++++ .../optimizations/UnusedDefinitionRemover.java | 2 +- 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 jack-tests/tests/com/android/jack/optimizations/unuseddef/UnusedDefTest.java create mode 100644 jack-tests/tests/com/android/jack/optimizations/unuseddef/test001/jack/Test001.java diff --git a/jack-tests/tests/com/android/jack/AllTests.java b/jack-tests/tests/com/android/jack/AllTests.java index 47b7a08..f1e39bd 100644 --- a/jack-tests/tests/com/android/jack/AllTests.java +++ b/jack-tests/tests/com/android/jack/AllTests.java @@ -47,6 +47,7 @@ import com.android.jack.nopackage.NoPackageTests; import com.android.jack.opcodes.OpcodesTests; import com.android.jack.optimizations.exprsimplifier.ExprsimplifierTests; import com.android.jack.optimizations.notsimplifier.NotsimplifierTests; +import com.android.jack.optimizations.unuseddef.UnusedDefTest; import com.android.jack.optimizations.uselesscopy.UselessVariableCopyTest; import com.android.jack.order.OrderTests; import com.android.jack.preprocessor.PreProcessorTests; @@ -134,6 +135,7 @@ import org.junit.runners.Suite.SuiteClasses; TryfinallyTests.class, TypeTests.class, UnaryTests.class, + UnusedDefTest.class, UselessVariableCopyTest.class, VerifyTests.class, WithPhantomTests.class, diff --git a/jack-tests/tests/com/android/jack/optimizations/unuseddef/UnusedDefTest.java b/jack-tests/tests/com/android/jack/optimizations/unuseddef/UnusedDefTest.java new file mode 100644 index 0000000..3fda172 --- /dev/null +++ b/jack-tests/tests/com/android/jack/optimizations/unuseddef/UnusedDefTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 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. + */ + +package com.android.jack.optimizations.unuseddef; + +import com.android.jack.TestTools; +import com.android.jack.test.junit.KnownIssue; +import com.android.jack.test.toolchain.AbstractTestTools; +import com.android.jack.test.toolchain.JackBasedToolchain; + +import junit.framework.Assert; + +import org.jf.dexlib.CodeItem; +import org.jf.dexlib.DexFile; +import org.jf.dexlib.Code.Instruction; +import org.jf.dexlib.Code.Opcode; +import org.junit.Test; + +import java.io.File; + +import javax.annotation.Nonnull; + +public class UnusedDefTest { + + /** + * Verify that generated dex contains a 'const_4' instruction corresponding to 'o = null' + * instruction. + */ + @Test + @KnownIssue + public void test001() throws Exception { + File out = AbstractTestTools.createTempDir(); + File outDex = new File(out, "classes.dex"); + JackBasedToolchain toolchain = AbstractTestTools.getCandidateToolchain(JackBasedToolchain.class); + toolchain.disableDxOptimizations(); + toolchain.addToClasspath(toolchain.getDefaultBootClasspath()) + .srcToExe(out, /* zipFile = */ false, + AbstractTestTools.getTestRootDir("com.android.jack.optimizations.unuseddef.test001.jack")); + + DexFile dexFile = new DexFile(outDex); + CodeItem ci = + TestTools.getEncodedMethod(dexFile, + "Lcom/android/jack/optimizations/unuseddef/test001/jack/Test001;", "test", + "()V").codeItem; + + Assert.assertTrue(hasOpcode(ci, Opcode.CONST_4)); + } + + private boolean hasOpcode(@Nonnull CodeItem codeItem, @Nonnull Opcode opcode) { + for (Instruction inst : codeItem.getInstructions()) { + if (inst.opcode == opcode) { + return true; + } + } + return false; + } + +} diff --git a/jack-tests/tests/com/android/jack/optimizations/unuseddef/test001/jack/Test001.java b/jack-tests/tests/com/android/jack/optimizations/unuseddef/test001/jack/Test001.java new file mode 100644 index 0000000..ce53880 --- /dev/null +++ b/jack-tests/tests/com/android/jack/optimizations/unuseddef/test001/jack/Test001.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015 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. + */ + +package com.android.jack.optimizations.unuseddef.test001.jack; + +public class Test001 { + + /** + * Check that 'o = null' always exists in generated code. + */ + public void test() { + Object o = new Object(); + o = null; + } + +} diff --git a/jack/src/com/android/jack/optimizations/UnusedDefinitionRemover.java b/jack/src/com/android/jack/optimizations/UnusedDefinitionRemover.java index cfc65d2..9706c0f 100644 --- a/jack/src/com/android/jack/optimizations/UnusedDefinitionRemover.java +++ b/jack/src/com/android/jack/optimizations/UnusedDefinitionRemover.java @@ -79,7 +79,7 @@ public class UnusedDefinitionRemover implements RunnableSchedulable { && !rhs.canThrow()) { DefinitionMarker dm = binary.getMarker(DefinitionMarker.class); - if (dm != null && dm.isUnused()) { + if (dm != null && dm.isUnused() && dm.getDefinedVariable().isSynthetic()) { assert !(binary.getLhs() instanceof JFieldRef || binary.getLhs() instanceof JArrayRef); removeUnusedDefinition((JAsgOperation) binary); } -- cgit v1.1