Reduce PassDriver overhead, clean up Pass and PassDriver.

Remove name lookup map and use vector for the pass list.
Add traversal mode kNoNodes to skip BasicBlock traversal.
Replace the warn_override parameter with a DCHECK.
Move iterators from arena to the stack. Style cleanup.

Change-Id: I4bf10e28caa65efb98ce82a4d7486d803ceca535
diff --git a/compiler/dex/bb_optimizations.cc b/compiler/dex/bb_optimizations.cc
index f013067..b6716e6 100644
--- a/compiler/dex/bb_optimizations.cc
+++ b/compiler/dex/bb_optimizations.cc
@@ -23,7 +23,7 @@
 /*
  * Code Layout pass implementation start.
  */
-bool CodeLayout::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool CodeLayout::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
   cUnit->mir_graph->LayoutBlocks(bb);
   // No need of repeating, so just return false.
   return false;
@@ -32,13 +32,13 @@
 /*
  * SSATransformation pass implementation start.
  */
-bool SSATransformation::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool SSATransformation::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
   cUnit->mir_graph->InsertPhiNodeOperands(bb);
   // No need of repeating, so just return false.
   return false;
 }
 
-void SSATransformation::End(CompilationUnit *cUnit) const {
+void SSATransformation::End(CompilationUnit* cUnit) const {
   // Verify the dataflow information after the pass.
   if (cUnit->enable_debug & (1 << kDebugVerifyDataflow)) {
     cUnit->mir_graph->VerifyDataflow();
@@ -48,7 +48,7 @@
 /*
  * ConstantPropagation pass implementation start
  */
-bool ConstantPropagation::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool ConstantPropagation::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
   cUnit->mir_graph->DoConstantPropagation(bb);
   // No need of repeating, so just return false.
   return false;
@@ -57,7 +57,7 @@
 /*
  * MethodUseCount pass implementation start.
  */
-bool MethodUseCount::Gate(const CompilationUnit *cUnit) const {
+bool MethodUseCount::Gate(const CompilationUnit* cUnit) const {
   // First initialize the data.
   cUnit->mir_graph->InitializeMethodUses();
 
@@ -67,7 +67,7 @@
   return res;
 }
 
-bool MethodUseCount::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool MethodUseCount::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
   cUnit->mir_graph->CountUses(bb);
   // No need of repeating, so just return false.
   return false;
@@ -77,7 +77,7 @@
  * Null Check Elimination and Type Inference Initialization pass implementation start.
  */
 
-bool NullCheckEliminationAndTypeInferenceInit::Gate(const CompilationUnit *cUnit) const {
+bool NullCheckEliminationAndTypeInferenceInit::Gate(const CompilationUnit* cUnit) const {
   // First check the ssa register vector
   cUnit->mir_graph->CheckSSARegisterVector();
 
@@ -87,7 +87,8 @@
   return performInit;
 }
 
-bool NullCheckEliminationAndTypeInferenceInit::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool NullCheckEliminationAndTypeInferenceInit::WalkBasicBlocks(CompilationUnit* cUnit,
+                                                               BasicBlock* bb) const {
   cUnit->mir_graph->NullCheckEliminationInit(bb);
   // No need of repeating, so just return false.
   return false;
@@ -96,7 +97,7 @@
 /*
  * BasicBlock Combine pass implementation start.
  */
-bool BBCombine::WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+bool BBCombine::WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
   cUnit->mir_graph->CombineBlocks(bb);
 
   // No need of repeating, so just return false.
@@ -106,7 +107,7 @@
 /*
  * BasicBlock Optimization pass implementation start.
  */
-void BBOptimizations::Start(CompilationUnit *cUnit) const {
+void BBOptimizations::Start(CompilationUnit* cUnit) const {
   DCHECK_EQ(cUnit->num_compiler_temps, 0);
 
   /*
diff --git a/compiler/dex/bb_optimizations.h b/compiler/dex/bb_optimizations.h
index 768b273..1286a8e 100644
--- a/compiler/dex/bb_optimizations.h
+++ b/compiler/dex/bb_optimizations.h
@@ -28,14 +28,14 @@
  */
 class CodeLayout : public Pass {
  public:
-  CodeLayout():Pass("CodeLayout", "2_post_layout_cfg") {
+  CodeLayout() : Pass("CodeLayout", "2_post_layout_cfg") {
   }
 
-  void Start(CompilationUnit *cUnit) const {
+  void Start(CompilationUnit* cUnit) const {
     cUnit->mir_graph->VerifyDataflow();
   }
 
-  bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+  bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
 };
 
 /**
@@ -44,16 +44,16 @@
  */
 class SSATransformation : public Pass {
  public:
-  SSATransformation():Pass("SSATransformation", kPreOrderDFSTraversal, "3_post_ssa_cfg") {
+  SSATransformation() : Pass("SSATransformation", kPreOrderDFSTraversal, "3_post_ssa_cfg") {
   }
 
-  bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+  bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
 
-  void Start(CompilationUnit *cUnit) const {
+  void Start(CompilationUnit* cUnit) const {
     cUnit->mir_graph->InitializeSSATransformation();
   }
 
-  void End(CompilationUnit *cUnit) const;
+  void End(CompilationUnit* cUnit) const;
 };
 
 /**
@@ -62,12 +62,12 @@
  */
 class ConstantPropagation : public Pass {
  public:
-  ConstantPropagation():Pass("ConstantPropagation") {
+  ConstantPropagation() : Pass("ConstantPropagation") {
   }
 
-  bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+  bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
 
-  void Start(CompilationUnit *cUnit) const {
+  void Start(CompilationUnit* cUnit) const {
     cUnit->mir_graph->InitializeConstantPropagation();
   }
 };
@@ -78,10 +78,10 @@
  */
 class InitRegLocations : public Pass {
  public:
-  InitRegLocations():Pass("InitRegLocation") {
+  InitRegLocations() : Pass("InitRegLocation", kNoNodes) {
   }
 
-  void Start(CompilationUnit *cUnit) const {
+  void Start(CompilationUnit* cUnit) const {
     cUnit->mir_graph->InitRegLocations();
   }
 };
@@ -92,12 +92,12 @@
  */
 class MethodUseCount : public Pass {
  public:
-  MethodUseCount():Pass("UseCount") {
+  MethodUseCount() : Pass("UseCount") {
   }
 
-  bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+  bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
 
-  bool Gate(const CompilationUnit *cUnit) const;
+  bool Gate(const CompilationUnit* cUnit) const;
 };
 
 /**
@@ -106,12 +106,12 @@
  */
 class NullCheckEliminationAndTypeInferenceInit : public Pass {
  public:
-  NullCheckEliminationAndTypeInferenceInit():Pass("NCE_TypeInferenceInit") {
+  NullCheckEliminationAndTypeInferenceInit() : Pass("NCE_TypeInferenceInit") {
   }
 
-  bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+  bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
 
-  bool Gate(const CompilationUnit *cUnit) const;
+  bool Gate(const CompilationUnit* cUnit) const;
 };
 
 /**
@@ -120,10 +120,11 @@
  */
 class NullCheckEliminationAndTypeInference : public Pass {
  public:
-  NullCheckEliminationAndTypeInference():Pass("NCE_TypeInference", kRepeatingPreOrderDFSTraversal, "4_post_nce_cfg") {
+  NullCheckEliminationAndTypeInference()
+    : Pass("NCE_TypeInference", kRepeatingPreOrderDFSTraversal, "4_post_nce_cfg") {
   }
 
-  bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const {
+  bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const {
     return cUnit->mir_graph->EliminateNullChecksAndInferTypes(bb);
   }
 };
@@ -134,14 +135,14 @@
  */
 class BBCombine : public Pass {
  public:
-  BBCombine():Pass("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
+  BBCombine() : Pass("BBCombine", kPreOrderDFSTraversal, "5_post_bbcombine_cfg") {
   }
 
-  bool Gate(const CompilationUnit *cUnit) const {
+  bool Gate(const CompilationUnit* cUnit) const {
     return ((cUnit->disable_opt & (1 << kSuppressExceptionEdges)) != 0);
   }
 
-  bool WalkBasicBlocks(CompilationUnit *cUnit, BasicBlock *bb) const;
+  bool WalkBasicBlocks(CompilationUnit* cUnit, BasicBlock* bb) const;
 };
 
 /**
@@ -150,14 +151,14 @@
  */
 class BBOptimizations : public Pass {
  public:
-  BBOptimizations():Pass("BBOptimizations", "5_post_bbo_cfg") {
+  BBOptimizations() : Pass("BBOptimizations", kNoNodes, "5_post_bbo_cfg") {
   }
 
-  bool Gate(const CompilationUnit *cUnit) const {
+  bool Gate(const CompilationUnit* cUnit) const {
     return ((cUnit->disable_opt & (1 << kBBOpt)) == 0);
   }
 
-  void Start(CompilationUnit *cUnit) const;
+  void Start(CompilationUnit* cUnit) const;
 };
 
 }  // namespace art
diff --git a/compiler/dex/dataflow_iterator-inl.h b/compiler/dex/dataflow_iterator-inl.h
index 0ca1a47..f8b9c1a 100644
--- a/compiler/dex/dataflow_iterator-inl.h
+++ b/compiler/dex/dataflow_iterator-inl.h
@@ -107,7 +107,7 @@
   // Find the next BasicBlock.
   while (keep_looking == true) {
     // Get next BasicBlock.
-    res = all_nodes_iterator_->Next();
+    res = all_nodes_iterator_.Next();
 
     // Are we done or is the BasicBlock not hidden?
     if ((res == NULL) || (res->hidden == false)) {
diff --git a/compiler/dex/dataflow_iterator.h b/compiler/dex/dataflow_iterator.h
index 658a9b1..b45d6a4 100644
--- a/compiler/dex/dataflow_iterator.h
+++ b/compiler/dex/dataflow_iterator.h
@@ -138,21 +138,6 @@
 
         return ForwardSingleNext();
       }
-
-      /**
-       * @brief Redefine the new operator to use the arena
-       * @param size actually unused, we use our own class size
-       * @param arena the arena to perform the actual allocation
-       * @return the pointer to the newly allocated object
-       */
-      static void* operator new(size_t size, ArenaAllocator* arena) {
-        return arena->Alloc(sizeof(PreOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
-      }
-
-      /**
-       * @brief Redefine delete to not actually delete anything since we are using the arena
-       */
-      static void operator delete(void* p) {}
   };
 
   /**
@@ -184,21 +169,6 @@
 
         return ForwardRepeatNext();
       }
-
-      /**
-       * @brief Redefine the new operator to use the arena
-       * @param size actually unused, we use our own class size
-       * @param arena the arena to perform the actual allocation
-       * @return the pointer to the newly allocated object
-       */
-      static void* operator new(size_t size, ArenaAllocator* arena) {
-        return arena->Alloc(sizeof(RepeatingPreOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
-      }
-
-      /**
-       * @brief Redefine delete to not actually delete anything since we are using the arena
-       */
-      static void operator delete(void* p) {}
   };
 
   /**
@@ -230,21 +200,6 @@
 
         return ForwardRepeatNext();
       }
-
-      /**
-       * @brief Redefine the new operator to use the arena
-       * @param size actually unused, we use our own class size
-       * @param arena the arena to perform the actual allocation
-       * @return the pointer to the newly allocated object
-       */
-      static void* operator new(size_t size, ArenaAllocator* arena) {
-        return arena->Alloc(sizeof(RepeatingPostOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
-      }
-
-      /**
-       * @brief Redefine delete to not actually delete anything since we are using the arena
-       */
-      static void operator delete(void* p) {}
   };
 
   /**
@@ -275,21 +230,6 @@
 
         return ReverseSingleNext();
       }
-
-      /**
-       * @brief Redefine the new operator to use the arena
-       * @param size actually unused, we use our own class size
-       * @param arena the arena to perform the actual allocation
-       * @return the pointer to the newly allocated object
-       */
-      static void* operator new(size_t size, ArenaAllocator* arena) {
-        return arena->Alloc(sizeof(ReversePostOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
-      }
-
-      /**
-       * @brief Redefine delete to not actually delete anything since we are using the arena
-       */
-      static void operator delete(void* p) {}
   };
 
   /**
@@ -321,21 +261,6 @@
 
         return ReverseRepeatNext();
       }
-
-      /**
-       * @brief Redefine the new operator to use the arena
-       * @param size actually unused, we use our own class size
-       * @param arena the arena to perform the actual allocation
-       * @return the pointer to the newly allocated object
-       */
-      static void* operator new(size_t size, ArenaAllocator* arena) {
-        return arena->Alloc(sizeof(RepeatingReversePostOrderDfsIterator), ArenaAllocator::kAllocGrowableBitMap);
-      }
-
-      /**
-       * @brief Redefine delete to not actually delete anything since we are using the arena
-       */
-      static void operator delete(void* p) {}
   };
 
   /**
@@ -366,21 +291,6 @@
 
         return ForwardSingleNext();
       }
-
-      /**
-       * @brief Redefine the new operator to use the arena
-       * @param size actually unused, we use our own class size
-       * @param arena the arena to perform the actual allocation
-       * @return the pointer to the newly allocated object
-       */
-      static void* operator new(size_t size, ArenaAllocator* arena) {
-        return arena->Alloc(sizeof(PostOrderDOMIterator), ArenaAllocator::kAllocGrowableBitMap);
-      }
-
-      /**
-       * @brief Redefine delete to not actually delete anything since we are using the arena
-       */
-      static void operator delete(void* p) {}
   };
 
   /**
@@ -394,16 +304,15 @@
        * @param mir_graph The MIRGraph considered.
        */
       explicit AllNodesIterator(MIRGraph* mir_graph)
-          : DataflowIterator(mir_graph, 0, 0) {
-        all_nodes_iterator_ = new
-            (mir_graph->GetArena()) GrowableArray<BasicBlock*>::Iterator(mir_graph->GetBlockList());
+          : DataflowIterator(mir_graph, 0, 0),
+            all_nodes_iterator_(mir_graph->GetBlockList()) {
       }
 
       /**
        * @brief Resetting the iterator.
        */
       void Reset() {
-        all_nodes_iterator_->Reset();
+        all_nodes_iterator_.Reset();
       }
 
       /**
@@ -413,23 +322,8 @@
        */
       virtual BasicBlock* Next(bool had_change = false) ALWAYS_INLINE;
 
-      /**
-       * @brief Redefine the new operator to use the arena
-       * @param size actually unused, we use our own class size
-       * @param arena the arena to perform the actual allocation
-       * @return the pointer to the newly allocated object
-       */
-      static void* operator new(size_t size, ArenaAllocator* arena) {
-        return arena->Alloc(sizeof(AllNodesIterator), ArenaAllocator::kAllocGrowableBitMap);
-      }
-
-      /**
-       * @brief Redefine delete to not actually delete anything since we are using the arena
-       */
-      static void operator delete(void* p) {}
-
     private:
-      GrowableArray<BasicBlock*>::Iterator* all_nodes_iterator_;    /**< @brief The list of all the nodes */
+      GrowableArray<BasicBlock*>::Iterator all_nodes_iterator_;    /**< @brief The list of all the nodes */
   };
 
 }  // namespace art
diff --git a/compiler/dex/growable_array.h b/compiler/dex/growable_array.h
index 639120a..b5842e1 100644
--- a/compiler/dex/growable_array.h
+++ b/compiler/dex/growable_array.h
@@ -66,11 +66,6 @@
           idx_ = 0;
         }
 
-        static void* operator new(size_t size, ArenaAllocator* arena) {
-          return arena->Alloc(sizeof(GrowableArray::Iterator), ArenaAllocator::kAllocGrowableArray);
-        };
-        static void operator delete(void* p) {}  // Nop.
-
       private:
         size_t idx_;
         GrowableArray* const g_list_;
diff --git a/compiler/dex/pass.h b/compiler/dex/pass.h
index c52ddf5..255892e 100644
--- a/compiler/dex/pass.h
+++ b/compiler/dex/pass.h
@@ -41,6 +41,7 @@
   kRepeatingPostOrderDFSTraversal,         /**< @brief Depth-First-Search / Repeating Post-Order. */
   kRepeatingReversePostOrderDFSTraversal,  /**< @brief Depth-First-Search / Repeating Reverse Post-Order. */
   kPostOrderDOMTraversal,                  /**< @brief Dominator tree / Post-Order. */
+  kNoNodes,                                /**< @brief Skip BasicBlock traversal. */
 };
 
 /**
@@ -50,20 +51,22 @@
  */
 class Pass {
  public:
-  Pass(const char *name, DataFlowAnalysisMode type, bool freed, const unsigned int f, const char *dump): pass_name_(name), traversal_type_(type), flags_(f), dump_cfg_folder_(dump) {
+  explicit Pass(const char* name, DataFlowAnalysisMode type = kAllNodes,
+                unsigned int flags = 0u, const char* dump = "")
+    : pass_name_(name), traversal_type_(type), flags_(flags), dump_cfg_folder_(dump) {
   }
 
-  Pass(const char *name, const char *dump): pass_name_(name), traversal_type_(kAllNodes), flags_(0), dump_cfg_folder_(dump) {
+  Pass(const char* name, DataFlowAnalysisMode type, const char* dump)
+    : pass_name_(name), traversal_type_(type), flags_(0), dump_cfg_folder_(dump) {
   }
 
-  explicit Pass(const char *name):pass_name_(name), traversal_type_(kAllNodes), flags_(0), dump_cfg_folder_("") {
+  Pass(const char* name, const char* dump)
+    : pass_name_(name), traversal_type_(kAllNodes), flags_(0), dump_cfg_folder_(dump) {
   }
 
-  Pass(const char *name, DataFlowAnalysisMode type, const char *dump):pass_name_(name), traversal_type_(type), flags_(false), dump_cfg_folder_(dump) {
+  virtual ~Pass() {
   }
 
-  virtual ~Pass() {}
-
   virtual const char* GetName() const {
     return pass_name_;
   }
@@ -76,14 +79,16 @@
     return (flags_ & flag);
   }
 
-  const char* GetDumpCFGFolder() const {return dump_cfg_folder_;}
+  const char* GetDumpCFGFolder() const {
+    return dump_cfg_folder_;
+  }
 
   /**
    * @brief Gate for the pass: determines whether to execute the pass or not considering a CompilationUnit
    * @param c_unit the CompilationUnit.
    * @return whether or not to execute the pass
    */
-  virtual bool Gate(const CompilationUnit *c_unit) const {
+  virtual bool Gate(const CompilationUnit* c_unit) const {
     // Unused parameter.
     UNUSED(c_unit);
 
@@ -95,7 +100,7 @@
    * @brief Start of the pass: called before the WalkBasicBlocks function
    * @param c_unit the considered CompilationUnit.
    */
-  virtual void Start(CompilationUnit *c_unit) const {
+  virtual void Start(CompilationUnit* c_unit) const {
     // Unused parameter.
     UNUSED(c_unit);
   }
@@ -104,7 +109,7 @@
    * @brief End of the pass: called after the WalkBasicBlocks function
    * @param c_unit the considered CompilationUnit.
    */
-  virtual void End(CompilationUnit *c_unit) const {
+  virtual void End(CompilationUnit* c_unit) const {
     // Unused parameter.
     UNUSED(c_unit);
   }
@@ -115,7 +120,7 @@
    * @param bb the BasicBlock.
    * @return whether or not there is a change when walking the BasicBlock
    */
-  virtual bool WalkBasicBlocks(CompilationUnit *c_unit, BasicBlock *bb) const {
+  virtual bool WalkBasicBlocks(CompilationUnit* c_unit, BasicBlock* bb) const {
     // Unused parameters.
     UNUSED(c_unit);
     UNUSED(bb);
diff --git a/compiler/dex/pass_driver.cc b/compiler/dex/pass_driver.cc
index 820dc5a..4f8739a 100644
--- a/compiler/dex/pass_driver.cc
+++ b/compiler/dex/pass_driver.cc
@@ -16,6 +16,8 @@
 
 #include <dlfcn.h>
 
+#include "base/logging.h"
+#include "base/macros.h"
 #include "bb_optimizations.h"
 #include "compiler_internals.h"
 #include "dataflow_iterator.h"
@@ -28,7 +30,8 @@
 namespace {  // anonymous namespace
 
 /**
- * @brief Helper function to create a single instance of a given Pass and can be shared across the threads
+ * @brief Helper function to create a single instance of a given Pass and can be shared across
+ * the threads.
  */
 template <typename PassType>
 const Pass* GetPassInstance() {
@@ -36,55 +39,58 @@
   return &pass;
 }
 
+void DoWalkBasicBlocks(CompilationUnit* c_unit, const Pass* pass, DataflowIterator* iterator) {
+  // Paranoid: Check the iterator before walking the BasicBlocks.
+  DCHECK(iterator != nullptr);
+
+  bool change = false;
+  for (BasicBlock *bb = iterator->Next(change); bb != 0; bb = iterator->Next(change)) {
+    change = pass->WalkBasicBlocks(c_unit, bb);
+  }
+}
+
+template <typename Iterator>
+inline void DoWalkBasicBlocks(CompilationUnit* c_unit, const Pass* pass) {
+  Iterator iterator(c_unit->mir_graph.get());
+  DoWalkBasicBlocks(c_unit, pass, &iterator);
+}
+
 }  // anonymous namespace
 
-PassDriver::PassDriver(CompilationUnit* cu, bool create_default_passes) : cu_(cu) {
-  dump_cfg_folder_ = "/sdcard/";
+PassDriver::PassDriver(CompilationUnit* cu, bool create_default_passes)
+    : cu_(cu), dump_cfg_folder_("/sdcard/") {
+  DCHECK(cu != nullptr);
 
   // If need be, create the default passes.
-  if (create_default_passes == true) {
+  if (create_default_passes) {
     CreatePasses();
   }
 }
 
 PassDriver::~PassDriver() {
-  // Clear the map: done to remove any chance of having a pointer after freeing below
-  pass_map_.clear();
 }
 
-void PassDriver::InsertPass(const Pass* new_pass, bool warn_override) {
-  assert(new_pass != 0);
+void PassDriver::InsertPass(const Pass* new_pass) {
+  DCHECK(new_pass != nullptr);
+  DCHECK(new_pass->GetName() != nullptr && new_pass->GetName()[0] != 0);
 
-  // Get name here to not do it all over the method.
-  const std::string& name = new_pass->GetName();
+  // It is an error to override an existing pass.
+  DCHECK(GetPass(new_pass->GetName()) == nullptr)
+      << "Pass name " << new_pass->GetName() << " already used.";
 
-  // Do we want to warn the user about squashing a pass?
-  if (warn_override == false) {
-    auto it = pass_map_.find(name);
-
-    if (it != pass_map_.end()) {
-      LOG(INFO) << "Pass name " << name << " already used, overwriting pass";
-    }
-  }
-
-  // Now add to map and list.
-  pass_map_.Put(name, new_pass);
+  // Now add to the list.
   pass_list_.push_back(new_pass);
 }
 
 void PassDriver::CreatePasses() {
   /*
-   * Create the pass list:
-   *   - These passes are immutable and are shared across the threads:
-   *    - This is achieved via:
-   *     - The UniquePtr used here.
-   *     - DISALLOW_COPY_AND_ASSIGN in the base Pass class.
+   * Create the pass list. These passes are immutable and are shared across the threads.
    *
    * Advantage is that there will be no race conditions here.
    * Disadvantage is the passes can't change their internal states depending on CompilationUnit:
    *   - This is not yet an issue: no current pass would require it.
    */
-  static const Pass* passes[] = {
+  static const Pass* const passes[] = {
       GetPassInstance<CodeLayout>(),
       GetPassInstance<SSATransformation>(),
       GetPassInstance<ConstantPropagation>(),
@@ -96,14 +102,10 @@
       GetPassInstance<BBOptimizations>(),
   };
 
-  // Get number of elements in the array.
-  unsigned int nbr = (sizeof(passes) / sizeof(passes[0]));
-
-  // Insert each pass into the map and into the list via the InsertPass method:
-  //   - Map is used for the lookup
-  //   - List is used for the pass walk
-  for (unsigned int i = 0; i < nbr; i++) {
-    InsertPass(passes[i]);
+  // Insert each pass into the list via the InsertPass method.
+  pass_list_.reserve(arraysize(passes));
+  for (const Pass* pass : passes) {
+    InsertPass(pass);
   }
 }
 
@@ -114,49 +116,37 @@
 }
 
 void PassDriver::DispatchPass(CompilationUnit* c_unit, const Pass* curPass) {
-  DataflowIterator* iterator = 0;
-
   LOG(DEBUG) << "Dispatching " << curPass->GetName();
 
-  MIRGraph* mir_graph = c_unit->mir_graph.get();
-  ArenaAllocator *arena = &(c_unit->arena);
-
-  // Let us start by getting the right iterator.
   DataFlowAnalysisMode mode = curPass->GetTraversal();
 
   switch (mode) {
     case kPreOrderDFSTraversal:
-      iterator = new (arena) PreOrderDfsIterator(mir_graph);
+      DoWalkBasicBlocks<PreOrderDfsIterator>(c_unit, curPass);
       break;
     case kRepeatingPreOrderDFSTraversal:
-      iterator = new (arena) RepeatingPreOrderDfsIterator(mir_graph);
+      DoWalkBasicBlocks<RepeatingPreOrderDfsIterator>(c_unit, curPass);
       break;
     case kRepeatingPostOrderDFSTraversal:
-      iterator = new (arena) RepeatingPostOrderDfsIterator(mir_graph);
+      DoWalkBasicBlocks<RepeatingPostOrderDfsIterator>(c_unit, curPass);
       break;
     case kReversePostOrderDFSTraversal:
-      iterator = new (arena) ReversePostOrderDfsIterator(mir_graph);
+      DoWalkBasicBlocks<ReversePostOrderDfsIterator>(c_unit, curPass);
       break;
     case kRepeatingReversePostOrderDFSTraversal:
-      iterator = new (arena) RepeatingReversePostOrderDfsIterator(mir_graph);
+      DoWalkBasicBlocks<RepeatingReversePostOrderDfsIterator>(c_unit, curPass);
       break;
     case kPostOrderDOMTraversal:
-      iterator = new (arena) PostOrderDOMIterator(mir_graph);
+      DoWalkBasicBlocks<PostOrderDOMIterator>(c_unit, curPass);
       break;
     case kAllNodes:
-      iterator = new (arena) AllNodesIterator(mir_graph);
+      DoWalkBasicBlocks<AllNodesIterator>(c_unit, curPass);
+      break;
+    case kNoNodes:
       break;
     default:
       LOG(DEBUG) << "Iterator mode not handled in dispatcher: " << mode;
-      return;
-  }
-
-  // Paranoid: Check the iterator before walking the BasicBlocks.
-  assert(iterator != 0);
-
-  bool change = false;
-  for (BasicBlock *bb = iterator->Next(change); bb != 0; bb = iterator->Next(change)) {
-    change = curPass->WalkBasicBlocks(c_unit, bb);
+      break;
   }
 }
 
@@ -166,33 +156,34 @@
   curPass->End(c_unit);
 }
 
-bool PassDriver::RunPass(CompilationUnit* c_unit, const Pass* curPass, bool time_split) {
-  // Paranoid: c_unit or curPass cannot be 0, and the pass should have a name.
-  if (c_unit == 0 || curPass == 0 || (strcmp(curPass->GetName(), "") == 0)) {
-    return false;
-  }
+bool PassDriver::RunPass(CompilationUnit* c_unit, const Pass* pass, bool time_split) {
+  // Paranoid: c_unit and pass cannot be nullptr, and the pass should have a name.
+  DCHECK(c_unit != nullptr);
+  DCHECK(pass != nullptr);
+  DCHECK(pass->GetName() != nullptr && pass->GetName()[0] != 0);
 
   // Do we perform a time split
-  if (time_split == true) {
-    c_unit->NewTimingSplit(curPass->GetName());
+  if (time_split) {
+    c_unit->NewTimingSplit(pass->GetName());
   }
 
   // Check the pass gate first.
-  bool shouldApplyPass = curPass->Gate(c_unit);
+  bool should_apply_pass = pass->Gate(c_unit);
 
-  if (shouldApplyPass == true) {
+  if (should_apply_pass) {
     // Applying the pass: first start, doWork, and end calls.
-    ApplyPass(c_unit, curPass);
+    ApplyPass(c_unit, pass);
 
     // Clean up if need be.
-    HandlePassFlag(c_unit, curPass);
+    HandlePassFlag(c_unit, pass);
 
     // Do we want to log it?
     if ((c_unit->enable_debug&  (1 << kDebugDumpCFG)) != 0) {
       // Do we have a pass folder?
-      const std::string& passFolder = curPass->GetDumpCFGFolder();
+      const char* passFolder = pass->GetDumpCFGFolder();
+      DCHECK(passFolder != nullptr);
 
-      if (passFolder != "") {
+      if (passFolder[0] != 0) {
         // Create directory prefix.
         std::string prefix = GetDumpCFGFolder();
         prefix += passFolder;
@@ -204,19 +195,18 @@
   }
 
   // If the pass gate passed, we can declare success.
-  return shouldApplyPass;
+  return should_apply_pass;
 }
 
-bool PassDriver::RunPass(CompilationUnit* c_unit, const std::string& pass_name) {
-  // Paranoid: c_unit cannot be 0 and we need a pass name.
-  if (c_unit == 0 || pass_name == "") {
-    return false;
-  }
+bool PassDriver::RunPass(CompilationUnit* c_unit, const char* pass_name) {
+  // Paranoid: c_unit cannot be nullptr and we need a pass name.
+  DCHECK(c_unit != nullptr);
+  DCHECK(pass_name != nullptr && pass_name[0] != 0);
 
-  const Pass* curPass = GetPass(pass_name);
+  const Pass* cur_pass = GetPass(pass_name);
 
-  if (curPass != 0) {
-    return RunPass(c_unit, curPass);
+  if (cur_pass != nullptr) {
+    return RunPass(c_unit, cur_pass);
   }
 
   // Return false, we did not find the pass.
@@ -224,27 +214,26 @@
 }
 
 void PassDriver::Launch() {
-  for (const Pass *curPass : pass_list_) {
-    RunPass(cu_, curPass, true);
+  for (const Pass* cur_pass : pass_list_) {
+    RunPass(cu_, cur_pass, true);
   }
 }
 
 void PassDriver::PrintPassNames() const {
   LOG(INFO) << "Loop Passes are:";
 
-  for (const Pass *curPass : pass_list_) {
-    LOG(INFO) << "\t-" << curPass->GetName();
+  for (const Pass* cur_pass : pass_list_) {
+    LOG(INFO) << "\t-" << cur_pass->GetName();
   }
 }
 
-const Pass* PassDriver::GetPass(const std::string& name) const {
-  auto it = pass_map_.find(name);
-
-  if (it != pass_map_.end()) {
-    return it->second;
+const Pass* PassDriver::GetPass(const char* name) const {
+  for (const Pass* cur_pass : pass_list_) {
+    if (strcmp(name, cur_pass->GetName()) == 0) {
+      return cur_pass;
+    }
   }
-
-  return 0;
+  return nullptr;
 }
 
 }  // namespace art
diff --git a/compiler/dex/pass_driver.h b/compiler/dex/pass_driver.h
index d580460..c734d3e 100644
--- a/compiler/dex/pass_driver.h
+++ b/compiler/dex/pass_driver.h
@@ -17,7 +17,7 @@
 #ifndef ART_COMPILER_DEX_PASS_DRIVER_H_
 #define ART_COMPILER_DEX_PASS_DRIVER_H_
 
-#include <list>
+#include <vector>
 #include "pass.h"
 #include "safe_map.h"
 
@@ -42,7 +42,7 @@
    * @param new_pass the new Pass to insert in the map and list.
    * @param warn_override warn if the name of the Pass is already used.
    */
-  void InsertPass(const Pass* new_pass, bool warn_override = true);
+  void InsertPass(const Pass* new_pass);
 
   /**
    * @brief Run a pass using the name as key.
@@ -50,7 +50,7 @@
    * @param pass_name the Pass name.
    * @return whether the pass was applied.
    */
-  bool RunPass(CompilationUnit* c_unit, const std::string& pass_name);
+  bool RunPass(CompilationUnit* c_unit, const char* pass_name);
 
   /**
    * @brief Run a pass using the Pass itself.
@@ -75,20 +75,17 @@
 
   void PrintPassNames() const;
 
-  const Pass* GetPass(const std::string& name) const;
+  const Pass* GetPass(const char* name) const;
 
-  const char *GetDumpCFGFolder() const {
+  const char* GetDumpCFGFolder() const {
     return dump_cfg_folder_;
   }
 
  protected:
   void CreatePasses();
 
-  /** @brief The Pass Map: contains name -> pass for quick lookup. */
-  SafeMap<std::string, const Pass*> pass_map_;
-
   /** @brief List of passes: provides the order to execute the passes. */
-  std::list<const Pass*> pass_list_;
+  std::vector<const Pass*> pass_list_;
 
   /** @brief The CompilationUnit on which to execute the passes on. */
   CompilationUnit* const cu_;