aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-09-09 21:00:17 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-09-09 21:00:17 +0000
commit5ca2084cf9b529563209429857f01fdae9dcdfa5 (patch)
tree7bef0cceae645c1fc7d1f8011e04d96776c53652 /lib/CodeGen/CodeGenFunction.cpp
parent8592b1d9a0f0acfcc1adbbcbf860a6f4fd429674 (diff)
Use a unified return block.
- For the time being this means our emitted code is somewhat worse, especially for aggregates. This will be fixed. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56013 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp42
1 files changed, 30 insertions, 12 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index ce0d7d8f89..d2da71270e 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -67,8 +67,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
EmitIndirectSwitches();
// Emit debug descriptor for function end.
- CGDebugInfo *DI = CGM.getDebugInfo();
- if (DI) {
+ if (CGDebugInfo *DI = CGM.getDebugInfo()) {
if (EndLoc.isValid()) {
DI->setLocation(EndLoc);
}
@@ -78,18 +77,31 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// Emit a return for code that falls off the end. If insert point
// is a dummy block with no predecessors then remove the block itself.
llvm::BasicBlock *BB = Builder.GetInsertBlock();
- if (isDummyBlock(BB))
+ if (isDummyBlock(BB)) {
BB->eraseFromParent();
- else {
- // FIXME: if this is C++ main, this should return 0.
- if (CurFn->getReturnType() == llvm::Type::VoidTy)
- Builder.CreateRetVoid();
- else
- Builder.CreateRet(llvm::UndefValue::get(CurFn->getReturnType()));
+ } else {
+ // Just transfer to return
+ Builder.CreateBr(ReturnBlock);
}
assert(BreakContinueStack.empty() &&
"mismatched push/pop in break/continue stack!");
-
+
+ // Emit code to actually return.
+ Builder.SetInsertPoint(ReturnBlock);
+ if (!ReturnValue) {
+ Builder.CreateRetVoid();
+ } else {
+ if (!hasAggregateLLVMType(FnRetTy)) {
+ Builder.CreateRet(Builder.CreateLoad(ReturnValue));
+ } else if (FnRetTy->isAnyComplexType()) {
+ EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, FnRetTy);
+ Builder.CreateRetVoid();
+ } else {
+ EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, FnRetTy);
+ Builder.CreateRetVoid();
+ }
+ }
+
// Remove the AllocaInsertPt instruction, which is just a convenience for us.
AllocaInsertPt->eraseFromParent();
AllocaInsertPt = 0;
@@ -98,6 +110,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
assert(!verifyFunction(*CurFn) && "Generated function is not well formed.");
}
+// FIXME: There is parallel code in StartObjCMethod.
void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
llvm::Function *Fn) {
CurFuncDecl = FD;
@@ -106,14 +119,19 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
assert(CurFn->isDeclaration() && "Function already has body?");
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", CurFn);
-
+
// Create a marker to make it easy to insert allocas into the entryblock
// later. Don't create this with the builder, because we don't want it
// folded.
llvm::Value *Undef = llvm::UndefValue::get(llvm::Type::Int32Ty);
AllocaInsertPt = new llvm::BitCastInst(Undef, llvm::Type::Int32Ty, "allocapt",
EntryBB);
-
+
+ ReturnBlock = llvm::BasicBlock::Create("return", CurFn);
+ ReturnValue = 0;
+ if (!FnRetTy->isVoidType())
+ ReturnValue = CreateTempAlloca(ConvertType(FnRetTy), "retval");
+
Builder.SetInsertPoint(EntryBB);
// Emit subprogram debug descriptor.