ART: Fix missing dependency between GVN and other passes

The GVN may be turned off completely, or skip running when the
method is too complex. Turn off DCE in that case.

The dependent cleanup pass is not an optimization pass, so can't be
turned off that way. Check whether the GVN skipped in the gate function.

A possible follow-up is proper dependencies between passes.

Change-Id: I5b7951ecd6c74ebbfa5b23726a3d2f3ea1a23a47
diff --git a/compiler/dex/bb_optimizations.cc b/compiler/dex/bb_optimizations.cc
index 11a7e44..f351d99 100644
--- a/compiler/dex/bb_optimizations.cc
+++ b/compiler/dex/bb_optimizations.cc
@@ -17,6 +17,7 @@
 #include "bb_optimizations.h"
 #include "dataflow_iterator.h"
 #include "dataflow_iterator-inl.h"
+#include "global_value_numbering.h"
 
 namespace art {
 
@@ -79,4 +80,14 @@
   return false;
 }
 
+bool GlobalValueNumberingCleanupPass::Gate(const PassDataHolder* data) const {
+  DCHECK(data != nullptr);
+  CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
+  DCHECK(c_unit != nullptr);
+  // Do not do cleanup if GVN skipped this.
+  // TODO: Proper dependencies between passes?
+  return !GlobalValueNumbering::Skip(c_unit);
+}
+
+
 }  // namespace art
diff --git a/compiler/dex/bb_optimizations.h b/compiler/dex/bb_optimizations.h
index eb87c29..b948afd 100644
--- a/compiler/dex/bb_optimizations.h
+++ b/compiler/dex/bb_optimizations.h
@@ -284,6 +284,9 @@
     : PassME("GVNCleanup", kNoNodes, "") {
   }
 
+  // Depends on GlobalValueNumbering, so implemented in cc file.
+  bool Gate(const PassDataHolder* data) const OVERRIDE;
+
   void Start(PassDataHolder* data) const OVERRIDE {
     DCHECK(data != nullptr);
     CompilationUnit* c_unit = down_cast<const PassMEDataHolder*>(data)->c_unit;
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 0d5da32..3482602 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -1355,8 +1355,13 @@
   temp_scoped_alloc_.reset();
 }
 
+static void DisableGVNDependentOptimizations(CompilationUnit* cu) {
+  cu->disable_opt |= (1u << kGvnDeadCodeElimination);
+}
+
 bool MIRGraph::ApplyGlobalValueNumberingGate() {
   if (GlobalValueNumbering::Skip(cu_)) {
+    DisableGVNDependentOptimizations(cu_);
     return false;
   }
 
@@ -1407,7 +1412,7 @@
     cu_->disable_opt |= (1u << kLocalValueNumbering);
   } else {
     LOG(WARNING) << "GVN failed for " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
-    cu_->disable_opt |= (1u << kGvnDeadCodeElimination);
+    DisableGVNDependentOptimizations(cu_);
   }
 }