diff options
author | Daniel Dunbar <daniel@zuster.org> | 2008-11-11 09:41:28 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2008-11-11 09:41:28 +0000 |
commit | d57a871339c7c98d58d93108b806f59bdf4e13e2 (patch) | |
tree | 965779772ee3189b5eba2360fd14a34bfef3d658 /lib/CodeGen/CGStmt.cpp | |
parent | f1d93600000bb516cdd499905f699b289fd73ada (diff) |
Add CodeGenFunction::EmitBranch.
- Emits an unconditional branch, with extra logic to avoid generating
spurious branches out of dummy blocks.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59037 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGStmt.cpp')
-rw-r--r-- | lib/CodeGen/CGStmt.cpp | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index b042261ec3..f2088f416d 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -149,22 +149,30 @@ RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast, } void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB) { - // Emit a branch from this block to the next one if this was a real block. If - // this was just a fall-through block after a terminator, don't emit it. - llvm::BasicBlock *LastBB = Builder.GetInsertBlock(); - - if (LastBB->getTerminator()) { - // If the previous block is already terminated, don't touch it. - } else if (isDummyBlock(LastBB)) { + // Fall out of the current block (if necessary). + EmitBranch(BB); + CurFn->getBasicBlockList().push_back(BB); + Builder.SetInsertPoint(BB); +} + +void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) { + // Emit a branch from the current block to the target one if this + // was a real block. If this was just a fall-through block after a + // terminator, don't emit it. + llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); + + if (!CurBB || CurBB->getTerminator()) { + // If there is no insert point or the previous block is already + // terminated, don't touch it. + } else if (isDummyBlock(CurBB)) { // If the last block was an empty placeholder, remove it now. // TODO: cache and reuse these. - LastBB->eraseFromParent(); + CurBB->eraseFromParent(); + Builder.ClearInsertionPoint(); } else { // Otherwise, create a fall-through branch. - Builder.CreateBr(BB); + Builder.CreateBr(Target); } - CurFn->getBasicBlockList().push_back(BB); - Builder.SetInsertPoint(BB); } void CodeGenFunction::EmitDummyBlock() { @@ -189,7 +197,7 @@ void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) { return; } - Builder.CreateBr(getBasicBlockForLabel(S.getLabel())); + EmitBranch(getBasicBlockForLabel(S.getLabel())); // Emit a block after the branch so that dead code after a goto has some place // to go. @@ -252,25 +260,13 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // Emit the 'then' code. EmitBlock(ThenBlock); EmitStmt(S.getThen()); - llvm::BasicBlock *BB = Builder.GetInsertBlock(); - if (isDummyBlock(BB)) { - BB->eraseFromParent(); - Builder.SetInsertPoint(ThenBlock); - } else { - Builder.CreateBr(ContBlock); - } + EmitBranch(ContBlock); // Emit the 'else' code if present. if (const Stmt *Else = S.getElse()) { EmitBlock(ElseBlock); EmitStmt(Else); - llvm::BasicBlock *BB = Builder.GetInsertBlock(); - if (isDummyBlock(BB)) { - BB->eraseFromParent(); - Builder.SetInsertPoint(ElseBlock); - } else { - Builder.CreateBr(ContBlock); - } + EmitBranch(ContBlock); } // Emit the continuation block for code after the if. @@ -314,7 +310,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { BreakContinueStack.pop_back(); // Cycle to the condition. - Builder.CreateBr(LoopHeader); + EmitBranch(LoopHeader); // Emit the exit block. EmitBlock(ExitBlock); @@ -433,7 +429,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) { } // Finally, branch back up to the condition for the next iteration. - Builder.CreateBr(CondBlock); + EmitBranch(CondBlock); // Emit the fall-through block. EmitBlock(AfterFor); @@ -447,7 +443,7 @@ void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) { } else { StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false); } - Builder.CreateBr(ReturnBlock); + EmitBranch(ReturnBlock); // Emit a block after the branch so that dead code after a return has some // place to go. @@ -487,7 +483,7 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) { } } - Builder.CreateBr(ReturnBlock); + EmitBranch(ReturnBlock); // Emit a block after the branch so that dead code after a return has some // place to go. @@ -504,7 +500,7 @@ void CodeGenFunction::EmitBreakStmt() { assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock; - Builder.CreateBr(Block); + EmitBranch(Block); EmitDummyBlock(); } @@ -512,7 +508,7 @@ void CodeGenFunction::EmitContinueStmt() { assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock; - Builder.CreateBr(Block); + EmitBranch(Block); EmitDummyBlock(); } |