summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/codegen/mir_to_gbc.cc6
-rw-r--r--src/compiler/compiler_ir.h4
-rw-r--r--src/compiler/dataflow.cc11
-rw-r--r--src/compiler/frontend.cc5
4 files changed, 18 insertions, 8 deletions
diff --git a/src/compiler/codegen/mir_to_gbc.cc b/src/compiler/codegen/mir_to_gbc.cc
index 79ac242e74..a2c2bbcca6 100644
--- a/src/compiler/codegen/mir_to_gbc.cc
+++ b/src/compiler/codegen/mir_to_gbc.cc
@@ -1018,7 +1018,7 @@ static bool ConvertMIRNode(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
}
EmitPopShadowFrame(cu);
cu->irb->CreateRet(GetLLVMValue(cu, rl_src[0].orig_sreg));
- bb->has_return = true;
+ DCHECK(bb->terminated_by_return);
}
break;
@@ -1028,7 +1028,7 @@ static bool ConvertMIRNode(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
}
EmitPopShadowFrame(cu);
cu->irb->CreateRetVoid();
- bb->has_return = true;
+ DCHECK(bb->terminated_by_return);
}
break;
@@ -1916,7 +1916,7 @@ static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb)
if (bb->block_type == kEntryBlock) {
cu->entryTarget_bb = GetLLVMBlock(cu, bb->fall_through->id);
- } else if ((bb->fall_through != NULL) && !bb->has_return) {
+ } else if ((bb->fall_through != NULL) && !bb->terminated_by_return) {
cu->irb->CreateBr(GetLLVMBlock(cu, bb->fall_through->id));
}
diff --git a/src/compiler/compiler_ir.h b/src/compiler/compiler_ir.h
index 056c308c79..c652f0c00d 100644
--- a/src/compiler/compiler_ir.h
+++ b/src/compiler/compiler_ir.h
@@ -230,8 +230,8 @@ struct BasicBlock {
bool catch_entry;
bool explicit_throw;
bool conditional_branch;
- bool has_return; // Contains a return.
- bool dominates_return; // Is a member of return extended basic block
+ bool terminated_by_return; // Block ends with a Dalvik return opcode.
+ bool dominates_return; // Is a member of return extended basic block.
uint16_t start_offset;
uint16_t nesting_depth;
BBType block_type;
diff --git a/src/compiler/dataflow.cc b/src/compiler/dataflow.cc
index 1e20cbd025..4d7e9d7a89 100644
--- a/src/compiler/dataflow.cc
+++ b/src/compiler/dataflow.cc
@@ -1890,6 +1890,11 @@ static bool CombineBlocks(struct CompilationUnit* cu, struct BasicBlock* bb)
bb->taken = bb_next->taken;
// Include the rest of the instructions
bb->last_mir_insn = bb_next->last_mir_insn;
+ /*
+ * If lower-half of pair of blocks to combine contained a return, move the flag
+ * to the newly combined block.
+ */
+ bb->terminated_by_return = bb_next->terminated_by_return;
/*
* NOTE: we aren't updating all dataflow info here. Should either make sure this pass
@@ -2096,17 +2101,17 @@ bool BuildExtendedBBList(struct CompilationUnit* cu, struct BasicBlock* bb)
}
BasicBlock* start_bb = bb;
cu->extended_basic_blocks.push_back(bb);
- bool has_return = false;
+ bool terminated_by_return = false;
// Visit blocks strictly dominated by this head.
while (bb != NULL) {
bb->visited = true;
- has_return |= bb->has_return;
+ terminated_by_return |= bb->terminated_by_return;
bb = NextDominatedBlock(cu, bb);
if (cu->verbose && (bb != NULL)) {
LOG(INFO) << "...added bb " << bb->id;
}
}
- if (has_return) {
+ if (terminated_by_return) {
// This extended basic block contains a return, so mark all members.
bb = start_bb;
while (bb != NULL) {
diff --git a/src/compiler/frontend.cc b/src/compiler/frontend.cc
index 44baea28fa..9afd18e4d9 100644
--- a/src/compiler/frontend.cc
+++ b/src/compiler/frontend.cc
@@ -148,6 +148,10 @@ static BasicBlock *SplitBlock(CompilationUnit* cu, unsigned int code_offset,
bottom_block->first_mir_insn = insn;
bottom_block->last_mir_insn = orig_block->last_mir_insn;
+ /* If this block was terminated by a return, the flag needs to go with the bottom block */
+ bottom_block->terminated_by_return = orig_block->terminated_by_return;
+ orig_block->terminated_by_return = false;
+
/* Add it to the quick lookup cache */
cu->block_map.Put(bottom_block->start_offset, bottom_block);
@@ -972,6 +976,7 @@ static CompiledMethod* CompileMethod(Compiler& compiler,
cur_block = ProcessCanBranch(cu.get(), cur_block, insn, cur_offset,
width, flags, code_ptr, code_end);
} else if (flags & Instruction::kReturn) {
+ cur_block->terminated_by_return = true;
cur_block->fall_through = exit_block;
InsertGrowableList(cu.get(), exit_block->predecessors,
reinterpret_cast<uintptr_t>(cur_block));