Improve bce so that more bounds checks can be eliminated.

For pattern like "int[] array = new int[size+1]", we record this range
for size:
[-1, array.length-1]
This can eliminate more bounds checks.

Also simplify overflow/underflow handling and make it more solid.

Enhance instruction simplifier such that if array is a result of
NewArray with a constant size, replace array.length with that constant.

Plan to move all bce gtests to checker in another change.

Change-Id: Ibe7cc7940b68fb6465dc3e0ff3ebdb0fd6487aa9
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 17c8f33..44dbb9d 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -28,6 +28,7 @@
   void VisitArraySet(HArraySet* equal) OVERRIDE;
   void VisitTypeConversion(HTypeConversion* instruction) OVERRIDE;
   void VisitNullCheck(HNullCheck* instruction) OVERRIDE;
+  void VisitArrayLength(HArrayLength* instruction) OVERRIDE;
 };
 
 void InstructionSimplifier::Run() {
@@ -75,6 +76,18 @@
   }
 }
 
+void InstructionSimplifierVisitor::VisitArrayLength(HArrayLength* instruction) {
+  HInstruction* input = instruction->InputAt(0);
+  // If the array is a NewArray with constant size, replace the array length
+  // with the constant instruction. This helps the bounds check elimination phase.
+  if (input->IsNewArray()) {
+    input = input->InputAt(0);
+    if (input->IsIntConstant()) {
+      instruction->ReplaceWith(input);
+    }
+  }
+}
+
 void InstructionSimplifierVisitor::VisitArraySet(HArraySet* instruction) {
   HInstruction* value = instruction->GetValue();
   if (value->GetType() != Primitive::kPrimNot) return;