!T->isBlockPointerType();
}
+void CodeGenFunction::EmitReturnBlock() {
+ // For cleanliness, we try to avoid emitting the return block for
+ // simple cases.
+ llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+
+ if (CurBB) {
+ assert(!CurBB->getTerminator() && "Unexpected terminated block.");
+
+ // We have a valid insert point, reuse it if there are no explicit
+ // jumps to the return block.
+ if (ReturnBlock->use_empty())
+ delete ReturnBlock;
+ else
+ EmitBlock(ReturnBlock);
+ return;
+ }
+
+ // Otherwise, if the return block is the target of a single direct
+ // branch then we can just put the code in that block instead. This
+ // cleans up functions which started with a unified return block.
+ if (ReturnBlock->hasOneUse()) {
+ llvm::BranchInst *BI =
+ dyn_cast<llvm::BranchInst>(*ReturnBlock->use_begin());
+ if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock) {
+ // Reset insertion point and delete the branch.
+ Builder.SetInsertPoint(BI->getParent());
+ BI->eraseFromParent();
+ delete ReturnBlock;
+ return;
+ }
+ }
+
+ // FIXME: We are at an unreachable point, there is no reason to emit
+ // the block unless it has uses. However, we still need a place to
+ // put the debug region.end for now.
+
+ EmitBlock(ReturnBlock);
+}
+
void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// Finish emission of indirect switches.
EmitIndirectSwitches();
assert(BreakContinueStack.empty() &&
"mismatched push/pop in break/continue stack!");
- // Emit function epilog (to return). For cleanliness, skip emission
- // if we know it is safe (when it is unused and the current block is
- // unterminated).
- if (!ReturnBlock->use_empty() ||
- !Builder.GetInsertBlock() ||
- Builder.GetInsertBlock()->getTerminator())
- EmitBlock(ReturnBlock);
+ // Emit function epilog (to return).
+ EmitReturnBlock();
// Emit debug descriptor for function end.
if (CGDebugInfo *DI = CGM.getDebugInfo()) {
const FunctionArgList &Args,
SourceLocation StartLoc);
+ /// EmitReturnBlock - Emit the unified return block, trying to avoid
+ /// its emission when possible.
+ void EmitReturnBlock();
+
/// FinishFunction - Complete IR generation of the current
/// function. It is legal to call this function even if there is no
/// current insertion point.