Put in place the ARM64 instruction simplification framework.

This commit introduces and runs the empty InstructionSimplifierArm64
pass. Further commits will introduce arm64-specific transformations in
that pass.

Change-Id: I458f8a2b15470297b87fc1f7ff85bd52155d93ef
diff --git a/compiler/Android.mk b/compiler/Android.mk
index 7d368a2..8b56880 100644
--- a/compiler/Android.mk
+++ b/compiler/Android.mk
@@ -62,8 +62,8 @@
 	jni/quick/calling_convention.cc \
 	jni/quick/jni_compiler.cc \
 	optimizing/boolean_simplifier.cc \
-	optimizing/builder.cc \
 	optimizing/bounds_check_elimination.cc \
+	optimizing/builder.cc \
 	optimizing/code_generator.cc \
 	optimizing/code_generator_utils.cc \
 	optimizing/constant_folding.cc \
@@ -136,6 +136,7 @@
 	jni/quick/arm64/calling_convention_arm64.cc \
 	linker/arm64/relative_patcher_arm64.cc \
 	optimizing/code_generator_arm64.cc \
+	optimizing/instruction_simplifier_arm64.cc \
 	optimizing/intrinsics_arm64.cc \
 	utils/arm64/assembler_arm64.cc \
 	utils/arm64/managed_register_arm64.cc \
diff --git a/compiler/optimizing/gvn.h b/compiler/optimizing/gvn.h
index 14a503b..4fdba26 100644
--- a/compiler/optimizing/gvn.h
+++ b/compiler/optimizing/gvn.h
@@ -26,8 +26,10 @@
 
 class GVNOptimization : public HOptimization {
  public:
-  GVNOptimization(HGraph* graph, const SideEffectsAnalysis& side_effects)
-      : HOptimization(graph, kGlobalValueNumberingPassName), side_effects_(side_effects) {}
+  GVNOptimization(HGraph* graph,
+                  const SideEffectsAnalysis& side_effects,
+                  const char* pass_name = kGlobalValueNumberingPassName)
+      : HOptimization(graph, pass_name), side_effects_(side_effects) {}
 
   void Run() OVERRIDE;
 
diff --git a/compiler/optimizing/instruction_simplifier_arm64.cc b/compiler/optimizing/instruction_simplifier_arm64.cc
new file mode 100644
index 0000000..4b2d36f
--- /dev/null
+++ b/compiler/optimizing/instruction_simplifier_arm64.cc
@@ -0,0 +1,23 @@
+/*
+ * 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 "instruction_simplifier_arm64.h"
+
+namespace art {
+namespace arm64 {
+
+}  // namespace arm64
+}  // namespace art
diff --git a/compiler/optimizing/instruction_simplifier_arm64.h b/compiler/optimizing/instruction_simplifier_arm64.h
new file mode 100644
index 0000000..d7f4eae
--- /dev/null
+++ b/compiler/optimizing/instruction_simplifier_arm64.h
@@ -0,0 +1,56 @@
+/*
+ * 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_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM64_H_
+#define ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM64_H_
+
+#include "nodes.h"
+#include "optimization.h"
+
+namespace art {
+namespace arm64 {
+
+class InstructionSimplifierArm64Visitor : public HGraphVisitor {
+ public:
+  InstructionSimplifierArm64Visitor(HGraph* graph, OptimizingCompilerStats* stats)
+      : HGraphVisitor(graph), stats_(stats) {}
+
+ private:
+  void RecordSimplification() {
+    if (stats_ != nullptr) {
+      stats_->RecordStat(kInstructionSimplificationsArch);
+    }
+  }
+
+  OptimizingCompilerStats* stats_;
+};
+
+
+class InstructionSimplifierArm64 : public HOptimization {
+ public:
+  InstructionSimplifierArm64(HGraph* graph, OptimizingCompilerStats* stats)
+    : HOptimization(graph, "instruction_simplifier_arm64", stats) {}
+
+  void Run() OVERRIDE {
+    InstructionSimplifierArm64Visitor visitor(graph_, stats_);
+    visitor.VisitReversePostOrder();
+  }
+};
+
+}  // namespace arm64
+}  // namespace art
+
+#endif  // ART_COMPILER_OPTIMIZING_INSTRUCTION_SIMPLIFIER_ARM64_H_
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 6a50b7d..866e717 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -19,6 +19,10 @@
 #include <fstream>
 #include <stdint.h>
 
+#ifdef ART_ENABLE_CODEGEN_arm64
+#include "instruction_simplifier_arm64.h"
+#endif
+
 #include "art_method-inl.h"
 #include "base/arena_allocator.h"
 #include "base/dumpable.h"
@@ -399,6 +403,32 @@
   RunOptimizations(optimizations, arraysize(optimizations), pass_observer);
 }
 
+static void RunArchOptimizations(InstructionSet instruction_set,
+                                 HGraph* graph,
+                                 OptimizingCompilerStats* stats,
+                                 PassObserver* pass_observer) {
+  ArenaAllocator* arena = graph->GetArena();
+  switch (instruction_set) {
+#ifdef ART_ENABLE_CODEGEN_arm64
+    case kArm64: {
+      arm64::InstructionSimplifierArm64* simplifier =
+          new (arena) arm64::InstructionSimplifierArm64(graph, stats);
+      SideEffectsAnalysis* side_effects = new (arena) SideEffectsAnalysis(graph);
+      GVNOptimization* gvn = new (arena) GVNOptimization(graph, *side_effects, "GVN_after_arch");
+      HOptimization* arm64_optimizations[] = {
+        simplifier,
+        side_effects,
+        gvn
+      };
+      RunOptimizations(arm64_optimizations, arraysize(arm64_optimizations), pass_observer);
+      break;
+    }
+#endif
+    default:
+      break;
+  }
+}
+
 static void RunOptimizations(HGraph* graph,
                              CompilerDriver* driver,
                              OptimizingCompilerStats* stats,
@@ -460,6 +490,8 @@
   };
 
   RunOptimizations(optimizations2, arraysize(optimizations2), pass_observer);
+
+  RunArchOptimizations(driver->GetInstructionSet(), graph, stats, pass_observer);
 }
 
 // The stack map we generate must be 4-byte aligned on ARM. Since existing
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index 53d052b..da5cb57 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -32,6 +32,7 @@
   kCompiledQuick,
   kInlinedInvoke,
   kInstructionSimplifications,
+  kInstructionSimplificationsArch,
   kNotCompiledBranchOutsideMethodCode,
   kNotCompiledCannotBuildSSA,
   kNotCompiledCantAccesType,
@@ -101,6 +102,7 @@
       case kCompiledQuick : return "kCompiledQuick";
       case kInlinedInvoke : return "kInlinedInvoke";
       case kInstructionSimplifications: return "kInstructionSimplifications";
+      case kInstructionSimplificationsArch: return "kInstructionSimplificationsArch";
       case kNotCompiledBranchOutsideMethodCode: return "kNotCompiledBranchOutsideMethodCode";
       case kNotCompiledCannotBuildSSA : return "kNotCompiledCannotBuildSSA";
       case kNotCompiledCantAccesType : return "kNotCompiledCantAccesType";