Merge "Revert "Revert "ARM: VIXL32: Add an initial code generator that passes codegen_tests."""
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 4ca0600..b787888 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1577,6 +1577,18 @@
return;
}
+ if ((input_cst != nullptr) && input_cst->IsOne()
+ && input_other->GetType() == Primitive::kPrimBoolean) {
+ // Replace code looking like
+ // XOR dst, src, 1
+ // with
+ // BOOLEAN_NOT dst, src
+ HBooleanNot* boolean_not = new (GetGraph()->GetArena()) HBooleanNot(input_other);
+ instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, boolean_not);
+ RecordSimplification();
+ return;
+ }
+
if ((input_cst != nullptr) && AreAllBitsSet(input_cst)) {
// Replace code looking like
// XOR dst, src, 0xFFF...FF
diff --git a/test/005-annotations/build b/test/005-annotations/build
index 216843d..8b9f550 100644
--- a/test/005-annotations/build
+++ b/test/005-annotations/build
@@ -30,7 +30,8 @@
if [ ${USE_JACK} = "true" ]; then
jar cf classes.jill.jar -C classes .
- ${JACK} --import classes.jill.jar --output-dex .
+ # Jack needs to emit annotations with CLASS retention.
+ ${JACK} -D jack.dex.annotation.class-retention=true --import classes.jill.jar --output-dex .
else
if [ ${NEED_DEX} = "true" ]; then
${DX} -JXmx256m --debug --dex --output=classes.dex classes
diff --git a/test/458-checker-instruct-simplification/src/Main.java b/test/458-checker-instruct-simplification/src/Main.java
index 5b14735..e71a0e1 100644
--- a/test/458-checker-instruct-simplification/src/Main.java
+++ b/test/458-checker-instruct-simplification/src/Main.java
@@ -1178,16 +1178,28 @@
* remove the second.
*/
+ /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier (before)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Result:z\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: <<NotResult:i\d+>> Xor [<<Result>>,<<Const1>>]
+ /// CHECK-DAG: Return [<<NotResult>>]
+
+ /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier (after)
+ /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<Result:z\d+>> InvokeStaticOrDirect
+ /// CHECK-DAG: <<NotResult:z\d+>> BooleanNot [<<Result>>]
+ /// CHECK-DAG: Return [<<NotResult>>]
+
/// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier$after_bce (before)
/// CHECK-DAG: <<Arg:z\d+>> ParameterValue
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- /// CHECK-DAG: <<NotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<Arg>>]
- /// CHECK-DAG: <<NotNotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<NotArg>>]
+ /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
+ /// CHECK-DAG: <<NotNotArg:z\d+>> BooleanNot [<<NotArg>>]
/// CHECK-DAG: Return [<<NotNotArg>>]
/// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier$after_bce (after)
/// CHECK-DAG: <<Arg:z\d+>> ParameterValue
+ /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
/// CHECK-DAG: Return [<<Arg>>]
public static boolean NegateValue(boolean arg) {
diff --git a/test/463-checker-boolean-simplifier/smali/BooleanNotDx.smali b/test/463-checker-boolean-simplifier/smali/BooleanNotDx.smali
new file mode 100644
index 0000000..765d0eb
--- /dev/null
+++ b/test/463-checker-boolean-simplifier/smali/BooleanNotDx.smali
@@ -0,0 +1,65 @@
+# 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.
+
+.class public LBooleanNotSmali;
+.super Ljava/lang/Object;
+
+#
+# Elementary test negating a boolean. Verifies that blocks are merged and
+# empty branches removed.
+#
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (before)
+## CHECK-DAG: <<Param:z\d+>> ParameterValue
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+## CHECK-DAG: If [<<Param>>]
+## CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0>>,<<Const1>>]
+## CHECK-DAG: Return [<<Phi>>]
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (before)
+## CHECK: Goto
+## CHECK: Goto
+## CHECK: Goto
+## CHECK-NOT: Goto
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (after)
+## CHECK-DAG: <<Param:z\d+>> ParameterValue
+## CHECK-DAG: <<Const0:i\d+>> IntConstant 0
+## CHECK-DAG: <<Const1:i\d+>> IntConstant 1
+## CHECK-DAG: <<NotParam:i\d+>> Select [<<Const1>>,<<Const0>>,<<Param>>]
+## CHECK-DAG: Return [<<NotParam>>]
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (after)
+## CHECK-NOT: If
+## CHECK-NOT: Phi
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (after)
+## CHECK: Goto
+## CHECK-NOT: Goto
+
+.method public static BooleanNot(Z)Z
+ .registers 2
+
+ if-eqz v1, :true_start
+ const/4 v0, 0x0
+
+:return_start
+ return v0
+
+:true_start
+ const/4 v0, 0x1
+ goto :return_start
+
+.end method
diff --git a/test/463-checker-boolean-simplifier/src/Main.java b/test/463-checker-boolean-simplifier/src/Main.java
index f0fe1b1..9368488 100644
--- a/test/463-checker-boolean-simplifier/src/Main.java
+++ b/test/463-checker-boolean-simplifier/src/Main.java
@@ -32,42 +32,14 @@
}
}
- /*
- * Elementary test negating a boolean. Verifies that blocks are merged and
- * empty branches removed.
- */
-
- /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (before)
- /// CHECK-DAG: <<Param:z\d+>> ParameterValue
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- /// CHECK-DAG: If [<<Param>>]
- /// CHECK-DAG: <<Phi:i\d+>> Phi [<<Const0>>,<<Const1>>]
- /// CHECK-DAG: Return [<<Phi>>]
-
- /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (before)
- /// CHECK: Goto
- /// CHECK: Goto
- /// CHECK: Goto
- /// CHECK-NOT: Goto
-
- /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (after)
- /// CHECK-DAG: <<Param:z\d+>> ParameterValue
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
- /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- /// CHECK-DAG: <<NotParam:i\d+>> Select [<<Const1>>,<<Const0>>,<<Param>>]
- /// CHECK-DAG: Return [<<NotParam>>]
-
- /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (after)
- /// CHECK-NOT: If
- /// CHECK-NOT: Phi
-
- /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (after)
- /// CHECK: Goto
- /// CHECK-NOT: Goto
-
- public static boolean BooleanNot(boolean x) {
- return !x;
+ // Invoke a method written in smali that implements the boolean ! operator. This method
+ // uses the if/else pattern generated by dx (while Jack generates a different pattern).
+ // Since this method is in a smali-generated class, we invoke it through reflection.
+ public static boolean SmaliBooleanNot(boolean x) throws Exception {
+ Class<?> c = Class.forName("BooleanNotSmali");
+ java.lang.reflect.Method method = c.getMethod("BooleanNot", boolean.class);
+ Object retValue = method.invoke(null, new Object[] { Boolean.valueOf(x) });
+ return ((Boolean) retValue).booleanValue();
}
/*
@@ -357,9 +329,9 @@
return x ? 42 : (write_field = 43);
}
- public static void main(String[] args) {
- assertBoolEquals(false, BooleanNot(true));
- assertBoolEquals(true, BooleanNot(false));
+ public static void main(String[] args) throws Exception {
+ assertBoolEquals(false, SmaliBooleanNot(true));
+ assertBoolEquals(true, SmaliBooleanNot(false));
assertBoolEquals(true, GreaterThan(10, 5));
assertBoolEquals(false, GreaterThan(10, 10));
assertBoolEquals(false, GreaterThan(5, 10));
diff --git a/test/565-checker-doublenegbitwise/src/Main.java b/test/565-checker-doublenegbitwise/src/Main.java
index 811c280..5ccc648 100644
--- a/test/565-checker-doublenegbitwise/src/Main.java
+++ b/test/565-checker-doublenegbitwise/src/Main.java
@@ -70,20 +70,19 @@
* same pass.
*/
- /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (before)
+ /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier (before)
/// CHECK: <<P1:z\d+>> ParameterValue
/// CHECK: <<P2:z\d+>> ParameterValue
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- /// CHECK: <<Select1:i\d+>> Select [<<Const1>>,<<Const0>>,<<P1>>]
- /// CHECK: <<Select2:i\d+>> Select [<<Const1>>,<<Const0>>,<<P2>>]
- /// CHECK: <<And:i\d+>> And [<<Select2>>,<<Select1>>]
+ /// CHECK-DAG: <<NotP1:i\d+>> Xor [<<P1>>,<<Const1>>]
+ /// CHECK-DAG: <<NotP2:i\d+>> Xor [<<P2>>,<<Const1>>]
+ /// CHECK: <<And:i\d+>> And [<<NotP1>>,<<NotP2>>]
/// CHECK: Return [<<And>>]
- /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (after)
+ /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier (after)
/// CHECK: <<Cond1:z\d+>> ParameterValue
/// CHECK: <<Cond2:z\d+>> ParameterValue
- /// CHECK: <<Or:i\d+>> Or [<<Cond2>>,<<Cond1>>]
+ /// CHECK: <<Or:i\d+>> Or [<<Cond1>>,<<Cond2>>]
/// CHECK: <<BooleanNot:z\d+>> BooleanNot [<<Or>>]
/// CHECK: Return [<<BooleanNot>>]
@@ -138,20 +137,19 @@
* same pass.
*/
- /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (before)
+ /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier (before)
/// CHECK: <<P1:z\d+>> ParameterValue
/// CHECK: <<P2:z\d+>> ParameterValue
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- /// CHECK: <<Select1:i\d+>> Select [<<Const1>>,<<Const0>>,<<P1>>]
- /// CHECK: <<Select2:i\d+>> Select [<<Const1>>,<<Const0>>,<<P2>>]
- /// CHECK: <<Or:i\d+>> Or [<<Select2>>,<<Select1>>]
+ /// CHECK: <<NotP1:i\d+>> Xor [<<P1>>,<<Const1>>]
+ /// CHECK: <<NotP2:i\d+>> Xor [<<P2>>,<<Const1>>]
+ /// CHECK: <<Or:i\d+>> Or [<<NotP1>>,<<NotP2>>]
/// CHECK: Return [<<Or>>]
- /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (after)
+ /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier (after)
/// CHECK: <<Cond1:z\d+>> ParameterValue
/// CHECK: <<Cond2:z\d+>> ParameterValue
- /// CHECK: <<And:i\d+>> And [<<Cond2>>,<<Cond1>>]
+ /// CHECK: <<And:i\d+>> And [<<Cond1>>,<<Cond2>>]
/// CHECK: <<BooleanNot:z\d+>> BooleanNot [<<And>>]
/// CHECK: Return [<<BooleanNot>>]
@@ -246,20 +244,19 @@
* same pass.
*/
- /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (before)
+ /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier (before)
/// CHECK: <<P1:z\d+>> ParameterValue
/// CHECK: <<P2:z\d+>> ParameterValue
- /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
- /// CHECK: <<Select1:i\d+>> Select [<<Const1>>,<<Const0>>,<<P1>>]
- /// CHECK: <<Select2:i\d+>> Select [<<Const1>>,<<Const0>>,<<P2>>]
- /// CHECK: <<Xor:i\d+>> Xor [<<Select2>>,<<Select1>>]
+ /// CHECK: <<NotP1:i\d+>> Xor [<<P1>>,<<Const1>>]
+ /// CHECK: <<NotP2:i\d+>> Xor [<<P2>>,<<Const1>>]
+ /// CHECK: <<Xor:i\d+>> Xor [<<NotP1>>,<<NotP2>>]
/// CHECK: Return [<<Xor>>]
- /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (after)
+ /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier (after)
/// CHECK: <<Cond1:z\d+>> ParameterValue
/// CHECK: <<Cond2:z\d+>> ParameterValue
- /// CHECK: <<Xor:i\d+>> Xor [<<Cond2>>,<<Cond1>>]
+ /// CHECK: <<Xor:i\d+>> Xor [<<Cond1>>,<<Cond2>>]
/// CHECK: Return [<<Xor>>]
/// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (after)