Quick: Rely on inferred types in GVN/LVN/DCE.
Fix LVN::GetEndingVregValueNumberImpl() to check whether
the requested wideness matches the SSA register type as
recorded in MIRGraph::reg_location_.
Add DCHECKs that the wideness matches when getting/setting
sreg values, update Phi handling in LVN/DCE to use the type
from MIRGraph::reg_location_ instead of determining it from
the sreg value maps which would now trigger the DCHECKs.
Update tests to initialize MIRGraph::reg_location_.
Reenable DCE.
Bug: 20572509
Change-Id: I1a4d4e32cd57807ca8b56d2f3ed5e1288660b82e
diff --git a/compiler/dex/gvn_dead_code_elimination_test.cc b/compiler/dex/gvn_dead_code_elimination_test.cc
index 3eb372c..f9f0882 100644
--- a/compiler/dex/gvn_dead_code_elimination_test.cc
+++ b/compiler/dex/gvn_dead_code_elimination_test.cc
@@ -406,6 +406,15 @@
}
}
+ template <size_t count>
+ void MarkAsWideSRegs(const int32_t (&sregs)[count]) {
+ for (int32_t sreg : sregs) {
+ cu_.mir_graph->reg_location_[sreg].wide = true;
+ cu_.mir_graph->reg_location_[sreg + 1].wide = true;
+ cu_.mir_graph->reg_location_[sreg + 1].high_word = true;
+ }
+ }
+
void PerformDCE() {
FillVregToSsaRegExitMaps();
cu_.mir_graph->GetNumOfCodeAndTempVRs();
@@ -467,9 +476,11 @@
cu_.access_flags = kAccStatic; // Don't let "this" interfere with this test.
allocator_.reset(ScopedArenaAllocator::Create(&cu_.arena_stack));
// By default, the zero-initialized reg_location_[.] with ref == false tells LVN that
- // 0 constants are integral, not references. Nothing else is used by LVN/GVN.
+ // 0 constants are integral, not references, and the values are all narrow.
+ // Nothing else is used by LVN/GVN. Tests can override the default values as needed.
cu_.mir_graph->reg_location_ = static_cast<RegLocation*>(cu_.arena.Alloc(
kMaxSsaRegs * sizeof(cu_.mir_graph->reg_location_[0]), kArenaAllocRegAlloc));
+ cu_.mir_graph->num_ssa_regs_ = kMaxSsaRegs;
// Bind all possible sregs to live vregs for test purposes.
live_in_v_->SetInitialBits(kMaxSsaRegs);
cu_.mir_graph->ssa_base_vregs_.reserve(kMaxSsaRegs);
@@ -705,6 +716,8 @@
PrepareSRegToVRegMap(sreg_to_vreg_map);
PrepareMIRs(mirs);
+ static const int32_t wide_sregs[] = { 3 };
+ MarkAsWideSRegs(wide_sregs);
PerformGVN_DCE();
ASSERT_EQ(arraysize(mirs), value_names_.size());
@@ -745,6 +758,8 @@
PrepareIFields(ifields);
PrepareMIRs(mirs);
+ static const int32_t wide_sregs[] = { 5 };
+ MarkAsWideSRegs(wide_sregs);
PerformGVN_DCE();
ASSERT_EQ(arraysize(mirs), value_names_.size());
@@ -777,6 +792,8 @@
PrepareSRegToVRegMap(sreg_to_vreg_map);
PrepareMIRs(mirs);
+ static const int32_t wide_sregs[] = { 0, 2 };
+ MarkAsWideSRegs(wide_sregs);
PerformGVN_DCE();
ASSERT_EQ(arraysize(mirs), value_names_.size());
@@ -1255,6 +1272,8 @@
PrepareIFields(ifields);
PrepareMIRs(mirs);
+ static const int32_t wide_sregs[] = { 1, 6 };
+ MarkAsWideSRegs(wide_sregs);
PerformGVN_DCE();
ASSERT_EQ(arraysize(mirs), value_names_.size());