diff options
Diffstat (limited to 'compiler/dex')
-rw-r--r-- | compiler/dex/mir_graph.cc | 3 | ||||
-rw-r--r-- | compiler/dex/mir_graph.h | 3 | ||||
-rw-r--r-- | compiler/dex/mir_optimization.cc | 12 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.cc | 14 |
4 files changed, 20 insertions, 12 deletions
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc index 86f6ee5..5732dce 100644 --- a/compiler/dex/mir_graph.cc +++ b/compiler/dex/mir_graph.cc @@ -306,6 +306,9 @@ BasicBlock* MIRGraph::ProcessCanBranch(BasicBlock* cur_block, MIR* insn, int cur default: LOG(FATAL) << "Unexpected opcode(" << insn->dalvikInsn.opcode << ") with kBranch set"; } + if (target <= cur_offset) { + insn->backwards_branch = true; + } BasicBlock *taken_block = FindBlock(target, /* split */ true, /* create */ true, /* immed_pred_block_p */ &cur_block); cur_block->taken = taken_block; diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h index 84ab259..45e425b 100644 --- a/compiler/dex/mir_graph.h +++ b/compiler/dex/mir_graph.h @@ -232,7 +232,8 @@ struct SSARepresentation { */ struct MIR { DecodedInstruction dalvikInsn; - unsigned int width; + uint16_t width; + bool backwards_branch; // TODO: may be useful to make this an attribute flag word. unsigned int offset; int m_unit_index; // From which method was this MIR included MIR* prev; diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc index a6314f4..82ba6e3 100644 --- a/compiler/dex/mir_optimization.cc +++ b/compiler/dex/mir_optimization.cc @@ -153,7 +153,14 @@ static BasicBlock* NextDominatedBlock(BasicBlock* bb) { } DCHECK((bb->block_type == kEntryBlock) || (bb->block_type == kDalvikByteCode) || (bb->block_type == kExitBlock)); - bb = bb->fall_through; + if (((bb->taken != NULL) && (bb->fall_through == NULL)) && + ((bb->taken->block_type == kDalvikByteCode) || (bb->taken->block_type == kExitBlock))) { + // Follow simple unconditional branches. + bb = bb->taken; + } else { + // Follow simple fallthrough + bb = (bb->taken != NULL) ? NULL : bb->fall_through; + } if (bb == NULL || (Predecessors(bb) != 1)) { return NULL; } @@ -303,7 +310,8 @@ bool MIRGraph::BasicBlockOpt(BasicBlock* bb) { case Instruction::IF_GEZ: case Instruction::IF_GTZ: case Instruction::IF_LEZ: - if (bb->taken->dominates_return) { + // If we've got a backwards branch to return, no need to suspend check. + if ((bb->taken->dominates_return) && (mir->backwards_branch)) { 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; diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc index 74eaa66..8f42999 100644 --- a/compiler/dex/quick/mir_to_lir.cc +++ b/compiler/dex/quick/mir_to_lir.cc @@ -239,7 +239,7 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list case Instruction::GOTO: case Instruction::GOTO_16: case Instruction::GOTO_32: - if (bb->taken->start_offset <= mir->offset) { + if (mir->backwards_branch) { GenSuspendTestAndBranch(opt_flags, &label_list[bb->taken->id]); } else { OpUnconditionalBranch(&label_list[bb->taken->id]); @@ -273,19 +273,17 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list case Instruction::IF_LE: { LIR* taken = &label_list[bb->taken->id]; LIR* fall_through = &label_list[bb->fall_through->id]; - bool backward_branch; - backward_branch = (bb->taken->start_offset <= mir->offset); // Result known at compile time? 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 && backward_branch) { + if (is_taken && mir->backwards_branch) { GenSuspendTest(opt_flags); } int id = is_taken ? bb->taken->id : bb->fall_through->id; OpUnconditionalBranch(&label_list[id]); } else { - if (backward_branch) { + if (mir->backwards_branch) { GenSuspendTest(opt_flags); } GenCompareAndBranch(opcode, rl_src[0], rl_src[1], taken, @@ -302,18 +300,16 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list case Instruction::IF_LEZ: { LIR* taken = &label_list[bb->taken->id]; LIR* fall_through = &label_list[bb->fall_through->id]; - bool backward_branch; - backward_branch = (bb->taken->start_offset <= mir->offset); // 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 && backward_branch) { + if (is_taken && mir->backwards_branch) { GenSuspendTest(opt_flags); } int id = is_taken ? bb->taken->id : bb->fall_through->id; OpUnconditionalBranch(&label_list[id]); } else { - if (backward_branch) { + if (mir->backwards_branch) { GenSuspendTest(opt_flags); } GenCompareZeroAndBranch(opcode, rl_src[0], taken, fall_through); |