diff options
author | Daniel Dunbar <daniel@zuster.org> | 2008-09-09 21:00:17 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2008-09-09 21:00:17 +0000 |
commit | 5ca2084cf9b529563209429857f01fdae9dcdfa5 (patch) | |
tree | 7bef0cceae645c1fc7d1f8011e04d96776c53652 /lib/CodeGen | |
parent | 8592b1d9a0f0acfcc1adbbcbf860a6f4fd429674 (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')
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 32 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 42 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.h | 6 |
4 files changed, 53 insertions, 32 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index b5834e68e5..70c1993887 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -121,6 +121,11 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD) { FnRetTy = OMD->getResultType(); CurFuncDecl = OMD; + ReturnBlock = llvm::BasicBlock::Create("return", CurFn); + ReturnValue = 0; + if (!FnRetTy->isVoidType()) + ReturnValue = CreateTempAlloca(ConvertType(FnRetTy), "retval"); + Builder.SetInsertPoint(EntryBB); // Emit allocs for param decls. Give the LLVM Argument nodes names. diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 4001be49f8..bf3469e538 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -405,33 +405,25 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) { void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { // Emit the result value, even if unused, to evalute the side effects. const Expr *RV = S.getRetValue(); - - llvm::Value* RetValue = 0; - if (FnRetTy->isVoidType()) { - // Make sure not to return anything - if (RV) { - // Evaluate the expression for side effects + + // FIXME: Clean this up by using an LValue for ReturnTemp, + // EmitStoreThroughLValue, and EmitAnyExpr. + if (!ReturnValue) { + // Make sure not to return anything, but evaluate the expression + // for side effects. + if (RV) EmitAnyExpr(RV); - } } else if (RV == 0) { - const llvm::Type *RetTy = CurFn->getFunctionType()->getReturnType(); - if (RetTy != llvm::Type::VoidTy) { - // Handle "return;" in a function that returns a value. - RetValue = llvm::UndefValue::get(RetTy); - } + // Do nothing (return value is left uninitialized) } else if (!hasAggregateLLVMType(RV->getType())) { - RetValue = EmitScalarExpr(RV); + Builder.CreateStore(EmitScalarExpr(RV), ReturnValue); } else if (RV->getType()->isAnyComplexType()) { - EmitComplexExprIntoAddr(RV, CurFn->arg_begin(), false); + EmitComplexExprIntoAddr(RV, ReturnValue, false); } else { - EmitAggExpr(RV, CurFn->arg_begin(), false); + EmitAggExpr(RV, ReturnValue, false); } - if (RetValue) { - Builder.CreateRet(RetValue); - } else { - Builder.CreateRetVoid(); - } + Builder.CreateBr(ReturnBlock); // Emit a block after the branch so that dead code after a return has some // place to go. 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. diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index d00c188639..6fad0486dd 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -64,6 +64,12 @@ public: QualType FnRetTy; llvm::Function *CurFn; + /// ReturnBlock - Unified return block. + llvm::BasicBlock *ReturnBlock; + /// ReturnValue - The temporary alloca to hold the return value. This + /// is null iff the function has no return value. + llvm::Instruction *ReturnValue; + /// AllocaInsertPoint - This is an instruction in the entry block before which /// we prefer to insert allocas. llvm::Instruction *AllocaInsertPt; |