Merge "ART: Formatting and comments in BooleanSimplifier"
diff --git a/compiler/optimizing/boolean_simplifier.cc b/compiler/optimizing/boolean_simplifier.cc
index ecf9fa2..0ecc0d7 100644
--- a/compiler/optimizing/boolean_simplifier.cc
+++ b/compiler/optimizing/boolean_simplifier.cc
@@ -18,15 +18,6 @@
 
 namespace art {
 
-static bool EndsWithAnIf(HBasicBlock* block) {
-  return block->GetLastInstruction()->IsIf();
-}
-
-static bool HasSinglePhi(HBasicBlock* block) {
-  return !block->GetPhis().IsEmpty()
-      && block->GetFirstPhi()->GetNext() == nullptr;
-}
-
 // Returns true if 'block1' and 'block2' are empty, merge into the same single
 // successor and the successor can only be reached from them.
 static bool BlocksDoMergeTogether(HBasicBlock* block1, HBasicBlock* block2) {
@@ -39,15 +30,15 @@
 // Returns true if the outcome of the branching matches the boolean value of
 // the branching condition.
 static bool PreservesCondition(HInstruction* input_true, HInstruction* input_false) {
-  return input_true->IsIntConstant() && input_true->AsIntConstant()->GetValue() == 1
-         && input_false->IsIntConstant() && input_false->AsIntConstant()->GetValue() == 0;
+  return input_true->IsIntConstant() && input_true->AsIntConstant()->IsOne()
+      && input_false->IsIntConstant() && input_false->AsIntConstant()->IsZero();
 }
 
 // Returns true if the outcome of the branching is exactly opposite of the
 // boolean value of the branching condition.
 static bool NegatesCondition(HInstruction* input_true, HInstruction* input_false) {
-  return input_true->IsIntConstant() && input_true->AsIntConstant()->GetValue() == 0
-         && input_false->IsIntConstant() && input_false->AsIntConstant()->GetValue() == 1;
+  return input_true->IsIntConstant() && input_true->AsIntConstant()->IsZero()
+      && input_false->IsIntConstant() && input_false->AsIntConstant()->IsOne();
 }
 
 // Returns an instruction with the opposite boolean value from 'cond'.
@@ -72,11 +63,11 @@
       return new (allocator) HLessThan(lhs, rhs);
     }
   } else if (cond->IsIntConstant()) {
-    int32_t value = cond->AsIntConstant()->GetValue();
-    if (value == 0) {
+    HIntConstant* int_const = cond->AsIntConstant();
+    if (int_const->IsZero()) {
       return graph->GetIntConstant1();
     } else {
-      DCHECK_EQ(value, 1);
+      DCHECK(int_const->IsOne());
       return graph->GetIntConstant0();
     }
   }
@@ -91,7 +82,7 @@
   // order does not matter.
   for (HPostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
     HBasicBlock* block = it.Current();
-    if (!EndsWithAnIf(block)) continue;
+    if (!block->EndsWithIf()) continue;
 
     // Find elements of the pattern.
     HIf* if_instruction = block->GetLastInstruction()->AsIf();
@@ -101,7 +92,7 @@
       continue;
     }
     HBasicBlock* merge_block = true_block->GetSuccessors().Get(0);
-    if (!HasSinglePhi(merge_block)) {
+    if (!merge_block->HasSinglePhi()) {
       continue;
     }
     HPhi* phi = merge_block->GetFirstPhi()->AsPhi();
diff --git a/compiler/optimizing/boolean_simplifier.h b/compiler/optimizing/boolean_simplifier.h
index 9fa9c5a..a88733e 100644
--- a/compiler/optimizing/boolean_simplifier.h
+++ b/compiler/optimizing/boolean_simplifier.h
@@ -15,7 +15,7 @@
  */
 
 // This optimization recognizes a common pattern where a boolean value is
-// either casted to an integer or negated by selecting from zero/one integer
+// either cast to an integer or negated by selecting from zero/one integer
 // constants with an If statement. Because boolean values are internally
 // represented as zero/one, we can safely replace the pattern with a suitable
 // condition instruction.
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index d783903..5a79a69 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -1388,8 +1388,8 @@
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(conversion, call_kind);
 
-  // Java language does not allow treating boolean as an integral type but our
-  // bit representation makes it safe.
+  // The Java language does not allow treating boolean as an integral type but
+  // our bit representation makes it safe.
 
   switch (result_type) {
     case Primitive::kPrimByte:
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 0a7d3fe..4414a65 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1370,8 +1370,8 @@
   LocationSummary* locations =
       new (GetGraph()->GetArena()) LocationSummary(conversion, call_kind);
 
-  // Java language does not allow treating boolean as an integral type but our
-  // bit representation makes it safe.
+  // The Java language does not allow treating boolean as an integral type but
+  // our bit representation makes it safe.
 
   switch (result_type) {
     case Primitive::kPrimByte:
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index bff8fc9..c1f601e 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1410,8 +1410,8 @@
   Primitive::Type input_type = conversion->GetInputType();
   DCHECK_NE(result_type, input_type);
 
-  // Java language does not allow treating boolean as an integral type but our
-  // bit representation makes it safe.
+  // The Java language does not allow treating boolean as an integral type but
+  // our bit representation makes it safe.
 
   switch (result_type) {
     case Primitive::kPrimByte:
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 6009cb5..4f6565d 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -832,6 +832,14 @@
          && (loop_info == nullptr || !loop_info->IsBackEdge(*this));
 }
 
+bool HBasicBlock::EndsWithIf() const {
+  return !GetInstructions().IsEmpty() && GetLastInstruction()->IsIf();
+}
+
+bool HBasicBlock::HasSinglePhi() const {
+  return !GetPhis().IsEmpty() && GetFirstPhi()->GetNext() == nullptr;
+}
+
 void HInstructionList::SetBlockOfInstructions(HBasicBlock* block) const {
   for (HInstruction* current = first_instruction_;
        current != nullptr;
@@ -1086,13 +1094,15 @@
 }
 
 void HGraph::MergeEmptyBranches(HBasicBlock* start_block, HBasicBlock* end_block) {
-  // Make sure this is a diamond control-flow path, find the two branches.
+  // Find the two branches of an If.
   DCHECK_EQ(start_block->GetSuccessors().Size(), 2u);
-  DCHECK_EQ(end_block->GetPredecessors().Size(), 2u);
   HBasicBlock* left_branch = start_block->GetSuccessors().Get(0);
   HBasicBlock* right_branch = start_block->GetSuccessors().Get(1);
+
+  // Make sure this is a diamond control-flow path.
   DCHECK_EQ(left_branch->GetSuccessors().Get(0), end_block);
   DCHECK_EQ(right_branch->GetSuccessors().Get(0), end_block);
+  DCHECK_EQ(end_block->GetPredecessors().Size(), 2u);
   DCHECK_EQ(start_block, end_block->GetDominator());
 
   // Disconnect the branches and merge the two blocks. This will move
@@ -1114,16 +1124,12 @@
   reverse_post_order_.Delete(right_branch);
   reverse_post_order_.Delete(end_block);
 
-  // Update loop information.
-  HLoopInformation* loop_info = start_block->GetLoopInformation();
-  if (kIsDebugBuild) {
-    if (loop_info != nullptr) {
-      DCHECK_EQ(loop_info, left_branch->GetLoopInformation());
-      DCHECK_EQ(loop_info, right_branch->GetLoopInformation());
-      DCHECK_EQ(loop_info, end_block->GetLoopInformation());
-    }
-  }
-  while (loop_info != nullptr) {
+  // Update loops which contain the code.
+  for (HLoopInformationOutwardIterator it(*start_block); !it.Done(); it.Advance()) {
+    HLoopInformation* loop_info = it.Current();
+    DCHECK(loop_info->Contains(*left_branch));
+    DCHECK(loop_info->Contains(*right_branch));
+    DCHECK(loop_info->Contains(*end_block));
     loop_info->Remove(left_branch);
     loop_info->Remove(right_branch);
     loop_info->Remove(end_block);
@@ -1131,8 +1137,6 @@
       loop_info->RemoveBackEdge(end_block);
       loop_info->AddBackEdge(start_block);
     }
-    // Move to parent loop if nested.
-    loop_info = loop_info->GetHeader()->GetDominator()->GetLoopInformation();
   }
 }
 
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index db7873b..664cf18 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -602,6 +602,9 @@
   bool IsCatchBlock() const { return is_catch_block_; }
   void SetIsCatchBlock() { is_catch_block_ = true; }
 
+  bool EndsWithIf() const;
+  bool HasSinglePhi() const;
+
  private:
   HGraph* graph_;
   GrowableArray<HBasicBlock*> predecessors_;
@@ -624,6 +627,31 @@
   DISALLOW_COPY_AND_ASSIGN(HBasicBlock);
 };
 
+// Iterates over the LoopInformation of all loops which contain 'block'
+// from the innermost to the outermost.
+class HLoopInformationOutwardIterator : public ValueObject {
+ public:
+  explicit HLoopInformationOutwardIterator(const HBasicBlock& block)
+      : current_(block.GetLoopInformation()) {}
+
+  bool Done() const { return current_ == nullptr; }
+
+  void Advance() {
+    DCHECK(!Done());
+    current_ = current_->GetHeader()->GetDominator()->GetLoopInformation();
+  }
+
+  HLoopInformation* Current() const {
+    DCHECK(!Done());
+    return current_;
+  }
+
+ private:
+  HLoopInformation* current_;
+
+  DISALLOW_COPY_AND_ASSIGN(HLoopInformationOutwardIterator);
+};
+
 #define FOR_EACH_CONCRETE_INSTRUCTION(M)                                \
   M(Add, BinaryOperation)                                               \
   M(And, BinaryOperation)                                               \
diff --git a/runtime/primitive.h b/runtime/primitive.h
index d11f1e9..32bfdaf 100644
--- a/runtime/primitive.h
+++ b/runtime/primitive.h
@@ -153,8 +153,8 @@
   }
 
   static bool IsIntegralType(Type type) {
-    // Java language does not allow treating boolean as an integral type but our
-    // bit representation makes it safe.
+    // The Java language does not allow treating boolean as an integral type but
+    // our bit representation makes it safe.
     switch (type) {
       case kPrimBoolean:
       case kPrimByte:
diff --git a/test/463-checker-boolean-simplifier/src/Main.java b/test/463-checker-boolean-simplifier/src/Main.java
index 25f58b4..efe0d3f 100644
--- a/test/463-checker-boolean-simplifier/src/Main.java
+++ b/test/463-checker-boolean-simplifier/src/Main.java
@@ -116,7 +116,7 @@
   // CHECK-DAG:                       Return [ [[Cond]] ]
 
   public static boolean LessThan(int x, int y) {
-    return x < y;
+    return (x < y) ? true : false;
   }
 
   /*