OSDN Git Service

ART: Simplify (Not)Equal bool vs. int to true/false
authorDavid Brazdil <dbrazdil@google.com>
Mon, 22 Jun 2015 09:26:45 +0000 (10:26 +0100)
committerDavid Brazdil <dbrazdil@google.com>
Mon, 22 Jun 2015 10:07:57 +0000 (11:07 +0100)
Optimizations on the HGraph may produce comparisons of bool and ints.
Instruction simplifier will simplify these only for 0/1 int constants.
Since the range of bool is known, comparison against all other int
constants can always be determined statically.

Change-Id: I502651b7a08edf71ee0b2589069f00def6aacf66

compiler/optimizing/instruction_simplifier.cc
test/458-checker-instruction-simplification/src/Main.java

index 678924d..e375f7b 100644 (file)
@@ -324,6 +324,11 @@ void InstructionSimplifierVisitor::VisitEqual(HEqual* equal) {
         block->ReplaceAndRemoveInstructionWith(
             equal, new (block->GetGraph()->GetArena()) HBooleanNot(input_value));
         RecordSimplification();
+      } else {
+        // Replace (bool_value == integer_not_zero_nor_one_constant) with false
+        equal->ReplaceWith(GetGraph()->GetIntConstant(0));
+        block->RemoveInstruction(equal);
+        RecordSimplification();
       }
     }
   }
@@ -347,6 +352,11 @@ void InstructionSimplifierVisitor::VisitNotEqual(HNotEqual* not_equal) {
         not_equal->ReplaceWith(input_value);
         block->RemoveInstruction(not_equal);
         RecordSimplification();
+      } else {
+        // Replace (bool_value != integer_not_zero_nor_one_constant) with true
+        not_equal->ReplaceWith(GetGraph()->GetIntConstant(1));
+        block->RemoveInstruction(not_equal);
+        RecordSimplification();
       }
     }
   }
index 3c3b939..aa4dda1 100644 (file)
@@ -927,6 +927,36 @@ public class Main {
     return (false == arg) ? 3 : 5;
   }
 
+  /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before)
+  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
+  /// CHECK-DAG:     <<BoolNot:z\d+>>  BooleanNot [<<Arg>>]
+  /// CHECK-DAG:     <<Cond:z\d+>>     Equal [<<BoolNot>>,<<Const2>>]
+  /// CHECK-DAG:                       Return [<<Cond>>]
+
+  /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after)
+  /// CHECK-DAG:     <<False:i\d+>>    IntConstant 0
+  /// CHECK-DAG:                       Return [<<False>>]
+
+  public static boolean EqualBoolVsIntConst(boolean arg) {
+    return (arg ? 0 : 1) == 2;
+  }
+
+  /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before)
+  /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
+  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
+  /// CHECK-DAG:     <<BoolNot:z\d+>>  BooleanNot [<<Arg>>]
+  /// CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<BoolNot>>,<<Const2>>]
+  /// CHECK-DAG:                       Return [<<Cond>>]
+
+  /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after)
+  /// CHECK-DAG:     <<True:i\d+>>     IntConstant 1
+  /// CHECK-DAG:                       Return [<<True>>]
+
+  public static boolean NotEqualBoolVsIntConst(boolean arg) {
+    return (arg ? 0 : 1) != 2;
+  }
+
   /*
    * Test simplification of double Boolean negation. Note that sometimes
    * both negations can be removed but we only expect the simplifier to