Merge "Add stats support for existing optimizations"
diff --git a/compiler/optimizing/boolean_simplifier.cc b/compiler/optimizing/boolean_simplifier.cc
index f985745..c3e88f3 100644
--- a/compiler/optimizing/boolean_simplifier.cc
+++ b/compiler/optimizing/boolean_simplifier.cc
@@ -36,6 +36,8 @@
   if (!boolean_not->HasUses()) {
     boolean_not->GetBlock()->RemoveInstruction(boolean_not);
   }
+
+  MaybeRecordStat(MethodCompilationStat::kBooleanSimplifier);
 }
 
 // Returns true if 'block1' and 'block2' are empty, merge into the same single
@@ -146,6 +148,8 @@
   block->MergeWith(false_block);
   block->MergeWith(merge_block);
 
+  MaybeRecordStat(MethodCompilationStat::kBooleanSimplifier);
+
   // No need to update any dominance information, as we are simplifying
   // a simple diamond shape, where the join block is merged with the
   // entry block. Any following blocks would have had the join block
diff --git a/compiler/optimizing/boolean_simplifier.h b/compiler/optimizing/boolean_simplifier.h
index e12a12c..0eb6c71 100644
--- a/compiler/optimizing/boolean_simplifier.h
+++ b/compiler/optimizing/boolean_simplifier.h
@@ -62,8 +62,8 @@
 
 class HBooleanSimplifier : public HOptimization {
  public:
-  explicit HBooleanSimplifier(HGraph* graph)
-    : HOptimization(graph, kBooleanSimplifierPassName) {}
+  HBooleanSimplifier(HGraph* graph, OptimizingCompilerStats* stats)
+    : HOptimization(graph, kBooleanSimplifierPassName, stats) {}
 
   void Run() OVERRIDE;
 
diff --git a/compiler/optimizing/constant_folding.cc b/compiler/optimizing/constant_folding.cc
index 57452cc..1db775e 100644
--- a/compiler/optimizing/constant_folding.cc
+++ b/compiler/optimizing/constant_folding.cc
@@ -68,6 +68,7 @@
         } else {
           inst->Accept(&simplifier);
         }
+        MaybeRecordStat(MethodCompilationStat::kConstantFolding);
       } else if (inst->IsUnaryOperation()) {
         // Constant folding: replace `op(a)' with a constant at compile
         // time if `a' is a constant.
@@ -76,6 +77,7 @@
           inst->ReplaceWith(constant);
           inst->GetBlock()->RemoveInstruction(inst);
         }
+        MaybeRecordStat(MethodCompilationStat::kConstantFolding);
       } else if (inst->IsTypeConversion()) {
         // Constant folding: replace `TypeConversion(a)' with a constant at
         // compile time if `a' is a constant.
@@ -84,6 +86,7 @@
           inst->ReplaceWith(constant);
           inst->GetBlock()->RemoveInstruction(inst);
         }
+        MaybeRecordStat(MethodCompilationStat::kConstantFolding);
       } else if (inst->IsDivZeroCheck()) {
         // We can safely remove the check if the input is a non-null constant.
         HDivZeroCheck* check = inst->AsDivZeroCheck();
@@ -92,6 +95,7 @@
           check->ReplaceWith(check_input);
           check->GetBlock()->RemoveInstruction(check);
         }
+        MaybeRecordStat(MethodCompilationStat::kConstantFolding);
       }
     }
   }
diff --git a/compiler/optimizing/constant_folding.h b/compiler/optimizing/constant_folding.h
index 2698b2d..df89371 100644
--- a/compiler/optimizing/constant_folding.h
+++ b/compiler/optimizing/constant_folding.h
@@ -32,8 +32,10 @@
  */
 class HConstantFolding : public HOptimization {
  public:
-  explicit HConstantFolding(HGraph* graph, const char* name = kConstantFoldingPassName)
-      : HOptimization(graph, name) {}
+  HConstantFolding(HGraph* graph,
+                   OptimizingCompilerStats* stats,
+                   const char* name = kConstantFoldingPassName)
+      : HOptimization(graph, name, stats) {}
 
   void Run() OVERRIDE;
 
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 0363f20..b33f6f2 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -395,11 +395,11 @@
 
   // Run simple optimizations on the graph.
   HDeadCodeElimination dce(callee_graph, stats_);
-  HConstantFolding fold(callee_graph);
+  HConstantFolding fold(callee_graph, stats_);
   ReferenceTypePropagation type_propagation(callee_graph, handles_);
   HSharpening sharpening(callee_graph, codegen_, dex_compilation_unit, compiler_driver_);
   InstructionSimplifier simplify(callee_graph, stats_);
-  IntrinsicsRecognizer intrinsics(callee_graph, compiler_driver_);
+  IntrinsicsRecognizer intrinsics(callee_graph, compiler_driver_, stats_);
 
   HOptimization* optimizations[] = {
     &intrinsics,
diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc
index b01324e..9516f01 100644
--- a/compiler/optimizing/intrinsics.cc
+++ b/compiler/optimizing/intrinsics.cc
@@ -438,6 +438,7 @@
                   << invoke->DebugName();
             } else {
               invoke->SetIntrinsic(intrinsic, NeedsEnvironmentOrCache(intrinsic));
+              MaybeRecordStat(MethodCompilationStat::kIntrinsicsRecognizer);
             }
           }
         }
diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h
index e459516..cc4f708 100644
--- a/compiler/optimizing/intrinsics.h
+++ b/compiler/optimizing/intrinsics.h
@@ -30,8 +30,8 @@
 // Recognize intrinsics from HInvoke nodes.
 class IntrinsicsRecognizer : public HOptimization {
  public:
-  IntrinsicsRecognizer(HGraph* graph, CompilerDriver* driver)
-      : HOptimization(graph, kIntrinsicsRecognizerPassName),
+  IntrinsicsRecognizer(HGraph* graph, CompilerDriver* driver, OptimizingCompilerStats* stats)
+      : HOptimization(graph, kIntrinsicsRecognizerPassName, stats),
         driver_(driver) {}
 
   void Run() OVERRIDE;
diff --git a/compiler/optimizing/licm.cc b/compiler/optimizing/licm.cc
index c38bbe3..6d0a616 100644
--- a/compiler/optimizing/licm.cc
+++ b/compiler/optimizing/licm.cc
@@ -123,6 +123,7 @@
             UpdateLoopPhisIn(instruction->GetEnvironment(), loop_info);
           }
           instruction->MoveBefore(pre_header->GetLastInstruction());
+          MaybeRecordStat(MethodCompilationStat::kLICM);
         } else if (instruction->CanThrow()) {
           // If `instruction` can throw, we cannot move further instructions
           // that can throw as well.
diff --git a/compiler/optimizing/licm.h b/compiler/optimizing/licm.h
index 0b5a0f1..bf56f53 100644
--- a/compiler/optimizing/licm.h
+++ b/compiler/optimizing/licm.h
@@ -26,8 +26,9 @@
 
 class LICM : public HOptimization {
  public:
-  LICM(HGraph* graph, const SideEffectsAnalysis& side_effects)
-      : HOptimization(graph, kLoopInvariantCodeMotionPassName), side_effects_(side_effects) {}
+  LICM(HGraph* graph, const SideEffectsAnalysis& side_effects, OptimizingCompilerStats* stats)
+      : HOptimization(graph, kLoopInvariantCodeMotionPassName, stats),
+        side_effects_(side_effects) {}
 
   void Run() OVERRIDE;
 
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 2204921..24f0d77 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -487,10 +487,10 @@
       graph, stats, HDeadCodeElimination::kInitialDeadCodeEliminationPassName);
   HDeadCodeElimination* dce2 = new (arena) HDeadCodeElimination(
       graph, stats, HDeadCodeElimination::kFinalDeadCodeEliminationPassName);
-  HConstantFolding* fold1 = new (arena) HConstantFolding(graph);
+  HConstantFolding* fold1 = new (arena) HConstantFolding(graph, stats);
   InstructionSimplifier* simplify1 = new (arena) InstructionSimplifier(graph, stats);
-  HBooleanSimplifier* boolean_simplify = new (arena) HBooleanSimplifier(graph);
-  HConstantFolding* fold2 = new (arena) HConstantFolding(graph, "constant_folding_after_inlining");
+  HBooleanSimplifier* boolean_simplify = new (arena) HBooleanSimplifier(graph, stats);
+  HConstantFolding* fold2 = new (arena) HConstantFolding(graph, stats, "constant_folding_after_inlining");
   SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph);
   GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects);
   LICM* licm = new (arena) LICM(graph, *side_effects);
@@ -507,7 +507,7 @@
   InstructionSimplifier* simplify4 = new (arena) InstructionSimplifier(
       graph, stats, "instruction_simplifier_before_codegen");
 
-  IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, driver);
+  IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, driver, stats);
 
   HOptimization* optimizations1[] = {
     intrinsics,
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index 6375cf1..21af170 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -54,6 +54,10 @@
   kRemovedCheckedCast,
   kRemovedDeadInstruction,
   kRemovedNullCheck,
+  kConstantFolding,
+  kBooleanSimplifier,
+  kIntrinsicsRecognizer,
+  kLICM,
   kLastStat
 };
 
@@ -121,6 +125,10 @@
       case kRemovedCheckedCast: return "kRemovedCheckedCast";
       case kRemovedDeadInstruction: return "kRemovedDeadInstruction";
       case kRemovedNullCheck: return "kRemovedNullCheck";
+      case kConstantFolding: return "kConstantFolding";
+      case kBooleanSimplifier: return "kBooleanSimplifier";
+      case kIntrinsicsRecognizer: return "kIntrinsicsRecognizer";
+      case kLICM: return "kLICM";
 
       case kLastStat: break;  // Invalid to print out.
     }