summaryrefslogtreecommitdiffstats
path: root/test/463-checker-boolean-simplifier
diff options
context:
space:
mode:
authorDavid Brazdil <dbrazdil@google.com>2015-03-16 17:31:52 +0000
committerDavid Brazdil <dbrazdil@google.com>2015-03-24 17:28:37 +0000
commit46e2a3915aa68c77426b71e95b9f3658250646b7 (patch)
tree2b0a4470b05291894db73c631fe94f0fdff8c46b /test/463-checker-boolean-simplifier
parentbce0855ca1dbb1fa226c5b6a81760272ce0b64ef (diff)
downloadart-46e2a3915aa68c77426b71e95b9f3658250646b7.zip
art-46e2a3915aa68c77426b71e95b9f3658250646b7.tar.gz
art-46e2a3915aa68c77426b71e95b9f3658250646b7.tar.bz2
ART: Boolean simplifier
The optimization recognizes the negation pattern generated by 'javac' and replaces it with a single condition. To this end, boolean values are now consistently assumed to be represented by an integer. This is a first optimization which deletes blocks from the HGraph and does so by replacing the corresponding entries with null. Hence, existing code can continue indexing the list of blocks with the block ID, but must check for null when iterating over the list. Change-Id: I7779da69cfa925c6521938ad0bcc11bc52335583
Diffstat (limited to 'test/463-checker-boolean-simplifier')
-rw-r--r--test/463-checker-boolean-simplifier/expected.txt0
-rw-r--r--test/463-checker-boolean-simplifier/info.txt1
-rw-r--r--test/463-checker-boolean-simplifier/src/Main.java174
3 files changed, 175 insertions, 0 deletions
diff --git a/test/463-checker-boolean-simplifier/expected.txt b/test/463-checker-boolean-simplifier/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/463-checker-boolean-simplifier/expected.txt
diff --git a/test/463-checker-boolean-simplifier/info.txt b/test/463-checker-boolean-simplifier/info.txt
new file mode 100644
index 0000000..9c0493a
--- /dev/null
+++ b/test/463-checker-boolean-simplifier/info.txt
@@ -0,0 +1 @@
+Tests simplification of boolean NOT in optimizing compiler.
diff --git a/test/463-checker-boolean-simplifier/src/Main.java b/test/463-checker-boolean-simplifier/src/Main.java
new file mode 100644
index 0000000..25f58b4
--- /dev/null
+++ b/test/463-checker-boolean-simplifier/src/Main.java
@@ -0,0 +1,174 @@
+/*
+* 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.
+*/
+
+public class Main {
+
+ // Note #1: `javac` flips the conditions of If statements.
+ // Note #2: In the optimizing compiler, the first input of Phi is always
+ // the fall-through path, i.e. the false branch.
+
+ public static void assertBoolEquals(boolean expected, boolean result) {
+ if (expected != result) {
+ throw new Error("Expected: " + expected + ", found: " + result);
+ }
+ }
+
+ /*
+ * Elementary test negating a boolean. Verifies that the condition is replaced,
+ * blocks merged and empty branches removed.
+ */
+
+ // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (before)
+ // CHECK-DAG: [[Param:z\d+]] ParameterValue
+ // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
+ // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
+ // CHECK-DAG: [[NotEq:z\d+]] NotEqual [ [[Param]] [[Const0]] ]
+ // CHECK-DAG: If [ [[NotEq]] ]
+ // CHECK-DAG: [[Phi:i\d+]] Phi [ [[Const1]] [[Const0]] ]
+ // CHECK-DAG: Return [ [[Phi]] ]
+
+ // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (before)
+ // CHECK: Goto
+ // CHECK: Goto
+ // CHECK: Goto
+ // CHECK-NOT: Goto
+
+ // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
+ // CHECK-DAG: [[Param:z\d+]] ParameterValue
+ // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
+ // CHECK-DAG: [[Eq:z\d+]] Equal [ [[Param]] [[Const0]] ]
+ // CHECK-DAG: Return [ [[Eq]] ]
+
+ // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
+ // CHECK-NOT: NotEqual
+ // CHECK-NOT: If
+ // CHECK-NOT: Phi
+
+ // CHECK-START: boolean Main.BooleanNot(boolean) boolean_simplifier (after)
+ // CHECK: Goto
+ // CHECK-NOT: Goto
+
+ public static boolean BooleanNot(boolean x) {
+ return !x;
+ }
+
+ /*
+ * Program which only delegates the condition, i.e. returns 1 when True
+ * and 0 when False.
+ */
+
+ // CHECK-START: boolean Main.GreaterThan(int, int) boolean_simplifier (before)
+ // CHECK-DAG: [[ParamX:i\d+]] ParameterValue
+ // CHECK-DAG: [[ParamY:i\d+]] ParameterValue
+ // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
+ // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
+ // CHECK-DAG: [[Cond:z\d+]] GreaterThan [ [[ParamX]] [[ParamY]] ]
+ // CHECK-DAG: If [ [[Cond]] ]
+ // CHECK-DAG: [[Phi:i\d+]] Phi [ [[Const0]] [[Const1]] ]
+ // CHECK-DAG: Return [ [[Phi]] ]
+
+ // CHECK-START: boolean Main.GreaterThan(int, int) boolean_simplifier (after)
+ // CHECK-DAG: [[ParamX:i\d+]] ParameterValue
+ // CHECK-DAG: [[ParamY:i\d+]] ParameterValue
+ // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
+ // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
+ // CHECK-DAG: [[Cond:z\d+]] GreaterThan [ [[ParamX]] [[ParamY]] ]
+ // CHECK-DAG: Return [ [[Cond]] ]
+
+ public static boolean GreaterThan(int x, int y) {
+ return (x <= y) ? false : true;
+ }
+
+ /*
+ * Program which negates a condition, i.e. returns 0 when True
+ * and 1 when False.
+ */
+
+ // CHECK-START: boolean Main.LessThan(int, int) boolean_simplifier (before)
+ // CHECK-DAG: [[ParamX:i\d+]] ParameterValue
+ // CHECK-DAG: [[ParamY:i\d+]] ParameterValue
+ // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
+ // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
+ // CHECK-DAG: [[Cond:z\d+]] GreaterThanOrEqual [ [[ParamX]] [[ParamY]] ]
+ // CHECK-DAG: If [ [[Cond]] ]
+ // CHECK-DAG: [[Phi:i\d+]] Phi [ [[Const1]] [[Const0]] ]
+ // CHECK-DAG: Return [ [[Phi]] ]
+
+ // CHECK-START: boolean Main.LessThan(int, int) boolean_simplifier (after)
+ // CHECK-DAG: [[ParamX:i\d+]] ParameterValue
+ // CHECK-DAG: [[ParamY:i\d+]] ParameterValue
+ // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
+ // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
+ // CHECK-DAG: [[Cond:z\d+]] LessThan [ [[ParamX]] [[ParamY]] ]
+ // CHECK-DAG: Return [ [[Cond]] ]
+
+ public static boolean LessThan(int x, int y) {
+ return x < y;
+ }
+
+ /*
+ * Program which further uses negated conditions.
+ * Note that Phis are discovered retrospectively.
+ */
+
+ // CHECK-START: boolean Main.ValuesOrdered(int, int, int) boolean_simplifier (before)
+ // CHECK-DAG: [[ParamX:i\d+]] ParameterValue
+ // CHECK-DAG: [[ParamY:i\d+]] ParameterValue
+ // CHECK-DAG: [[ParamZ:i\d+]] ParameterValue
+ // CHECK-DAG: [[Const0:i\d+]] IntConstant 0
+ // CHECK-DAG: [[Const1:i\d+]] IntConstant 1
+ // CHECK-DAG: [[CondXY:z\d+]] GreaterThan [ [[ParamX]] [[ParamY]] ]
+ // CHECK-DAG: If [ [[CondXY]] ]
+ // CHECK-DAG: [[CondYZ:z\d+]] GreaterThan [ [[ParamY]] [[ParamZ]] ]
+ // CHECK-DAG: If [ [[CondYZ]] ]
+ // CHECK-DAG: [[CondXYZ:z\d+]] NotEqual [ [[PhiXY:i\d+]] [[PhiYZ:i\d+]] ]
+ // CHECK-DAG: If [ [[CondXYZ]] ]
+ // CHECK-DAG: Return [ [[PhiXYZ:i\d+]] ]
+ // CHECK-DAG: [[PhiXY]] Phi [ [[Const1]] [[Const0]] ]
+ // CHECK-DAG: [[PhiYZ]] Phi [ [[Const1]] [[Const0]] ]
+ // CHECK-DAG: [[PhiXYZ]] Phi [ [[Const1]] [[Const0]] ]
+
+ // CHECK-START: boolean Main.ValuesOrdered(int, int, int) boolean_simplifier (after)
+ // CHECK-DAG: [[ParamX:i\d+]] ParameterValue
+ // CHECK-DAG: [[ParamY:i\d+]] ParameterValue
+ // CHECK-DAG: [[ParamZ:i\d+]] ParameterValue
+ // CHECK-DAG: [[CmpXY:z\d+]] LessThanOrEqual [ [[ParamX]] [[ParamY]] ]
+ // CHECK-DAG: [[CmpYZ:z\d+]] LessThanOrEqual [ [[ParamY]] [[ParamZ]] ]
+ // CHECK-DAG: [[CmpXYZ:z\d+]] Equal [ [[CmpXY]] [[CmpYZ]] ]
+ // CHECK-DAG: Return [ [[CmpXYZ]] ]
+
+ public static boolean ValuesOrdered(int x, int y, int z) {
+ return (x <= y) == (y <= z);
+ }
+
+ public static void main(String[] args) {
+ assertBoolEquals(false, BooleanNot(true));
+ assertBoolEquals(true, BooleanNot(false));
+ assertBoolEquals(true, GreaterThan(10, 5));
+ assertBoolEquals(false, GreaterThan(10, 10));
+ assertBoolEquals(false, GreaterThan(5, 10));
+ assertBoolEquals(true, LessThan(5, 10));
+ assertBoolEquals(false, LessThan(10, 10));
+ assertBoolEquals(false, LessThan(10, 5));
+ assertBoolEquals(true, ValuesOrdered(1, 3, 5));
+ assertBoolEquals(true, ValuesOrdered(5, 3, 1));
+ assertBoolEquals(false, ValuesOrdered(1, 3, 2));
+ assertBoolEquals(false, ValuesOrdered(2, 3, 1));
+ assertBoolEquals(true, ValuesOrdered(3, 3, 3));
+ assertBoolEquals(true, ValuesOrdered(3, 3, 5));
+ assertBoolEquals(false, ValuesOrdered(5, 5, 3));
+ }
+}