diff options
Diffstat (limited to 'compiler/dex/local_value_numbering.cc')
-rw-r--r-- | compiler/dex/local_value_numbering.cc | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/compiler/dex/local_value_numbering.cc b/compiler/dex/local_value_numbering.cc index 99b6683b26..dc222b5211 100644 --- a/compiler/dex/local_value_numbering.cc +++ b/compiler/dex/local_value_numbering.cc @@ -1520,7 +1520,6 @@ uint16_t LocalValueNumbering::GetValueNumber(MIR* mir) { case Instruction::GOTO: case Instruction::GOTO_16: case Instruction::GOTO_32: - case Instruction::CHECK_CAST: case Instruction::THROW: case Instruction::FILL_ARRAY_DATA: case Instruction::PACKED_SWITCH: @@ -1612,9 +1611,32 @@ uint16_t LocalValueNumbering::GetValueNumber(MIR* mir) { HandleInvokeOrClInitOrAcquireOp(mir); break; + case Instruction::INSTANCE_OF: { + uint16_t operand = GetOperandValue(mir->ssa_rep->uses[0]); + uint16_t type = mir->dalvikInsn.vC; + res = gvn_->LookupValue(Instruction::INSTANCE_OF, operand, type, kNoValue); + SetOperandValue(mir->ssa_rep->defs[0], res); + } + break; + case Instruction::CHECK_CAST: + if (gvn_->CanModify()) { + // Check if there was an instance-of operation on the same value and if we are + // in a block where its result is true. If so, we can eliminate the check-cast. + uint16_t operand = GetOperandValue(mir->ssa_rep->uses[0]); + uint16_t type = mir->dalvikInsn.vB; + uint16_t cond = gvn_->FindValue(Instruction::INSTANCE_OF, operand, type, kNoValue); + if (cond != kNoValue && gvn_->IsTrueInBlock(cond, Id())) { + if (gvn_->GetCompilationUnit()->verbose) { + LOG(INFO) << "Removing check-cast at 0x" << std::hex << mir->offset; + } + // Don't use kMirOpNop. Keep the check-cast as it defines the type of the register. + mir->optimization_flags |= MIR_IGNORE_CHECK_CAST; + } + } + break; + case Instruction::MOVE_RESULT: case Instruction::MOVE_RESULT_OBJECT: - case Instruction::INSTANCE_OF: // 1 result, treat as unique each time, use result s_reg - will be unique. res = GetOperandValue(mir->ssa_rep->defs[0]); SetOperandValue(mir->ssa_rep->defs[0], res); |