Merge "Clean up pass driver"
diff --git a/compiler/Android.mk b/compiler/Android.mk
index 27c6daf..4f4d075 100644
--- a/compiler/Android.mk
+++ b/compiler/Android.mk
@@ -69,12 +69,14 @@
 	dex/post_opt_passes.cc \
 	dex/pass_driver_me_opts.cc \
 	dex/pass_driver_me_post_opt.cc \
+	dex/pass_manager.cc \
 	dex/ssa_transformation.cc \
 	dex/verified_method.cc \
 	dex/verification_results.cc \
 	dex/vreg_analysis.cc \
 	dex/quick_compiler_callbacks.cc \
 	driver/compiler_driver.cc \
+	driver/compiler_options.cc \
 	driver/dex_compilation_unit.cc \
 	jni/quick/arm/calling_convention_arm.cc \
 	jni/quick/arm64/calling_convention_arm64.cc \
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index 96f8e0c..1cd78f8 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -19,9 +19,10 @@
 #include "arch/instruction_set_features.h"
 #include "class_linker.h"
 #include "compiled_method.h"
+#include "dex/pass_manager.h"
 #include "dex/quick_compiler_callbacks.h"
-#include "dex/verification_results.h"
 #include "dex/quick/dex_file_to_method_inliner_map.h"
+#include "dex/verification_results.h"
 #include "driver/compiler_driver.h"
 #include "interpreter/interpreter.h"
 #include "mirror/art_method.h"
diff --git a/compiler/compiler.cc b/compiler/compiler.cc
index baa6688..5e8ec1e 100644
--- a/compiler/compiler.cc
+++ b/compiler/compiler.cc
@@ -17,7 +17,7 @@
 #include "compiler.h"
 
 #include "base/logging.h"
-#include "dex/quick/quick_compiler.h"
+#include "dex/quick/quick_compiler_factory.h"
 #include "driver/compiler_driver.h"
 #include "optimizing/optimizing_compiler.h"
 
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc
index db4141c..0f7d45d 100644
--- a/compiler/dex/mir_graph.cc
+++ b/compiler/dex/mir_graph.cc
@@ -30,6 +30,7 @@
 #include "dex_instruction-inl.h"
 #include "driver/compiler_driver.h"
 #include "driver/dex_compilation_unit.h"
+#include "dex/quick/quick_compiler.h"
 #include "leb128.h"
 #include "pass_driver_me_post_opt.h"
 #include "stack.h"
@@ -2432,7 +2433,10 @@
 }
 
 void MIRGraph::CalculateBasicBlockInformation() {
-  PassDriverMEPostOpt driver(cu_);
+  auto* quick_compiler = down_cast<QuickCompiler*>(cu_->compiler_driver->GetCompiler());
+  DCHECK(quick_compiler != nullptr);
+  /* Create the pass driver and launch it */
+  PassDriverMEPostOpt driver(quick_compiler->GetPostOptPassManager(), cu_);
   driver.Launch();
 }
 
diff --git a/compiler/dex/pass_driver.h b/compiler/dex/pass_driver.h
index 632df38..671bcec 100644
--- a/compiler/dex/pass_driver.h
+++ b/compiler/dex/pass_driver.h
@@ -21,19 +21,14 @@
 
 #include "base/logging.h"
 #include "pass.h"
