Implements a BasicBlock iterator using the ArenaBitVector.

Added the implementation of a BasicBlock iterator using the ArenaBitVector.
This patch only adds the implementation of the iterator and does not yet use
 it everywhere it could be.

Added one example in ssa_transformation.cc of its use.

Change-Id: Ia85d58320c80c48a43609265ea5318a416c71f18
Signed-off-by: Jean Christophe Beyler <jean.christophe.beyler@intel.com>
diff --git a/compiler/dex/arena_bit_vector.cc b/compiler/dex/arena_bit_vector.cc
index b567ae8..1b37b71 100644
--- a/compiler/dex/arena_bit_vector.cc
+++ b/compiler/dex/arena_bit_vector.cc
@@ -44,4 +44,14 @@
                                bool expandable, OatBitMapKind kind)
   :  BitVector(start_bits, expandable, new (arena) ArenaBitVectorAllocator(arena)), kind_(kind) {}
 
+BasicBlock* ArenaBitVector::BasicBlockIterator::Next() {
+    int idx = internal_iterator_.Next();
+
+    if (idx == -1) {
+      return nullptr;
+    }
+
+    return mir_graph_->GetBasicBlock(idx);
+}
+
 }  // namespace art
diff --git a/compiler/dex/arena_bit_vector.h b/compiler/dex/arena_bit_vector.h
index e904406..cdd5c68 100644
--- a/compiler/dex/arena_bit_vector.h
+++ b/compiler/dex/arena_bit_vector.h
@@ -20,14 +20,45 @@
 #include "base/bit_vector.h"
 #include "compiler_enums.h"
 #include "utils/arena_allocator.h"
+#include "compiler_ir.h"
 
 namespace art {
 
+// Forward declaration
+class MIRGraph;
+
 /*
  * A BitVector implementation that uses Arena allocation.
  */
 class ArenaBitVector : public BitVector {
   public:
+    /**
+     * @class BasicBlockIterator
+     * @brief Helper class to get the BasicBlocks when iterating through the ArenaBitVector.
+     */
+    class BasicBlockIterator {
+      public:
+        explicit BasicBlockIterator(ArenaBitVector* bv, MIRGraph* mir_graph)
+          : mir_graph_(mir_graph),
+            internal_iterator_(bv) {}
+
+        explicit BasicBlockIterator(ArenaBitVector* bv, CompilationUnit* c_unit)
+          : mir_graph_(c_unit->mir_graph.get()),
+            internal_iterator_(bv) {}
+
+        BasicBlock* Next();
+
+        static void* operator new(size_t size, ArenaAllocator* arena) {
+          return arena->Alloc(sizeof(ArenaBitVector::BasicBlockIterator),
+                              ArenaAllocator::kAllocGrowableArray);
+        };
+        static void operator delete(void* p) {}  // Nop.
+
+      private:
+        MIRGraph* const mir_graph_;
+        Iterator internal_iterator_;
+    };
+
     ArenaBitVector(ArenaAllocator* arena, uint32_t start_bits, bool expandable,
                    OatBitMapKind kind = kBitMapMisc);
     ~ArenaBitVector() {}
diff --git a/compiler/dex/ssa_transformation.cc b/compiler/dex/ssa_transformation.cc
index 502df1e..0f79f41 100644
--- a/compiler/dex/ssa_transformation.cc
+++ b/compiler/dex/ssa_transformation.cc
@@ -248,22 +248,11 @@
   }
 
   /* Calculate DF_up */
-  ArenaBitVector::Iterator bv_iterator(bb->i_dominated);
-  while (true) {
-    // TUNING: hot call to BitVectorIteratorNext
-    int dominated_idx = bv_iterator.Next();
-    if (dominated_idx == -1) {
-      break;
-    }
-    BasicBlock* dominated_bb = GetBasicBlock(dominated_idx);
-    ArenaBitVector::Iterator df_iterator(dominated_bb->dom_frontier);
-    while (true) {
-      // TUNING: hot call to BitVectorIteratorNext
-      int df_up_idx = df_iterator.Next();
-      if (df_up_idx == -1) {
-        break;
-      }
-      BasicBlock* df_up_block = GetBasicBlock(df_up_idx);
+  ArenaBitVector::BasicBlockIterator it(bb->i_dominated, cu_);
+  for (BasicBlock *dominated_bb = it.Next(); dominated_bb != nullptr; dominated_bb = it.Next()) {
+    ArenaBitVector::BasicBlockIterator inner_it(dominated_bb->dom_frontier, cu_);
+    for (BasicBlock *df_up_block = inner_it.Next(); df_up_block != nullptr;
+         df_up_block = inner_it.Next()) {
       CheckForDominanceFrontier(bb, df_up_block);
     }
   }