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.cc b/compiler/dex/gvn_dead_code_elimination.cc
index bd7bd71..4f0e9d1 100644
--- a/compiler/dex/gvn_dead_code_elimination.cc
+++ b/compiler/dex/gvn_dead_code_elimination.cc
@@ -984,18 +984,17 @@
uint16_t opcode = mir->dalvikInsn.opcode;
switch (opcode) {
case kMirOpPhi: {
- // We can't recognize wide variables in Phi from num_defs == 2 as we've got two Phis instead.
+ // Determine if this Phi is merging wide regs.
+ RegLocation raw_dest = gvn_->GetMirGraph()->GetRawDest(mir);
+ if (raw_dest.high_word) {
+ // This is the high part of a wide reg. Ignore the Phi.
+ return false;
+ }
+ bool wide = raw_dest.wide;
+ // Record the value.
DCHECK_EQ(mir->ssa_rep->num_defs, 1);
int s_reg = mir->ssa_rep->defs[0];
- bool wide = false;
- uint16_t new_value = lvn_->GetSregValue(s_reg);
- if (new_value == kNoValue) {
- wide = true;
- new_value = lvn_->GetSregValueWide(s_reg);
- if (new_value == kNoValue) {
- return false; // Ignore the high word Phi.
- }
- }
+ uint16_t new_value = wide ? lvn_->GetSregValueWide(s_reg) : lvn_->GetSregValue(s_reg);
int v_reg = mir_graph_->SRegToVReg(s_reg);
DCHECK_EQ(vreg_chains_.CurrentValue(v_reg), kNoValue); // No previous def for v_reg.