Add the "time" compilation filter and output compilation stats.

A "time" compiler filter means the compiler optimizes for
compile time.

Change-Id: Id1a207ceb2d95f3548aae5e45d51b80695da2029
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 75f4155..a539192 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -38,7 +38,7 @@
  */
 class CodeVectorAllocator FINAL : public CodeAllocator {
  public:
-  CodeVectorAllocator() { }
+  CodeVectorAllocator() {}
 
   virtual uint8_t* Allocate(size_t size) {
     size_ = size;
@@ -70,6 +70,7 @@
 class OptimizingCompiler FINAL : public Compiler {
  public:
   explicit OptimizingCompiler(CompilerDriver* driver);
+  ~OptimizingCompiler();
 
   bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit* cu) const
       OVERRIDE;
@@ -113,6 +114,13 @@
   void UnInit() const OVERRIDE;
 
  private:
+  // Whether we should run any optimization or register allocation. If false, will
+  // just run the code generation after the graph was built.
+  const bool run_optimizations_;
+  mutable AtomicInteger total_compiled_methods_;
+  mutable AtomicInteger unoptimized_compiled_methods_;
+  mutable AtomicInteger optimized_compiled_methods_;
+
   std::unique_ptr<std::ostream> visualizer_output_;
 
   // Delegate to another compiler in case the optimizing compiler cannot compile a method.
@@ -122,8 +130,16 @@
   DISALLOW_COPY_AND_ASSIGN(OptimizingCompiler);
 };
 
-OptimizingCompiler::OptimizingCompiler(CompilerDriver* driver) : Compiler(driver, 100),
-    delegate_(Create(driver, Compiler::Kind::kQuick)) {
+static const int kMaximumCompilationTimeBeforeWarning = 100; /* ms */
+
+OptimizingCompiler::OptimizingCompiler(CompilerDriver* driver)
+    : Compiler(driver, kMaximumCompilationTimeBeforeWarning),
+      run_optimizations_(
+          driver->GetCompilerOptions().GetCompilerFilter() != CompilerOptions::kTime),
+      total_compiled_methods_(0),
+      unoptimized_compiled_methods_(0),
+      optimized_compiled_methods_(0),
+      delegate_(Create(driver, Compiler::Kind::kQuick)) {
   if (kIsVisualizerEnabled) {
     visualizer_output_.reset(new std::ofstream("art.cfg"));
   }
@@ -137,6 +153,14 @@
   delegate_->UnInit();
 }
 
+OptimizingCompiler::~OptimizingCompiler() {
+  size_t unoptimized_percent = (unoptimized_compiled_methods_ * 100 / total_compiled_methods_);
+  size_t optimized_percent = (optimized_compiled_methods_ * 100 / total_compiled_methods_);
+  LOG(INFO) << "Compiled " << total_compiled_methods_ << " methods: "
+            << unoptimized_percent << "% (" << unoptimized_compiled_methods_ << ") unoptimized, "
+            << optimized_percent << "% (" << optimized_compiled_methods_ << ") optimized.";
+}
+
 bool OptimizingCompiler::CanCompileMethod(uint32_t method_idx, const DexFile& dex_file,
                                           CompilationUnit* cu) const {
   return delegate_->CanCompileMethod(method_idx, dex_file, cu);
@@ -173,6 +197,7 @@
                                                uint32_t method_idx,
                                                jobject class_loader,
                                                const DexFile& dex_file) const {
+  total_compiled_methods_++;
   InstructionSet instruction_set = GetCompilerDriver()->GetInstructionSet();
   // Always use the thumb2 assembler: some runtime functionality (like implicit stack
   // overflow checks) assume thumb2.
@@ -222,7 +247,8 @@
 
   CodeVectorAllocator allocator;
 
-  if (RegisterAllocator::CanAllocateRegistersFor(*graph, instruction_set)) {
+  if (run_optimizations_ && RegisterAllocator::CanAllocateRegistersFor(*graph, instruction_set)) {
+    optimized_compiled_methods_++;
     graph->BuildDominatorTree();
     graph->TransformToSSA();
     visualizer.DumpGraph("ssa");
@@ -262,6 +288,7 @@
     LOG(FATAL) << "Could not allocate registers in optimizing compiler";
     return nullptr;
   } else {
+    unoptimized_compiled_methods_++;
     codegen->CompileBaseline(&allocator);
 
     // Run these phases to get some test coverage.