summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2013-08-19 15:12:12 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-08-19 15:12:12 +0000
commita2476f4a68c127d0a8eceea269b0a2edb3d6b9b9 (patch)
tree290fc53c4f1359d2a0f336a11b27e62783853f29 /compiler
parent5bf1d38c0f0294a6632c0c6b2c0ba6bd642aa1c0 (diff)
parentcbcfaf3a410e35730c4daeaff6c791665764925a (diff)
downloadart-a2476f4a68c127d0a8eceea269b0a2edb3d6b9b9.zip
art-a2476f4a68c127d0a8eceea269b0a2edb3d6b9b9.tar.gz
art-a2476f4a68c127d0a8eceea269b0a2edb3d6b9b9.tar.bz2
Merge "Fix suspend check optimization" into dalvik-dev
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/mir_graph.cc3
-rw-r--r--compiler/dex/mir_graph.h3
-rw-r--r--compiler/dex/mir_optimization.cc12
-rw-r--r--compiler/dex/quick/mir_to_lir.cc14
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);