Implement running user defined list of passes

This change introduces new dex2oat switch --run-passes=. This switch
accepts path to a text file with names of passes to run.
Compiler will run optimization passes specified in the file rather
then the default ones.

There is no verification implemented on the compiler side. It is user's
responsibility to provide a list of passes that leads to successful
generation of correct code. Care should be taken to prepare a list
that satisfies all dependencies between optimizations.

We only take control of the optional optimizations. Codegen (builder),
and all passes required for register allocation will run unaffected
by this mechanism.

Change-Id: Ic3694e53515fefcc5ce6f28d9371776b5afcbb4f
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index cc66d7a..abc58d7 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -76,7 +76,8 @@
                   const std::string& dump_cfg_file_name,
                   bool dump_cfg_append,
                   bool force_determinism,
-                  RegisterAllocator::Strategy regalloc_strategy);
+                  RegisterAllocator::Strategy regalloc_strategy,
+                  const std::vector<std::string>* passes_to_run);
 
   CompilerFilter::Filter GetCompilerFilter() const {
     return compiler_filter_;
@@ -250,6 +251,10 @@
     return register_allocation_strategy_;
   }
 
+  const std::vector<std::string>* GetPassesToRun() const {
+    return passes_to_run_;
+  }
+
  private:
   void ParseDumpInitFailures(const StringPiece& option, UsageFn Usage);
   void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage);
@@ -306,6 +311,14 @@
 
   RegisterAllocator::Strategy register_allocation_strategy_;
 
+  // If not null, specifies optimization passes which will be run instead of defaults.
+  // Note that passes_to_run_ is not checked for correctness and providing an incorrect
+  // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies
+  // between passes. Failing to satisfy them can for example lead to compiler crashes.
+  // Passing pass names which are not recognized by the compiler will result in
+  // compiler-dependant behavior.
+  const std::vector<std::string>* passes_to_run_;
+
   friend class Dex2Oat;
 
   DISALLOW_COPY_AND_ASSIGN(CompilerOptions);