The tricks played with kMirOpCheckPart2 are making the
native GC map generation unnecessarily complex. They have
caused problems in the past and now there is bad interaction
with the DCE. Rather than fixing it time and again, remove
the pseudo-insn.
(The whole purpose of those tricks seems to be to allow the
register tracking to be used for the throwing insn before
resetting the tracking for the next block. However, it's
questionable whether that's better than processing the
throwing insn with the subsequent instructions.)
Bug:
20736048
(cherry picked from commit
e299f167c9559401548eab71678d4b779e46c2fb)
Change-Id: Ifae6c5bd961a2619b50fd3440261762cb9151460
kMirOpRangeCheck,
kMirOpDivZeroCheck,
kMirOpCheck,
- kMirOpCheckPart2,
kMirOpSelect,
// Vector opcodes:
// 10B MIR_CHECK
0,
- // 10C MIR_CHECKPART2
- 0,
-
// 10D MIR_SELECT
DF_DA | DF_UB,
"OpNullCheck",
"OpRangeCheck",
"OpDivZeroCheck",
- "Check1",
- "Check2",
+ "Check",
"Select",
"ConstVector",
"MoveVector",
Instruction::Format dalvik_format = Instruction::k10x; // Default to no-operand format.
// Handle special cases that recover the original dalvik instruction.
- if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) {
+ if (opcode == kMirOpCheck) {
str.append(extended_mir_op_names_[opcode - kMirOpFirst]);
str.append(": ");
// Recover the original Dex instruction.
return Instruction::kContinue | Instruction::kThrow;
case kMirOpCheck:
return Instruction::kContinue | Instruction::kThrow;
- case kMirOpCheckPart2:
- return Instruction::kContinue;
case kMirOpSelect:
return Instruction::kContinue;
case kMirOpConstVector:
}
}
}
- if (bb->block_type != kEntryBlock && bb->first_mir_insn != nullptr &&
- static_cast<int>(bb->first_mir_insn->dalvikInsn.opcode) == kMirOpCheckPart2) {
- // In Mir2Lir::MethodBlockCodeGen() we have artificially moved the throwing
- // instruction to the previous block. However, the MIRGraph data used above
- // doesn't reflect that, so we still need to process that MIR insn here.
- MIR* mir = nullptr;
- BasicBlock* pred_bb = bb;
- // Traverse empty blocks.
- while (mir == nullptr && pred_bb->predecessors.size() == 1u) {
- pred_bb = mir_graph_->GetBasicBlock(bb->predecessors[0]);
- DCHECK(pred_bb != nullptr);
- mir = pred_bb->last_mir_insn;
- }
- DCHECK(mir != nullptr);
- UpdateReferenceVRegsLocal(nullptr, mir, references);
- }
}
bool Mir2Lir::UpdateReferenceVRegsLocal(MIR* mir, MIR* prev_mir, BitVector* references) {
case kMirOpRangeCheck:
case kMirOpDivZeroCheck:
case kMirOpCheck:
- case kMirOpCheckPart2:
// Ignore these known opcodes
break;
default:
head_lir->u.m.def_mask = &kEncodeAll;
}
- if (opcode == kMirOpCheck) {
- // Combine check and work halves of throwing instruction.
- MIR* work_half = mir->meta.throw_insn;
- mir->dalvikInsn = work_half->dalvikInsn;
- mir->optimization_flags = work_half->optimization_flags;
- mir->meta = work_half->meta; // Whatever the work_half had, we need to copy it.
- opcode = work_half->dalvikInsn.opcode;
- SSARepresentation* ssa_rep = work_half->ssa_rep;
- work_half->ssa_rep = mir->ssa_rep;
- mir->ssa_rep = ssa_rep;
- work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheckPart2);
- work_half->meta.throw_insn = mir;
- }
-
if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) {
HandleExtendedMethodMIR(bb, mir);
continue;
kMirOpRangeCheck,
kMirOpDivZeroCheck,
kMirOpCheck,
- kMirOpCheckPart2,
kMirOpSelect,
};