More suspend check repair.
The previous fix to the suspend check optimization mechanism left
a bug in the handling of constant-folded branches.
Change-Id: Ib71f1cb9f17203bee26746006e568d448666962d
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 8f42999..862c1d7 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -239,7 +239,7 @@
case Instruction::GOTO:
case Instruction::GOTO_16:
case Instruction::GOTO_32:
- if (mir->backwards_branch) {
+ if (mir_graph_->IsBackedge(bb, bb->taken)) {
GenSuspendTestAndBranch(opt_flags, &label_list[bb->taken->id]);
} else {
OpUnconditionalBranch(&label_list[bb->taken->id]);
@@ -277,13 +277,13 @@
if (rl_src[0].is_const && rl_src[1].is_const) {
bool is_taken = EvaluateBranch(opcode, mir_graph_->ConstantValue(rl_src[0].orig_sreg),
mir_graph_->ConstantValue(rl_src[1].orig_sreg));
- if (is_taken && mir->backwards_branch) {
+ BasicBlock* target = is_taken ? bb->taken : bb->fall_through;
+ if (mir_graph_->IsBackedge(bb, target)) {
GenSuspendTest(opt_flags);
}
- int id = is_taken ? bb->taken->id : bb->fall_through->id;
- OpUnconditionalBranch(&label_list[id]);
+ OpUnconditionalBranch(&label_list[target->id]);
} else {
- if (mir->backwards_branch) {
+ if (mir_graph_->IsBackwardsBranch(bb)) {
GenSuspendTest(opt_flags);
}
GenCompareAndBranch(opcode, rl_src[0], rl_src[1], taken,
@@ -303,13 +303,13 @@
// Result known at compile time?
if (rl_src[0].is_const) {
bool is_taken = EvaluateBranch(opcode, mir_graph_->ConstantValue(rl_src[0].orig_sreg), 0);
- if (is_taken && mir->backwards_branch) {
+ BasicBlock* target = is_taken ? bb->taken : bb->fall_through;
+ if (mir_graph_->IsBackedge(bb, target)) {
GenSuspendTest(opt_flags);
}
- int id = is_taken ? bb->taken->id : bb->fall_through->id;
- OpUnconditionalBranch(&label_list[id]);
+ OpUnconditionalBranch(&label_list[target->id]);
} else {
- if (mir->backwards_branch) {
+ if (mir_graph_->IsBackwardsBranch(bb)) {
GenSuspendTest(opt_flags);
}
GenCompareZeroAndBranch(opcode, rl_src[0], taken, fall_through);