Global Value Numbering.

Implement the Global Value Numbering for optimization
purposes. Use it for the null check and range check
elimination as the LVN used to do.

The order of evaluation of basic blocks needs improving as
we currently fail to recognize some obviously identical
values in methods with more than one loop. (There are three
disabled tests that check this. This is just a missed
optimization, not a correctness issue.)

Change-Id: I0d0ce16b2495b5a3b17ad1b2b32931cd69f5a25a
diff --git a/compiler/dex/bb_optimizations.h b/compiler/dex/bb_optimizations.h
index 6eccb0e..eb897f0 100644
--- a/compiler/dex/bb_optimizations.h
+++ b/compiler/dex/bb_optimizations.h
@@ -199,8 +199,43 @@
 };
 
 /**
- * @class NullCheckEliminationAndTypeInference
- * @brief Null check elimination and type inference.
+ * @class GlobalValueNumberingPass
+ * @brief Performs the global value numbering pass.
+ */
+class GlobalValueNumberingPass : public PassME {
+ public:
+  GlobalValueNumberingPass()
+    : PassME("GVN", kRepeatingTopologicalSortTraversal, "4_post_gvn_cfg") {
+  }
+
+  bool Gate(const PassDataHolder* data) const {
+    DCHECK(data != nullptr);
+    CompilationUnit* cUnit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+    DCHECK(cUnit != nullptr);
+    return cUnit->mir_graph->ApplyGlobalValueNumberingGate();
+  }
+
+  bool Worker(const PassDataHolder* data) const {
+    DCHECK(data != nullptr);
+    const PassMEDataHolder* pass_me_data_holder = down_cast<const PassMEDataHolder*>(data);
+    CompilationUnit* cUnit = pass_me_data_holder->c_unit;
+    DCHECK(cUnit != nullptr);
+    BasicBlock* bb = pass_me_data_holder->bb;
+    DCHECK(bb != nullptr);
+    return cUnit->mir_graph->ApplyGlobalValueNumbering(bb);
+  }
+
+  void End(PassDataHolder* data) const {
+    DCHECK(data != nullptr);
+    CompilationUnit* cUnit = down_cast<PassMEDataHolder*>(data)->c_unit;
+    DCHECK(cUnit != nullptr);
+    cUnit->mir_graph->ApplyGlobalValueNumberingEnd();
+  }
+};
+
+/**
+ * @class BBCombine
+ * @brief Perform the basic block combination pass.
  */
 class BBCombine : public PassME {
  public: