Merge "Only inline constructors if the receiver remains the this value."
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 8ae2147..b698fc5 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
@@ -50,7 +50,9 @@
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.InvokeNewArray;
import com.android.tools.r8.ir.code.InvokeVirtual;
+import com.android.tools.r8.ir.code.JumpInstruction;
import com.android.tools.r8.ir.code.MemberType;
+import com.android.tools.r8.ir.code.Move;
import com.android.tools.r8.ir.code.MoveType;
import com.android.tools.r8.ir.code.NewArrayEmpty;
import com.android.tools.r8.ir.code.NewArrayFilledData;
@@ -61,6 +63,7 @@
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.code.Switch;
import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.code.Xor;
import com.android.tools.r8.ir.conversion.OptimizationFeedback;
import com.android.tools.r8.ir.optimize.SwitchUtils.EnumSwitchInfo;
import com.android.tools.r8.utils.InternalOptions;
@@ -1545,7 +1548,7 @@
// First rewrite zero comparison.
rewriteIfWithConstZero(block);
- if (simplifyKnownBooleanCondition(dominator, block)) {
+ if (simplifyKnownBooleanCondition(code, dominator, block)) {
continue;
}
@@ -1608,8 +1611,19 @@
*
* which can be replaced by a fallthrough and the phi value can be replaced
* with the boolean value itself.
+ *
+ * We also consider the forms:
+ *
+ * ifeqz booleanValue ifnez booleanValue
+ * / \ / \
+ * \ / \ /
+ * phi(1, 0) phi(0, 1)
+ *
+ * which can be replaced by a fallthrough and the phi value can be replaced
+ * by an xor instruction which is smaller.
*/
- private boolean simplifyKnownBooleanCondition(DominatorTree dominator, BasicBlock block) {
+ private boolean simplifyKnownBooleanCondition(IRCode code, DominatorTree dominator,
+ BasicBlock block) {
If theIf = block.exit().asIf();
Value testValue = theIf.inValues().get(0);
if (theIf.isZeroTest() && testValue.knownToBeBoolean()) {
@@ -1639,6 +1653,19 @@
falseNumber.isIntegerZero())) {
phi.replaceUsers(testValue);
deadPhis++;
+ } else if ((theIf.getType() == Type.NE &&
+ trueNumber.isIntegerZero() &&
+ falseNumber.isIntegerOne()) ||
+ (theIf.getType() == Type.EQ &&
+ trueNumber.isIntegerOne() &&
+ falseNumber.isIntegerZero())) {
+ Value newOutValue = code.createValue(phi.outType(), phi.getLocalInfo());
+ phi.replaceUsers(newOutValue);
+ Instruction newInstruction = new Xor(NumericType.INT, newOutValue, testValue,
+ trueNumber.isIntegerOne() ? trueValue : falseValue);
+ newInstruction.setBlock(phi.getBlock());
+ phi.getBlock().getInstructions().add(0, newInstruction);
+ deadPhis++;
}
}
}
diff --git a/src/test/java/com/android/tools/r8/jasmin/Regress63598979.java b/src/test/java/com/android/tools/r8/jasmin/Regress63598979.java
new file mode 100644
index 0000000..091a43a
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/jasmin/Regress63598979.java
@@ -0,0 +1,120 @@
+// Copyright (c) 2017, 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.jasmin;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+
+public class Regress63598979 extends JasminTestBase {
+
+ @Test
+ public void testSimplifyIf() throws Exception {
+ JasminBuilder builder = new JasminBuilder();
+ JasminBuilder.ClassBuilder clazz = builder.addClass("Test");
+
+ clazz.addStaticMethod("test1", ImmutableList.of("Z"), "Z",
+ ".limit stack 2",
+ ".limit locals 2",
+ " iload 0",
+ " ifne L2",
+ "L1:",
+ " iconst_1",
+ " goto L3",
+ "L2:",
+ " iconst_0",
+ "L3:",
+ " ireturn");
+
+ clazz.addStaticMethod("test2", ImmutableList.of("Z"), "Z",
+ ".limit stack 2",
+ ".limit locals 2",
+ " iload 0",
+ " ifne L2",
+ "L1:",
+ " iconst_0",
+ " goto L3",
+ "L2:",
+ " iconst_1",
+ "L3:",
+ " ireturn");
+
+ clazz.addStaticMethod("test3", ImmutableList.of("Z"), "Z",
+ ".limit stack 2",
+ ".limit locals 2",
+ " iload 0",
+ " ifeq L2",
+ "L1:",
+ " iconst_0",
+ " goto L3",
+ "L2:",
+ " iconst_1",
+ "L3:",
+ " ireturn");
+
+
+ clazz.addStaticMethod("test4", ImmutableList.of("Z"), "Z",
+ ".limit stack 2",
+ ".limit locals 2",
+ " iload 0",
+ " ifeq L2",
+ "L1:",
+ " iconst_1",
+ " goto L3",
+ "L2:",
+ " iconst_0",
+ "L3:",
+ " ireturn");
+
+ clazz.addMainMethod(
+ ".limit stack 2",
+ ".limit locals 1",
+ " getstatic java/lang/System/out Ljava/io/PrintStream;",
+ " iconst_0",
+ " invokestatic Test/test1(Z)Z",
+ " invokestatic java/lang/Boolean/toString(Z)Ljava/lang/String;",
+ " invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+ " getstatic java/lang/System/out Ljava/io/PrintStream;",
+ " iconst_1",
+ " invokestatic Test/test1(Z)Z",
+ " invokestatic java/lang/Boolean/toString(Z)Ljava/lang/String;",
+ " invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+ " getstatic java/lang/System/out Ljava/io/PrintStream;",
+ " iconst_0",
+ " invokestatic Test/test2(Z)Z",
+ " invokestatic java/lang/Boolean/toString(Z)Ljava/lang/String;",
+ " invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+ " getstatic java/lang/System/out Ljava/io/PrintStream;",
+ " iconst_1",
+ " invokestatic Test/test2(Z)Z",
+ " invokestatic java/lang/Boolean/toString(Z)Ljava/lang/String;",
+ " invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+ " getstatic java/lang/System/out Ljava/io/PrintStream;",
+ " iconst_0",
+ " invokestatic Test/test3(Z)Z",
+ " invokestatic java/lang/Boolean/toString(Z)Ljava/lang/String;",
+ " invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+ " getstatic java/lang/System/out Ljava/io/PrintStream;",
+ " iconst_1",
+ " invokestatic Test/test3(Z)Z",
+ " invokestatic java/lang/Boolean/toString(Z)Ljava/lang/String;",
+ " invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+ " getstatic java/lang/System/out Ljava/io/PrintStream;",
+ " iconst_0",
+ " invokestatic Test/test4(Z)Z",
+ " invokestatic java/lang/Boolean/toString(Z)Ljava/lang/String;",
+ " invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+ " getstatic java/lang/System/out Ljava/io/PrintStream;",
+ " iconst_1",
+ " invokestatic Test/test4(Z)Z",
+ " invokestatic java/lang/Boolean/toString(Z)Ljava/lang/String;",
+ " invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
+ " return");
+
+ String expected = runOnJava(builder, clazz.name);
+ String artResult = runOnArtD8(builder, clazz.name);
+ assertEquals(expected, artResult);
+ }
+}
diff --git a/tools/notify.py b/tools/notify.py
new file mode 100644
index 0000000..f7ae50e
--- /dev/null
+++ b/tools/notify.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# Copyright (c) 2017, 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.
+
+try:
+ import gi
+ from gi.repository import Notify
+ Notify.init("R8 build tools")
+
+ def notify(message):
+ try:
+ Notify.Notification.new("R8 build tools", message).show()
+ except:
+ return
+
+except ImportError:
+ def notify(message):
+ return
diff --git a/tools/test.py b/tools/test.py
index ab4b0d6..c0a1e02 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -14,6 +14,7 @@
import sys
import utils
import uuid
+import notify
ALL_ART_VMS = ["default", "7.0.0", "6.0.1", "5.1.1"]
BUCKET = 'r8-test-results'
@@ -149,4 +150,9 @@
return return_code
if __name__ == '__main__':
- sys.exit(Main())
+ return_code = Main()
+ if return_code != 0:
+ notify.notify("Tests failed.")
+ else:
+ notify.notify("Tests passed.")
+ sys.exit(return_code)