Eliminate suspend checks on back-edges to return insn.
This optimization seems to have been broken for a long time.
Change-Id: I62ec85c71bb5253917ad9465a952911e917f6b52
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index 9d52807..1f630f7 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -477,29 +477,25 @@
}
}
break;
- case Instruction::GOTO:
- case Instruction::GOTO_16:
- case Instruction::GOTO_32:
- case Instruction::IF_EQ:
- case Instruction::IF_NE:
- case Instruction::IF_LT:
- case Instruction::IF_GE:
- case Instruction::IF_GT:
- case Instruction::IF_LE:
- case Instruction::IF_EQZ:
- case Instruction::IF_NEZ:
- case Instruction::IF_LTZ:
- case Instruction::IF_GEZ:
- case Instruction::IF_GTZ:
- case Instruction::IF_LEZ:
- // If we've got a backwards branch to return, no need to suspend check.
- if ((IsBackedge(bb, bb->taken) && GetBasicBlock(bb->taken)->dominates_return) ||
- (IsBackedge(bb, bb->fall_through) &&
- GetBasicBlock(bb->fall_through)->dominates_return)) {
- mir->optimization_flags |= MIR_IGNORE_SUSPEND_CHECK;
- if (cu_->verbose) {
- LOG(INFO) << "Suppressed suspend check on branch to return at 0x" << std::hex
- << mir->offset;
+ case Instruction::RETURN_VOID:
+ case Instruction::RETURN:
+ case Instruction::RETURN_WIDE:
+ case Instruction::RETURN_OBJECT:
+ if (bb->GetFirstNonPhiInsn() == mir) {
+ // This is a simple return BB. Eliminate suspend checks on predecessor back-edges.
+ for (BasicBlockId pred_id : bb->predecessors) {
+ BasicBlock* pred_bb = GetBasicBlock(pred_id);
+ DCHECK(pred_bb != nullptr);
+ if (IsBackedge(pred_bb, bb->id) && pred_bb->last_mir_insn != nullptr &&
+ (IsInstructionIfCc(pred_bb->last_mir_insn->dalvikInsn.opcode) ||
+ IsInstructionIfCcZ(pred_bb->last_mir_insn->dalvikInsn.opcode) ||
+ IsInstructionGoto(pred_bb->last_mir_insn->dalvikInsn.opcode))) {
+ pred_bb->last_mir_insn->optimization_flags |= MIR_IGNORE_SUSPEND_CHECK;
+ if (cu_->verbose) {
+ LOG(INFO) << "Suppressed suspend check on branch to return at 0x" << std::hex
+ << pred_bb->last_mir_insn->offset;
+ }
+ }
}
}
break;