Make BCE a no-op if there is no array access.

Change-Id: I8456182808c1dbaa0c0ae1b8c2e94bb17baf5f29
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 4ca3648..1d16794 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -944,6 +944,10 @@
 };
 
 void BoundsCheckElimination::Run() {
+  if (!graph_->HasArrayAccesses()) {
+    return;
+  }
+
   BCEVisitor visitor(graph_);
   // Reverse post order guarantees a node's dominators are visited first.
   // We want to visit in the dominator-based order since if a value is known to
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 20a1b03..2cac93d 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -840,6 +840,7 @@
     current_block_->AddInstruction(new (arena_) HArrayGet(object, index, anticipated_type));
     UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction());
   }
+  graph_->SetHasArrayAccesses(true);
 }
 
 void HGraphBuilder::BuildFilledNewArray(uint32_t dex_pc,
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index d55a3ca..b34957a 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -216,6 +216,10 @@
 
   callee_graph->InlineInto(graph_, invoke_instruction);
 
+  if (callee_graph->HasArrayAccesses()) {
+    graph_->SetHasArrayAccesses(true);
+  }
+
   // Now that we have inlined the callee, we need to update the next
   // instruction id of the caller, so that new instructions added
   // after optimizations get a unique id.
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 98076a0..b7dd756 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -113,6 +113,7 @@
         number_of_vregs_(0),
         number_of_in_vregs_(0),
         temporaries_vreg_slots_(0),
+        has_array_accesses_(false),
         current_instruction_id_(start_instruction_id) {}
 
   ArenaAllocator* GetArena() const { return arena_; }
@@ -199,6 +200,14 @@
     return reverse_post_order_;
   }
 
+  bool HasArrayAccesses() const {
+    return has_array_accesses_;
+  }
+
+  void SetHasArrayAccesses(bool value) {
+    has_array_accesses_ = value;
+  }
+
   HNullConstant* GetNullConstant();
 
  private:
@@ -236,6 +245,9 @@
   // Number of vreg size slots that the temporaries use (used in baseline compiler).
   size_t temporaries_vreg_slots_;
 
+  // Has array accesses. We can totally skip BCE if it's false.
+  bool has_array_accesses_;
+
   // The current id to assign to a newly added instruction. See HInstruction.id_.
   int32_t current_instruction_id_;