-#include "safe_map.h"
+#include "pass_manager.h"
 
 namespace art {
 
-/**
- * @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() {
-  static const PassType pass;
-  return &pass;
-}
+class Pass;
+class PassDataHolder;
+class PassDriver;
+class PassManager;
 
 // Empty holder for the constructor.
 class PassDriverDataHolder {
@@ -43,11 +38,11 @@
  * @class PassDriver
  * @brief PassDriver is the wrapper around all Pass instances in order to execute them
  */
-template <typename PassDriverType>
 class PassDriver {
  public:
-  explicit PassDriver() {
-    InitializePasses();
+  explicit PassDriver(const PassManager* const pass_manager) : pass_manager_(pass_manager) {
+    pass_list_ = *pass_manager_->GetDefaultPassList();
+    DCHECK(!pass_list_.empty());
   }
 
   virtual ~PassDriver() {
@@ -58,12 +53,12 @@
    */
   void InsertPass(const Pass* new_pass) {
     DCHECK(new_pass != nullptr);
-    DCHECK(new_pass->GetName() != nullptr && new_pass->GetName()[0] != 0);
+    DCHECK(new_pass->GetName() != nullptr);
+    DCHECK_NE(new_pass->GetName()[0], 0);
 
     // It is an error to override an existing pass.
     DCHECK(GetPass(new_pass->GetName()) == nullptr)
         << "Pass name " << new_pass->GetName() << " already used.";
-
     // Now add to the list.
     pass_list_.push_back(new_pass);
   }
@@ -74,7 +69,8 @@
    */
   virtual bool RunPass(const char* pass_name) {
     // Paranoid: c_unit cannot be nullptr and we need a pass name.
-    DCHECK(pass_name != nullptr && pass_name[0] != 0);
+    DCHECK(pass_name != nullptr);
+    DCHECK_NE(pass_name[0], 0);
 
     const Pass* cur_pass = GetPass(pass_name);
 
@@ -108,21 +104,6 @@
     return nullptr;
   }
 
-  static void CreateDefaultPassList(const std::string& disable_passes) {
-    // Insert each pass from g_passes into g_default_pass_list.
-    PassDriverType::g_default_pass_list.clear();
-    PassDriverType::g_default_pass_list.reserve(PassDriver<PassDriverType>::g_passes_size);
-    for (uint16_t i = 0; i < PassDriver<PassDriverType>::g_passes_size; ++i) {
-      const Pass* pass = PassDriver<PassDriverType>::g_passes[i];
-      // Check if we should disable this pass.
-      if (disable_passes.find(pass->GetName()) != std::string::npos) {
-        LOG(INFO) << "Skipping " << pass->GetName();
-      } else {
-        PassDriver<PassDriverType>::g_default_pass_list.push_back(pass);
-      }
-    }
-  }
-
   /**
    * @brief Run a pass using the Pass itself.
    * @param time_split do we want a time split request(default: false)?
@@ -130,57 +111,7 @@
    */
   virtual bool RunPass(const Pass* pass, bool time_split = false) = 0;
 
-  /**
-   * @brief Print the pass names of all the passes available.
-   */
-  static void PrintPassNames() {
-    LOG(INFO) << "Loop Passes are:";
-
-    for (const Pass* cur_pass : PassDriver<PassDriverType>::g_default_pass_list) {
-      LOG(INFO) << "\t-" << cur_pass->GetName();
-    }
-  }
-
-  /**
-   * @brief Gets the list of passes currently schedule to execute.
-   * @return pass_list_
-   */
-  std::vector<const Pass*>& GetPasses() {
-    return pass_list_;
-  }
-
-  static void SetPrintAllPasses() {
-    default_print_passes_ = true;
-  }
-
-  static void SetDumpPassList(const std::string& list) {
-    dump_pass_list_ = list;
-  }
-
-  static void SetPrintPassList(const std::string& list) {
-    print_pass_list_ = list;
-  }
-
-  /**
-   * @brief Used to set a string that contains the overridden pass options.
-   * @details An overridden pass option means that the pass uses this option
-   * instead of using its default option.
-   * @param s The string passed by user with overridden options. The string is in format
-   * Pass1Name:Pass1Option:Pass1Setting,Pass2Name:Pass2Option::Pass2Setting
-   */
-  static void SetOverriddenPassOptions(const std::string& s) {
-    overridden_pass_options_list_ = s;
-  }
-
-  void SetDefaultPasses() {
-    pass_list_ = PassDriver<PassDriverType>::g_default_pass_list;
-  }
-
  protected:
-  virtual void InitializePasses() {
-    SetDefaultPasses();
-  }
-
   /**
    * @brief Apply a patch: perform start/work/end functions.
    */
@@ -189,6 +120,7 @@
     DispatchPass(pass);
     pass->End(data);
   }
+
   /**
    * @brief Dispatch a patch.
    * Gives the ability to add logic when running the patch.
@@ -197,29 +129,11 @@
     UNUSED(pass);
   }
 
-  /** @brief List of passes: provides the order to execute the passes. */
+  /** @brief List of passes: provides the order to execute the passes.
+   *  Passes are owned by pass_manager_. */
   std::vector<const Pass*> pass_list_;
 
-  /** @brief The number of passes within g_passes.  */
-  static const uint16_t g_passes_size;
-
-  /** @brief The number of passes within g_passes.  */
-  static const Pass* const g_passes[];
-
-  /** @brief The default pass list is used to initialize pass_list_. */
-  static std::vector<const Pass*> g_default_pass_list;
-
-  /** @brief Do we, by default, want to be printing the log messages? */
-  static bool default_print_passes_;
-
-  /** @brief What are the passes we want to be printing the log messages? */
-  static std::string print_pass_list_;
-
-  /** @brief What are the passes we want to be dumping the CFG? */
-  static std::string dump_pass_list_;
-
-  /** @brief String of all options that should be overridden for selected passes */
-  static std::string overridden_pass_options_list_;
+  const PassManager* const pass_manager_;
 };
 
 }  // namespace art
diff --git a/compiler/dex/pass_driver_me.h b/compiler/dex/pass_driver_me.h
index ff7c4a4..fed92be 100644
--- a/compiler/dex/pass_driver_me.h
+++ b/compiler/dex/pass_driver_me.h
@@ -19,20 +19,25 @@
 
 #include <cstdlib>
 #include <cstring>
+
 #include "bb_optimizations.h"
 #include "dataflow_iterator.h"
 #include "dataflow_iterator-inl.h"
 #include "dex_flags.h"
 #include "pass_driver.h"
+#include "pass_manager.h"
 #include "pass_me.h"
+#include "safe_map.h"
 
 namespace art {
 
-template <typename PassDriverType>
-class PassDriverME: public PassDriver<PassDriverType> {
+class PassManager;
+class PassManagerOptions;
+
+class PassDriverME: public PassDriver {
  public:
-  explicit PassDriverME(CompilationUnit* cu)
-      : pass_me_data_holder_(), dump_cfg_folder_("/sdcard/") {
+  explicit PassDriverME(const PassManager* const pass_manager, CompilationUnit* cu)
+      : PassDriver(pass_manager), pass_me_data_holder_(), dump_cfg_folder_("/sdcard/") {
         pass_me_data_holder_.bb = nullptr;
         pass_me_data_holder_.c_unit = cu;
   }
@@ -82,7 +87,7 @@
     }
   }
 
-  bool RunPass(const Pass* pass, bool time_split) {
+  bool RunPass(const Pass* pass, bool time_split) OVERRIDE {
     // Paranoid: c_unit and pass cannot be nullptr, and the pass should have a name
     DCHECK(pass != nullptr);
     DCHECK(pass->GetName() != nullptr && pass->GetName()[0] != 0);
@@ -96,15 +101,17 @@
 
     // First, work on determining pass verbosity.
     bool old_print_pass = c_unit->print_pass;
-    c_unit->print_pass = PassDriver<PassDriverType>::default_print_passes_;
-    const char* print_pass_list = PassDriver<PassDriverType>::print_pass_list_.c_str();
-    if (print_pass_list != nullptr && strstr(print_pass_list, pass->GetName()) != nullptr) {
+    c_unit->print_pass = pass_manager_->GetOptions().GetPrintAllPasses();
+    auto* const options = &pass_manager_->GetOptions();
+    const std::string& print_pass_list = options->GetPrintPassList();
+    if (!print_pass_list.empty() && strstr(print_pass_list.c_str(), pass->GetName()) != nullptr) {
       c_unit->print_pass = true;
     }
 
-    // Next, check if there are any overridden settings for the pass that change default configuration.
+    // Next, check if there are any overridden settings for the pass that change default
+    // configuration.
     c_unit->overridden_pass_options.clear();
-    FillOverriddenPassSettings(pass->GetName(), c_unit->overridden_pass_options);
+    FillOverriddenPassSettings(options, pass->GetName(), c_unit->overridden_pass_options);
     if (c_unit->print_pass) {
       for (auto setting_it : c_unit->overridden_pass_options) {
         LOG(INFO) << "Overridden option \"" << setting_it.first << ":"
@@ -118,13 +125,12 @@
       // Applying the pass: first start, doWork, and end calls.
       this->ApplyPass(&pass_me_data_holder_, pass);
 
-      bool should_dump = ((c_unit->enable_debug & (1 << kDebugDumpCFG)) != 0);
+      bool should_dump = (c_unit->enable_debug & (1 << kDebugDumpCFG)) != 0;
 
-      const char* dump_pass_list = PassDriver<PassDriverType>::dump_pass_list_.c_str();
-
-      if (dump_pass_list != nullptr) {
-        bool found = strstr(dump_pass_list, pass->GetName());
-        should_dump = (should_dump || found);
+      const std::string& dump_pass_list = pass_manager_->GetOptions().GetDumpPassList();
+      if (!dump_pass_list.empty()) {
+        const bool found = strstr(dump_pass_list.c_str(), pass->GetName());
+        should_dump = should_dump || found;
       }
 
       if (should_dump) {
@@ -154,22 +160,23 @@
     return should_apply_pass;
   }
 
-  const char* GetDumpCFGFolder() const {
-    return dump_cfg_folder_;
-  }
-
-  static void PrintPassOptions() {
-    for (auto pass : PassDriver<PassDriverType>::g_default_pass_list) {
+  static void PrintPassOptions(PassManager* manager) {
+    for (const auto* pass : *manager->GetDefaultPassList()) {
       const PassME* me_pass = down_cast<const PassME*>(pass);
       if (me_pass->HasOptions()) {
         LOG(INFO) << "Pass options for \"" << me_pass->GetName() << "\" are:";
         SafeMap<const std::string, int> overridden_settings;
-        FillOverriddenPassSettings(me_pass->GetName(), overridden_settings);
+        FillOverriddenPassSettings(&manager->GetOptions(), me_pass->GetName(),
+                                   overridden_settings);
         me_pass->PrintPassOptions(overridden_settings);
       }
     }
   }
 
+  const char* GetDumpCFGFolder() const {
+    return dump_cfg_folder_;
+  }
+
  protected:
   /** @brief The data holder that contains data needed for the PassDriverME. */
   PassMEDataHolder pass_me_data_holder_;
@@ -198,12 +205,15 @@
     }
 
   /**
-   * @brief Fills the settings_to_fill by finding all of the applicable options in the overridden_pass_options_list_.
+   * @brief Fills the settings_to_fill by finding all of the applicable options in the
+   * overridden_pass_options_list_.
    * @param pass_name The pass name for which to fill settings.
-   * @param settings_to_fill Fills the options to contain the mapping of name of option to the new configuration.
+   * @param settings_to_fill Fills the options to contain the mapping of name of option to the new
+   * configuration.
    */
-  static void FillOverriddenPassSettings(const char* pass_name, SafeMap<const std::string, int>& settings_to_fill) {
-    const std::string& settings = PassDriver<PassDriverType>::overridden_pass_options_list_;
+  static void FillOverriddenPassSettings(const PassManagerOptions* options, const char* pass_name,
+                                         SafeMap<const std::string, int>& settings_to_fill) {
+    const std::string& settings = options->GetOverriddenPassOptions();
     const size_t settings_len = settings.size();
 
     // Before anything, check if we care about anything right now.
@@ -277,10 +287,12 @@
 
       // Get the actual setting itself. Strtol is being used to convert because it is
       // exception safe. If the input is not sane, it will set a setting of 0.
-      std::string setting_string = settings.substr(setting_pos, next_configuration_separator - setting_pos);
+      std::string setting_string =
+          settings.substr(setting_pos, next_configuration_separator - setting_pos);
       int setting = std::strtol(setting_string.c_str(), 0, 0);
 
-      std::string setting_name = settings.substr(setting_name_pos, setting_pos - setting_name_pos - 1);
+      std::string setting_name =
+          settings.substr(setting_name_pos, setting_pos - setting_name_pos - 1);
 
       settings_to_fill.Put(setting_name, setting);
 
diff --git a/compiler/dex/pass_driver_me_opts.cc b/compiler/dex/pass_driver_me_opts.cc
index c2b6b91..8c8bde6 100644
--- a/compiler/dex/pass_driver_me_opts.cc
+++ b/compiler/dex/pass_driver_me_opts.cc
@@ -21,77 +21,44 @@
 #include "bb_optimizations.h"
 #include "dataflow_iterator.h"
 #include "dataflow_iterator-inl.h"
+#include "pass_driver_me_opts.h"
+#include "pass_manager.h"
 #include "post_opt_passes.h"
 
 namespace art {
 
-/*
- * 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.
- */
-// The initial list of passes to be used by the PassDriveMEOpts.
-template<>
-const Pass* const PassDriver<PassDriverMEOpts>::g_passes[] = {
-  GetPassInstance<CacheFieldLoweringInfo>(),
-  GetPassInstance<CacheMethodLoweringInfo>(),
-  GetPassInstance<CalculatePredecessors>(),
-  GetPassInstance<DFSOrders>(),
-  GetPassInstance<ClassInitCheckElimination>(),
-  GetPassInstance<SpecialMethodInliner>(),
-  GetPassInstance<NullCheckElimination>(),
-  GetPassInstance<BBCombine>(),
-  GetPassInstance<CodeLayout>(),
-  GetPassInstance<GlobalValueNumberingPass>(),
-  GetPassInstance<ConstantPropagation>(),
-  GetPassInstance<MethodUseCount>(),
-  GetPassInstance<BBOptimizations>(),
-  GetPassInstance<SuspendCheckElimination>(),
-};
-
-// The number of the passes in the initial list of Passes (g_passes).
-template<>
-uint16_t const PassDriver<PassDriverMEOpts>::g_passes_size =
-    arraysize(PassDriver<PassDriverMEOpts>::g_passes);
-
-// The default pass list is used by the PassDriverME instance of PassDriver
-// to initialize pass_list_.
-template<>
-std::vector<const Pass*> PassDriver<PassDriverMEOpts>::g_default_pass_list(
-    PassDriver<PassDriverMEOpts>::g_passes,
-    PassDriver<PassDriverMEOpts>::g_passes +
-    PassDriver<PassDriverMEOpts>::g_passes_size);
-
-// By default, do not have a dump pass list.
-template<>
-std::string PassDriver<PassDriverMEOpts>::dump_pass_list_ = std::string();
-
-// By default, do not have a print pass list.
-template<>
-std::string PassDriver<PassDriverMEOpts>::print_pass_list_ = std::string();
-
-// By default, we do not print the pass' information.
-template<>
-bool PassDriver<PassDriverMEOpts>::default_print_passes_ = false;
-
-// By default, there are no overridden pass settings.
-template<>
-std::string PassDriver<PassDriverMEOpts>::overridden_pass_options_list_ = std::string();
+void PassDriverMEOpts::SetupPasses(PassManager* pass_manager) {
+  /*
+   * 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.
+   */
+  pass_manager->AddPass(new CacheFieldLoweringInfo);
+  pass_manager->AddPass(new CacheMethodLoweringInfo);
+  pass_manager->AddPass(new CalculatePredecessors);
+  pass_manager->AddPass(new DFSOrders);
+  pass_manager->AddPass(new ClassInitCheckElimination);
+  pass_manager->AddPass(new SpecialMethodInliner);
+  pass_manager->AddPass(new NullCheckElimination);
+  pass_manager->AddPass(new BBCombine);
+  pass_manager->AddPass(new CodeLayout);
+  pass_manager->AddPass(new GlobalValueNumberingPass);
+  pass_manager->AddPass(new ConstantPropagation);
+  pass_manager->AddPass(new MethodUseCount);
+  pass_manager->AddPass(new BBOptimizations);
+  pass_manager->AddPass(new SuspendCheckElimination);
+}
 
 void PassDriverMEOpts::ApplyPass(PassDataHolder* data, const Pass* pass) {
-  const PassME* pass_me = down_cast<const PassME*> (pass);
+  const PassME* const pass_me = down_cast<const PassME*>(pass);
   DCHECK(pass_me != nullptr);
-
-  PassMEDataHolder* pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
-
+  PassMEDataHolder* const pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
   // Set to dirty.
   pass_me_data_holder->dirty = true;
-
   // First call the base class' version.
   PassDriver::ApplyPass(data, pass);
-
   // Now we care about flags.
   if ((pass_me->GetFlag(kOptimizationBasicBlockChange) == true) ||
       (pass_me->GetFlag(kOptimizationDefUsesChange) == true)) {
diff --git a/compiler/dex/pass_driver_me_opts.h b/compiler/dex/pass_driver_me_opts.h
index 0a5b5ae..b930d02 100644
--- a/compiler/dex/pass_driver_me_opts.h
+++ b/compiler/dex/pass_driver_me_opts.h
@@ -25,19 +25,26 @@
 struct CompilationUnit;
 class Pass;
 class PassDataHolder;
+class PassManager;
 
-class PassDriverMEOpts : public PassDriverME<PassDriverMEOpts> {
+class PassDriverMEOpts : public PassDriverME {
  public:
-  explicit PassDriverMEOpts(CompilationUnit* cu):PassDriverME<PassDriverMEOpts>(cu) {
+  explicit PassDriverMEOpts(const PassManager* const manager, CompilationUnit* cu)
+      : PassDriverME(manager, cu) {
   }
 
   ~PassDriverMEOpts() {
   }
 
   /**
+   * @brief Write and allocate corresponding passes into the pass manager.
+   */
+  static void SetupPasses(PassManager* pass_manasger);
+
+  /**
    * @brief Apply a patch: perform start/work/end functions.
    */
-  virtual void ApplyPass(PassDataHolder* data, const Pass* pass);
+  virtual void ApplyPass(PassDataHolder* data, const Pass* pass) OVERRIDE;
 };
 
 }  // namespace art
diff --git a/compiler/dex/pass_driver_me_post_opt.cc b/compiler/dex/pass_driver_me_post_opt.cc
index 5f0c65c..4e13227 100644
--- a/compiler/dex/pass_driver_me_post_opt.cc
+++ b/compiler/dex/pass_driver_me_post_opt.cc
@@ -14,63 +14,35 @@
  * limitations under the License.
  */
 
+#include "pass_driver_me_post_opt.h"
+
 #include "base/macros.h"
 #include "post_opt_passes.h"
-#include "pass_driver_me_post_opt.h"
+#include "pass_manager.h"
 
 namespace art {
 
-/*
- * 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.
- */
-// The initial list of passes to be used by the PassDriveMEPostOpt.
-template<>
-const Pass* const PassDriver<PassDriverMEPostOpt>::g_passes[] = {
-    GetPassInstance<DFSOrders>(),
-    GetPassInstance<BuildDomination>(),
-    GetPassInstance<TopologicalSortOrders>(),
-    GetPassInstance<InitializeSSATransformation>(),
-    GetPassInstance<ClearPhiInstructions>(),
-    GetPassInstance<DefBlockMatrix>(),
-    GetPassInstance<CreatePhiNodes>(),
-    GetPassInstance<SSAConversion>(),
-    GetPassInstance<PhiNodeOperands>(),
-    GetPassInstance<PerformInitRegLocations>(),
-    GetPassInstance<TypeInference>(),
-    GetPassInstance<FinishSSATransformation>(),
-};
-
-// The number of the passes in the initial list of Passes (g_passes).
-template<>
-uint16_t const PassDriver<PassDriverMEPostOpt>::g_passes_size =
-    arraysize(PassDriver<PassDriverMEPostOpt>::g_passes);
-
-// The default pass list is used by the PassDriverME instance of PassDriver
-// to initialize pass_list_.
-template<>
-std::vector<const Pass*> PassDriver<PassDriverMEPostOpt>::g_default_pass_list(
-    PassDriver<PassDriverMEPostOpt>::g_passes,
-    PassDriver<PassDriverMEPostOpt>::g_passes +
-    PassDriver<PassDriverMEPostOpt>::g_passes_size);
-
-// By default, do not have a dump pass list.
-template<>
-std::string PassDriver<PassDriverMEPostOpt>::dump_pass_list_ = std::string();
-
-// By default, do not have a print pass list.
-template<>
-std::string PassDriver<PassDriverMEPostOpt>::print_pass_list_ = std::string();
-
-// By default, we do not print the pass' information.
-template<>
-bool PassDriver<PassDriverMEPostOpt>::default_print_passes_ = false;
-
-// By default, there are no overridden pass settings.
-template<>
-std::string PassDriver<PassDriverMEPostOpt>::overridden_pass_options_list_ = std::string();
+void PassDriverMEPostOpt::SetupPasses(PassManager* pass_manager) {
+  /*
+   * 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.
+   */
+  // The initial list of passes to be used by the PassDriveMEPostOpt.
+  pass_manager->AddPass(new DFSOrders);
+  pass_manager->AddPass(new BuildDomination);
+  pass_manager->AddPass(new TopologicalSortOrders);
+  pass_manager->AddPass(new InitializeSSATransformation);
+  pass_manager->AddPass(new ClearPhiInstructions);
+  pass_manager->AddPass(new DefBlockMatrix);
+  pass_manager->AddPass(new CreatePhiNodes);
+  pass_manager->AddPass(new SSAConversion);
+  pass_manager->AddPass(new PhiNodeOperands);
+  pass_manager->AddPass(new PerformInitRegLocations);
+  pass_manager->AddPass(new TypeInference);
+  pass_manager->AddPass(new FinishSSATransformation);
+}
 
 }  // namespace art
diff --git a/compiler/dex/pass_driver_me_post_opt.h b/compiler/dex/pass_driver_me_post_opt.h
index 574a6ba..9e03c4e 100644
--- a/compiler/dex/pass_driver_me_post_opt.h
+++ b/compiler/dex/pass_driver_me_post_opt.h
@@ -26,13 +26,19 @@
 class Pass;
 class PassDataHolder;
 
-class PassDriverMEPostOpt : public PassDriverME<PassDriverMEPostOpt> {
+class PassDriverMEPostOpt : public PassDriverME {
  public:
-  explicit PassDriverMEPostOpt(CompilationUnit* cu) : PassDriverME<PassDriverMEPostOpt>(cu) {
+  explicit PassDriverMEPostOpt(const PassManager* const manager, CompilationUnit* cu)
+      : PassDriverME(manager, cu) {
   }
 
   ~PassDriverMEPostOpt() {
   }
+
+  /**
+   * @brief Write and allocate corresponding passes into the pass manager.
+   */
+  static void SetupPasses(PassManager* pass_manager);
 };
 
 }  // namespace art
diff --git a/compiler/dex/pass_manager.cc b/compiler/dex/pass_manager.cc
new file mode 100644
index 0000000..6d58f65
--- /dev/null
+++ b/compiler/dex/pass_manager.cc
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pass_manager.h"
+
+#include "base/stl_util.h"
+#include "pass_me.h"
+
+namespace art {
+
+PassManager::PassManager(const PassManagerOptions& options) : options_(options) {
+}
+
+PassManager::~PassManager() {
+  STLDeleteElements(&passes_);
+}
+
+void PassManager::CreateDefaultPassList() {
+  default_pass_list_.clear();
+  // Add each pass which isn't disabled into default_pass_list_.
+  for (const auto* pass : passes_) {
+    if (options_.GetDisablePassList().find(pass->GetName()) != std::string::npos) {
+      LOG(INFO) << "Skipping disabled pass " << pass->GetName();
+    } else {
+      default_pass_list_.push_back(pass);
+    }
+  }
+}
+
+void PassManager::PrintPassNames() const {
+  LOG(INFO) << "Loop Passes are:";
+  for (const Pass* cur_pass : default_pass_list_) {
+    LOG(INFO) << "\t-" << cur_pass->GetName();
+  }
+}
+
+}  // namespace art
diff --git a/compiler/dex/pass_manager.h b/compiler/dex/pass_manager.h
new file mode 100644
index 0000000..68e488d
--- /dev/null
+++ b/compiler/dex/pass_manager.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_COMPILER_DEX_PASS_MANAGER_H_
+#define ART_COMPILER_DEX_PASS_MANAGER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/logging.h"
+
+namespace art {
+
+class Pass;
+
+class PassManagerOptions {
+ public:
+  PassManagerOptions()
+     : default_print_passes_(false),
+       print_pass_names_(false),
+       print_pass_options_(false) {
+  }
+  explicit PassManagerOptions(const PassManagerOptions&) = default;
+
+  void SetPrintPassNames(bool b) {
+    print_pass_names_ = b;
+  }
+
+  void SetPrintAllPasses() {
+    default_print_passes_ = true;
+  }
+  bool GetPrintAllPasses() const {
+    return default_print_passes_;
+  }
+
+  void SetDisablePassList(const std::string& list) {
+    disable_pass_list_ = list;
+  }
+  const std::string& GetDisablePassList() const {
+    return disable_pass_list_;
+  }
+
+  void SetPrintPassList(const std::string& list) {
+    print_pass_list_ = list;
+  }
+  const std::string& GetPrintPassList() const {
+    return print_pass_list_;
+  }
+
+  void SetDumpPassList(const std::string& list) {
+    dump_pass_list_ = list;
+  }
+  const std::string& GetDumpPassList() const {
+    return dump_pass_list_;
+  }
+
+  /**
+   * @brief Used to set a string that contains the overridden pass options.
+   * @details An overridden pass option means that the pass uses this option
+   * instead of using its default option.
+   * @param s The string passed by user with overridden options. The string is in format
+   * Pass1Name:Pass1Option:Pass1Setting,Pass2Name:Pass2Option::Pass2Setting
+   */
+  void SetOverriddenPassOptions(const std::string& list) {
+    overridden_pass_options_list_ = list;
+  }
+  const std::string& GetOverriddenPassOptions() const {
+    return overridden_pass_options_list_;
+  }
+
+  void SetPrintPassOptions(bool b) {
+    print_pass_options_ = b;
+  }
+  bool GetPrintPassOptions() const {
+    return print_pass_options_;
+  }
+
+ private:
+  /** @brief Do we, by default, want to be printing the log messages? */
+  bool default_print_passes_;
+
+  /** @brief What are the passes we want to be printing the log messages? */
+  std::string print_pass_list_;
+
+  /** @brief What are the passes we want to be dumping the CFG? */
+  std::string dump_pass_list_;
+
+  /** @brief String of all options that should be overridden for selected passes */
+  std::string overridden_pass_options_list_;
+
+  /** @brief String of all options that should be overridden for selected passes */
+  std::string disable_pass_list_;
+
+  /** @brief Whether or not we print all the passes when we create the pass manager */
+  bool print_pass_names_;
+
+  /** @brief Whether or not we print all the pass options when we create the pass manager */
+  bool print_pass_options_;
+};
+
+/**
+ * @class PassManager
+ * @brief Owns passes
+ */
+class PassManager {
+ public:
+  explicit PassManager(const PassManagerOptions& options);
+  virtual ~PassManager();
+  void CreateDefaultPassList();
+  void AddPass(const Pass* pass) {
+    passes_.push_back(pass);
+  }
+  /**
+   * @brief Print the pass names of all the passes available.
+   */
+  void PrintPassNames() const;
+  const std::vector<const Pass*>* GetDefaultPassList() const {
+    return &default_pass_list_;
+  }
+  const PassManagerOptions& GetOptions() const {
+    return options_;
+  }
+
+ private:
+  /** @brief The set of possible passes.  */
+  std::vector<const Pass*> passes_;
+
+  /** @brief The default pass list is used to initialize pass_list_. */
+  std::vector<const Pass*> default_pass_list_;
+
+  /** @brief Pass manager options. */
+  PassManagerOptions options_;
+
+  DISALLOW_COPY_AND_ASSIGN(PassManager);
+};
+}  // namespace art
+#endif  // ART_COMPILER_DEX_PASS_MANAGER_H_
diff --git a/compiler/dex/pass_me.h b/compiler/dex/pass_me.h
index 73e49ec..79d8f51 100644
--- a/compiler/dex/pass_me.h
+++ b/compiler/dex/pass_me.h
@@ -42,11 +42,11 @@
 
 // Data holder class.
 class PassMEDataHolder: public PassDataHolder {
-  public:
-    CompilationUnit* c_unit;
-    BasicBlock* bb;
-    void* data;               /**< @brief Any data the pass wants to use */
-    bool dirty;               /**< @brief Has the pass rendered the CFG dirty, requiring post-opt? */
+ public:
+  CompilationUnit* c_unit;
+  BasicBlock* bb;
+  void* data;               /**< @brief Any data the pass wants to use */
+  bool dirty;               /**< @brief Has the pass rendered the CFG dirty, requiring post-opt? */
 };
 
 enum DataFlowAnalysisMode {
@@ -103,8 +103,8 @@
    * @details The printing is done using LOG(INFO).
    */
   void PrintPassDefaultOptions() const {
-    for (auto option_it = default_options_.begin(); option_it != default_options_.end(); option_it++) {
-      LOG(INFO) << "\t" << option_it->first << ":" << std::dec << option_it->second;
+    for (const auto& option : default_options_) {
+      LOG(INFO) << "\t" << option.first << ":" << std::dec << option.second;
     }
   }
 
@@ -115,8 +115,9 @@
   void PrintPassOptions(SafeMap<const std::string, int>& overridden_options) const {
     // We walk through the default options only to get the pass names. We use GetPassOption to
     // also consider the overridden ones.
-    for (auto option_it = default_options_.begin(); option_it != default_options_.end(); option_it++) {
-      LOG(INFO) << "\t" << option_it->first << ":" << std::dec << GetPassOption(option_it->first, overridden_options);
+    for (const auto& option : default_options_) {
+      LOG(INFO) << "\t" << option.first << ":" << std::dec
+                << GetPassOption(option.first, overridden_options);
     }
   }
 
diff --git a/compiler/dex/quick/quick_compiler.cc b/compiler/dex/quick/quick_compiler.cc
index 3a34fcd..909077e 100644
--- a/compiler/dex/quick/quick_compiler.cc
+++ b/compiler/dex/quick/quick_compiler.cc
@@ -29,6 +29,8 @@
 #include "dex/dex_flags.h"
 #include "dex/mir_graph.h"
 #include "dex/pass_driver_me_opts.h"
+#include "dex/pass_driver_me_post_opt.h"
+#include "dex/pass_manager.h"
 #include "dex/quick/mir_to_lir.h"
 #include "driver/compiler_driver.h"
 #include "driver/compiler_options.h"
@@ -47,48 +49,6 @@
 
 namespace art {
 
-class QuickCompiler FINAL : public Compiler {
- public:
-  explicit QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) {}
-
-  void Init() OVERRIDE;
-
-  void UnInit() const OVERRIDE;
-
-  bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit* cu) const
-      OVERRIDE;
-
-  CompiledMethod* Compile(const DexFile::CodeItem* code_item,
-                          uint32_t access_flags,
-                          InvokeType invoke_type,
-                          uint16_t class_def_idx,
-                          uint32_t method_idx,
-                          jobject class_loader,
-                          const DexFile& dex_file) const OVERRIDE;
-
-  CompiledMethod* JniCompile(uint32_t access_flags,
-                             uint32_t method_idx,
-                             const DexFile& dex_file) const OVERRIDE;
-
-  uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const OVERRIDE
-      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  bool WriteElf(art::File* file,
-                OatWriter* oat_writer,
-                const std::vector<const art::DexFile*>& dex_files,
-                const std::string& android_root,
-                bool is_host) const
-    OVERRIDE
-    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
-  Mir2Lir* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const;
-
-  void InitCompilationUnit(CompilationUnit& cu) const OVERRIDE;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(QuickCompiler);
-};
-
 static_assert(0U == static_cast<size_t>(kNone),   "kNone not 0");
 static_assert(1U == static_cast<size_t>(kArm),    "kArm not 1");
 static_assert(2U == static_cast<size_t>(kArm64),  "kArm64 not 2");
@@ -730,7 +690,7 @@
   }
 
   /* Create the pass driver and launch it */
-  PassDriverMEOpts pass_driver(&cu);
+  PassDriverMEOpts pass_driver(GetPreOptPassManager(), &cu);
   pass_driver.Launch();
 
   /* For non-leaf methods check if we should skip compilation when the profiler is enabled. */
@@ -850,8 +810,34 @@
   return mir_to_lir;
 }
 
+QuickCompiler::QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) {
+  const auto& compiler_options = driver->GetCompilerOptions();
+  auto* pass_manager_options = compiler_options.GetPassManagerOptions();
+  pre_opt_pass_manager_.reset(new PassManager(*pass_manager_options));
+  CHECK(pre_opt_pass_manager_.get() != nullptr);
+  PassDriverMEOpts::SetupPasses(pre_opt_pass_manager_.get());
+  pre_opt_pass_manager_->CreateDefaultPassList();
+  if (pass_manager_options->GetPrintPassOptions()) {
+    PassDriverMEOpts::PrintPassOptions(pre_opt_pass_manager_.get());
+  }
+  // TODO: Different options for pre vs post opts?
+  post_opt_pass_manager_.reset(new PassManager(PassManagerOptions()));
+  CHECK(post_opt_pass_manager_.get() != nullptr);
+  PassDriverMEPostOpt::SetupPasses(post_opt_pass_manager_.get());
+  post_opt_pass_manager_->CreateDefaultPassList();
+  if (pass_manager_options->GetPrintPassOptions()) {
+    PassDriverMEPostOpt::PrintPassOptions(post_opt_pass_manager_.get());
+  }
+}
+
+QuickCompiler::~QuickCompiler() {
+}
 
 Compiler* CreateQuickCompiler(CompilerDriver* driver) {
+  return QuickCompiler::Create(driver);
+}
+
+Compiler* QuickCompiler::Create(CompilerDriver* driver) {
   return new QuickCompiler(driver);
 }
 
diff --git a/compiler/dex/quick/quick_compiler.h b/compiler/dex/quick/quick_compiler.h
index 10de5fb..5153a9e 100644
--- a/compiler/dex/quick/quick_compiler.h
+++ b/compiler/dex/quick/quick_compiler.h
@@ -17,12 +17,70 @@
 #ifndef ART_COMPILER_DEX_QUICK_QUICK_COMPILER_H_
 #define ART_COMPILER_DEX_QUICK_QUICK_COMPILER_H_
 
+#include "compiler.h"
+
 namespace art {
 
 class Compiler;
 class CompilerDriver;
+class Mir2Lir;
+class PassManager;
 
-Compiler* CreateQuickCompiler(CompilerDriver* driver);
+class QuickCompiler : public Compiler {
+ public:
+  virtual ~QuickCompiler();
+
+  void Init() OVERRIDE;
+
+  void UnInit() const OVERRIDE;
+
+  bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit* cu) const
+      OVERRIDE;
+
+  CompiledMethod* Compile(const DexFile::CodeItem* code_item,
+                          uint32_t access_flags,
+                          InvokeType invoke_type,
+                          uint16_t class_def_idx,
+                          uint32_t method_idx,
+                          jobject class_loader,
+                          const DexFile& dex_file) const OVERRIDE;
+
+  CompiledMethod* JniCompile(uint32_t access_flags,
+                             uint32_t method_idx,
+                             const DexFile& dex_file) const OVERRIDE;
+
+  uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const OVERRIDE
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  bool WriteElf(art::File* file,
+                OatWriter* oat_writer,
+                const std::vector<const art::DexFile*>& dex_files,
+                const std::string& android_root,
+                bool is_host) const
+    OVERRIDE
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  Mir2Lir* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const;
+
+  void InitCompilationUnit(CompilationUnit& cu) const OVERRIDE;
+
+  static Compiler* Create(CompilerDriver* driver);
+
+  const PassManager* GetPreOptPassManager() const {
+    return pre_opt_pass_manager_.get();
+  }
+  const PassManager* GetPostOptPassManager() const {
+    return post_opt_pass_manager_.get();
+  }
+
+ protected:
+  explicit QuickCompiler(CompilerDriver* driver);
+
+ private:
+  std::unique_ptr<PassManager> pre_opt_pass_manager_;
+  std::unique_ptr<PassManager> post_opt_pass_manager_;
+  DISALLOW_COPY_AND_ASSIGN(QuickCompiler);
+};
 
 }  // namespace art
 
diff --git a/compiler/dex/quick/quick_compiler_factory.h b/compiler/dex/quick/quick_compiler_factory.h
new file mode 100644
index 0000000..31ee1cf
--- /dev/null
+++ b/compiler/dex/quick/quick_compiler_factory.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_COMPILER_DEX_QUICK_QUICK_COMPILER_FACTORY_H_
+#define ART_COMPILER_DEX_QUICK_QUICK_COMPILER_FACTORY_H_
+
+namespace art {
+
+class Compiler;
+class CompilerDriver;
+
+Compiler* CreateQuickCompiler(CompilerDriver* driver);
+
+}  // namespace art
+
+#endif  // ART_COMPILER_DEX_QUICK_QUICK_COMPILER_FACTORY_H_
diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc
new file mode 100644
index 0000000..09ec9a2
--- /dev/null
+++ b/compiler/driver/compiler_options.cc
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "compiler_options.h"
+
+#include "dex/pass_manager.h"
+
+namespace art {
+
+CompilerOptions::CompilerOptions()
+    : compiler_filter_(kDefaultCompilerFilter),
+      huge_method_threshold_(kDefaultHugeMethodThreshold),
+      large_method_threshold_(kDefaultLargeMethodThreshold),
+      small_method_threshold_(kDefaultSmallMethodThreshold),
+      tiny_method_threshold_(kDefaultTinyMethodThreshold),
+      num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold),
+      generate_gdb_information_(false),
+      include_patch_information_(kDefaultIncludePatchInformation),
+      top_k_profile_threshold_(kDefaultTopKProfileThreshold),
+      include_debug_symbols_(kDefaultIncludeDebugSymbols),
+      implicit_null_checks_(true),
+      implicit_so_checks_(true),
+      implicit_suspend_checks_(false),
+      compile_pic_(false),
+      verbose_methods_(nullptr),
+      pass_manager_options_(new PassManagerOptions),
+      init_failure_output_(nullptr) {
+}
+
+CompilerOptions::CompilerOptions(CompilerFilter compiler_filter,
+                                 size_t huge_method_threshold,
+                                 size_t large_method_threshold,
+                                 size_t small_method_threshold,
+                                 size_t tiny_method_threshold,
+                                 size_t num_dex_methods_threshold,
+                                 bool generate_gdb_information,
+                                 bool include_patch_information,
+                                 double top_k_profile_threshold,
+                                 bool include_debug_symbols,
+                                 bool implicit_null_checks,
+                                 bool implicit_so_checks,
+                                 bool implicit_suspend_checks,
+                                 bool compile_pic,
+                                 const std::vector<std::string>* verbose_methods,
+                                 PassManagerOptions* pass_manager_options,
+                                 std::ostream* init_failure_output
+                                 ) :  // NOLINT(whitespace/parens)
+    compiler_filter_(compiler_filter),
+    huge_method_threshold_(huge_method_threshold),
+    large_method_threshold_(large_method_threshold),
+    small_method_threshold_(small_method_threshold),
+    tiny_method_threshold_(tiny_method_threshold),
+    num_dex_methods_threshold_(num_dex_methods_threshold),
+    generate_gdb_information_(generate_gdb_information),
+    include_patch_information_(include_patch_information),
+    top_k_profile_threshold_(top_k_profile_threshold),
+    include_debug_symbols_(include_debug_symbols),
+    implicit_null_checks_(implicit_null_checks),
+    implicit_so_checks_(implicit_so_checks),
+    implicit_suspend_checks_(implicit_suspend_checks),
+    compile_pic_(compile_pic),
+    verbose_methods_(verbose_methods),
+    pass_manager_options_(pass_manager_options),
+    init_failure_output_(init_failure_output) {
+}
+
+}  // namespace art
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index 5466d45..122ae4b 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -26,6 +26,8 @@
 
 namespace art {
 
+class PassManagerOptions;
+
 class CompilerOptions FINAL {
  public:
   enum CompilerFilter {
@@ -53,24 +55,7 @@
   static const bool kDefaultIncludeDebugSymbols = kIsDebugBuild;
   static const bool kDefaultIncludePatchInformation = false;
 
-  CompilerOptions() :
-    compiler_filter_(kDefaultCompilerFilter),
-    huge_method_threshold_(kDefaultHugeMethodThreshold),
-    large_method_threshold_(kDefaultLargeMethodThreshold),
-    small_method_threshold_(kDefaultSmallMethodThreshold),
-    tiny_method_threshold_(kDefaultTinyMethodThreshold),
-    num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold),
-    generate_gdb_information_(false),
-    include_patch_information_(kDefaultIncludePatchInformation),
-    top_k_profile_threshold_(kDefaultTopKProfileThreshold),
-    include_debug_symbols_(kDefaultIncludeDebugSymbols),
-    implicit_null_checks_(true),
-    implicit_so_checks_(true),
-    implicit_suspend_checks_(false),
-    compile_pic_(false),
-    verbose_methods_(nullptr),
-    init_failure_output_(nullptr) {
-  }
+  CompilerOptions();
 
   CompilerOptions(CompilerFilter compiler_filter,
                   size_t huge_method_threshold,
@@ -87,25 +72,8 @@
                   bool implicit_suspend_checks,
                   bool compile_pic,
                   const std::vector<std::string>* verbose_methods,
-                  std::ostream* init_failure_output
-                  ) :  // NOLINT(whitespace/parens)
-    compiler_filter_(compiler_filter),
-    huge_method_threshold_(huge_method_threshold),
-    large_method_threshold_(large_method_threshold),
-    small_method_threshold_(small_method_threshold),
-    tiny_method_threshold_(tiny_method_threshold),
-    num_dex_methods_threshold_(num_dex_methods_threshold),
-    generate_gdb_information_(generate_gdb_information),
-    include_patch_information_(include_patch_information),
-    top_k_profile_threshold_(top_k_profile_threshold),
-    include_debug_symbols_(include_debug_symbols),
-    implicit_null_checks_(implicit_null_checks),
-    implicit_so_checks_(implicit_so_checks),
-    implicit_suspend_checks_(implicit_suspend_checks),
-    compile_pic_(compile_pic),
-    verbose_methods_(verbose_methods),
-    init_failure_output_(init_failure_output) {
-  }
+                  PassManagerOptions* pass_manager_options,
+                  std::ostream* init_failure_output);
 
   CompilerFilter GetCompilerFilter() const {
     return compiler_filter_;
@@ -210,6 +178,10 @@
     return init_failure_output_;
   }
 
+  const PassManagerOptions* GetPassManagerOptions() const {
+    return pass_manager_options_.get();
+  }
+
  private:
   CompilerFilter compiler_filter_;
   const size_t huge_method_threshold_;
@@ -230,6 +202,8 @@
   // Vector of methods to have verbose output enabled for.
   const std::vector<std::string>* const verbose_methods_;
 
+  std::unique_ptr<PassManagerOptions> pass_manager_options_;
+
   // Log initialization of initialization failures to this stream if not null.
   std::ostream* const init_failure_output_;
 
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index d3d2055..46aed60 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -18,9 +18,10 @@
 #include "class_linker.h"
 #include "common_compiler_test.h"
 #include "compiler.h"
-#include "dex/verification_results.h"
+#include "dex/pass_manager.h"
 #include "dex/quick/dex_file_to_method_inliner_map.h"
 #include "dex/quick_compiler_callbacks.h"
+#include "dex/verification_results.h"
 #include "entrypoints/quick/quick_entrypoints.h"
 #include "mirror/art_method-inl.h"
 #include "mirror/class-inl.h"
diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h
index b3eb1e2..29d47e1 100644
--- a/compiler/optimizing/optimizing_unit_test.h
+++ b/compiler/optimizing/optimizing_unit_test.h
@@ -19,6 +19,7 @@
 
 #include "nodes.h"
 #include "builder.h"
+#include "compiler/dex/pass_manager.h"
 #include "dex_file.h"
 #include "dex_instruction.h"
 #include "ssa_liveness_analysis.h"
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index fe3a978..e607e15 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -44,7 +44,7 @@
 #include "compiler.h"
 #include "compiler_callbacks.h"
 #include "dex_file-inl.h"
-#include "dex/pass_driver_me_opts.h"
+#include "dex/pass_manager.h"
 #include "dex/verification_results.h"
 #include "dex/quick_compiler_callbacks.h"
 #include "dex/quick/dex_file_to_method_inliner_map.h"
@@ -490,12 +490,13 @@
     // Profile file to use
     double top_k_profile_threshold = CompilerOptions::kDefaultTopKProfileThreshold;
 
-    bool print_pass_options = false;
     bool include_patch_information = CompilerOptions::kDefaultIncludePatchInformation;
     bool include_debug_symbols = kIsDebugBuild;
     bool watch_dog_enabled = true;
     bool generate_gdb_information = kIsDebugBuild;
 
+    PassManagerOptions pass_manager_options;
+
     std::string error_msg;
 
     for (int i = 0; i < argc; i++) {
@@ -685,23 +686,23 @@
       } else if (option.starts_with("--top-k-profile-threshold=")) {
         ParseDouble(option.data(), '=', 0.0, 100.0, &top_k_profile_threshold);
       } else if (option == "--print-pass-names") {
-        PassDriverMEOpts::PrintPassNames();
+        pass_manager_options.SetPrintPassNames(true);
       } else if (option.starts_with("--disable-passes=")) {
-        std::string disable_passes = option.substr(strlen("--disable-passes=")).data();
-        PassDriverMEOpts::CreateDefaultPassList(disable_passes);
+        const std::string disable_passes = option.substr(strlen("--disable-passes=")).data();
+        pass_manager_options.SetDisablePassList(disable_passes);
       } else if (option.starts_with("--print-passes=")) {
-        std::string print_passes = option.substr(strlen("--print-passes=")).data();
-        PassDriverMEOpts::SetPrintPassList(print_passes);
+        const std::string print_passes = option.substr(strlen("--print-passes=")).data();
+        pass_manager_options.SetPrintPassList(print_passes);
       } else if (option == "--print-all-passes") {
-        PassDriverMEOpts::SetPrintAllPasses();
+        pass_manager_options.SetPrintAllPasses();
       } else if (option.starts_with("--dump-cfg-passes=")) {
-        std::string dump_passes_string = option.substr(strlen("--dump-cfg-passes=")).data();
-        PassDriverMEOpts::SetDumpPassList(dump_passes_string);
+        const std::string dump_passes_string = option.substr(strlen("--dump-cfg-passes=")).data();
+        pass_manager_options.SetDumpPassList(dump_passes_string);
       } else if (option == "--print-pass-options") {
-        print_pass_options = true;
+        pass_manager_options.SetPrintPassOptions(true);
       } else if (option.starts_with("--pass-options=")) {
-        std::string options = option.substr(strlen("--pass-options=")).data();
-        PassDriverMEOpts::SetOverriddenPassOptions(options);
+        const std::string options = option.substr(strlen("--pass-options=")).data();
+        pass_manager_options.SetOverriddenPassOptions(options);
       } else if (option == "--include-patch-information") {
         include_patch_information = true;
       } else if (option == "--no-include-patch-information") {
@@ -924,10 +925,6 @@
         break;
     }
 
-    if (print_pass_options) {
-      PassDriverMEOpts::PrintPassOptions();
-    }
-
     compiler_options_.reset(new CompilerOptions(compiler_filter,
                                                 huge_method_threshold,
                                                 large_method_threshold,
@@ -945,6 +942,7 @@
                                                 verbose_methods_.empty() ?
                                                     nullptr :
                                                     &verbose_methods_,
+                                                new PassManagerOptions(pass_manager_options),
                                                 init_failure_output_.get()));
 
     // Done with usage checks, enable watchdog if requested