Quick: Fix and enable DCE and improve GVN/DCE cleanup.
When eliminating a move by renaming its source register,
check that it doesn't conflict with vreg usage by insns
between the defining insn and the move.
Improve the GVN/DCE cleanup so that it can handle cases
where GVN or DCE is individually disabled in the pass driver
but not in the disable_opt flags.
Bug: 19419671
Change-Id: I49bb67b81509f51fbaf90c6016c509962be43736
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 467c14e..0d5da32 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -1409,14 +1409,10 @@
LOG(WARNING) << "GVN failed for " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
cu_->disable_opt |= (1u << kGvnDeadCodeElimination);
}
-
- if ((cu_->disable_opt & (1 << kGvnDeadCodeElimination)) != 0) {
- EliminateDeadCodeEnd();
- } // else preserve GVN data for CSE.
}
bool MIRGraph::EliminateDeadCodeGate() {
- if ((cu_->disable_opt & (1 << kGvnDeadCodeElimination)) != 0) {
+ if ((cu_->disable_opt & (1 << kGvnDeadCodeElimination)) != 0 || temp_.gvn.gvn == nullptr) {
return false;
}
DCHECK(temp_scoped_alloc_ != nullptr);
@@ -1437,11 +1433,21 @@
}
void MIRGraph::EliminateDeadCodeEnd() {
- DCHECK_EQ(temp_.gvn.dce != nullptr, (cu_->disable_opt & (1 << kGvnDeadCodeElimination)) == 0);
- if (temp_.gvn.dce != nullptr) {
- delete temp_.gvn.dce;
- temp_.gvn.dce = nullptr;
+ if (kIsDebugBuild) {
+ // DCE can make some previously dead vregs alive again. Make sure the obsolete
+ // live-in information is not used anymore.
+ AllNodesIterator iter(this);
+ for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
+ if (bb->data_flow_info != nullptr) {
+ bb->data_flow_info->live_in_v = nullptr;
+ }
+ }
}
+}
+
+void MIRGraph::GlobalValueNumberingCleanup() {
+ delete temp_.gvn.dce;
+ temp_.gvn.dce = nullptr;
delete temp_.gvn.gvn;
temp_.gvn.gvn = nullptr;
temp_.gvn.ifield_ids = nullptr;