summaryrefslogtreecommitdiffstats
path: root/compiler/dex/gvn_dead_code_elimination.cc
diff options
context:
space:
mode:
authorSerguei Katkov <serguei.i.katkov@intel.com>2015-08-10 12:59:02 +0600
committerVladimir Marko <vmarko@google.com>2015-08-11 17:00:26 +0100
commit0d9982daaff119e709d0424a700042751120bd60 (patch)
tree65de60222d10945584b13fc0aad224919f37c800 /compiler/dex/gvn_dead_code_elimination.cc
parent168387df8dcbae1b51f124eed84daf8e8de6a974 (diff)
downloadart-0d9982daaff119e709d0424a700042751120bd60.zip
art-0d9982daaff119e709d0424a700042751120bd60.tar.gz
art-0d9982daaff119e709d0424a700042751120bd60.tar.bz2
ART: Fix Quick's DCE+GVN
DCE_GVN does not take into account the following case: mov a, b ... mov c, b when optimization tries to replace a with c it must ensure that for all uses of a there is no new definition of c before use. Otherwise that use will incorrectly substituted with new c instead of original b. Bug: 23102860 Signed-off-by: Serguei Katkov <serguei.i.katkov@intel.com> (cherry picked from commit 2f2f17399f6bdfc5ec94a875152c31ef79620520) Change-Id: I1f08c99cedbe4fd1b96cad11f17d60ab551c7cf7
Diffstat (limited to 'compiler/dex/gvn_dead_code_elimination.cc')
-rw-r--r--compiler/dex/gvn_dead_code_elimination.cc18
1 files changed, 16 insertions, 2 deletions
diff --git a/compiler/dex/gvn_dead_code_elimination.cc b/compiler/dex/gvn_dead_code_elimination.cc
index d29b865..4de3410 100644
--- a/compiler/dex/gvn_dead_code_elimination.cc
+++ b/compiler/dex/gvn_dead_code_elimination.cc
@@ -715,6 +715,7 @@ void GvnDeadCodeElimination::RecordPassTryToKillOverwrittenMoveOrMoveSrc(uint16_
// Try to find a MOVE to a vreg that wasn't changed since check_change.
uint16_t value_name =
data->wide_def ? lvn_->GetSregValueWide(dest_s_reg) : lvn_->GetSregValue(dest_s_reg);
+ uint32_t dest_v_reg = mir_graph_->SRegToVReg(dest_s_reg);
for (size_t c = check_change + 1u, size = vreg_chains_.NumMIRs(); c != size; ++c) {
MIRData* d = vreg_chains_.GetMIRData(c);
if (d->is_move && d->wide_def == data->wide_def &&
@@ -731,8 +732,21 @@ void GvnDeadCodeElimination::RecordPassTryToKillOverwrittenMoveOrMoveSrc(uint16_
if (!vreg_chains_.IsVRegUsed(check_change + 1u, c, new_dest_v_reg, mir_graph_) &&
(!d->wide_def ||
!vreg_chains_.IsVRegUsed(check_change + 1u, c, new_dest_v_reg + 1, mir_graph_))) {
- RecordPassKillMoveByRenamingSrcDef(check_change, c);
- return;
+ // If the move's destination vreg changed, check if the vreg we're trying
+ // to rename is unused after that change.
+ uint16_t dest_change = vreg_chains_.FindFirstChangeAfter(new_dest_v_reg, c);
+ if (d->wide_def) {
+ uint16_t dest_change_high = vreg_chains_.FindFirstChangeAfter(new_dest_v_reg + 1, c);
+ if (dest_change_high != kNPos &&
+ (dest_change == kNPos || dest_change_high < dest_change)) {
+ dest_change = dest_change_high;
+ }
+ }
+ if (dest_change == kNPos ||
+ !vreg_chains_.IsVRegUsed(dest_change + 1u, size, dest_v_reg, mir_graph_)) {
+ RecordPassKillMoveByRenamingSrcDef(check_change, c);
+ return;
+ }
}
}
}