diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index b7139456b779..f531d3676f0a 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -242,14 +242,12 @@ void AggExprEmitter::VisitConditionalOperator(const ConditionalOperator *E) { assert(E->getLHS() && "Must have LHS for aggregate value"); Visit(E->getLHS()); - Builder.CreateBr(ContBlock); - LHSBlock = Builder.GetInsertBlock(); + CGF.EmitBranch(ContBlock); CGF.EmitBlock(RHSBlock); Visit(E->getRHS()); - Builder.CreateBr(ContBlock); - RHSBlock = Builder.GetInsertBlock(); + CGF.EmitBranch(ContBlock); CGF.EmitBlock(ContBlock); } diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index d12d355ee709..92226620269a 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -479,14 +479,14 @@ VisitConditionalOperator(const ConditionalOperator *E) { assert(E->getLHS() && "Must have LHS for complex value"); ComplexPairTy LHS = Visit(E->getLHS()); - Builder.CreateBr(ContBlock); LHSBlock = Builder.GetInsertBlock(); + CGF.EmitBranch(ContBlock); CGF.EmitBlock(RHSBlock); ComplexPairTy RHS = Visit(E->getRHS()); - Builder.CreateBr(ContBlock); RHSBlock = Builder.GetInsertBlock(); + CGF.EmitBranch(ContBlock); CGF.EmitBlock(ContBlock); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 4a1793835777..465574187aa9 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -1139,14 +1139,14 @@ VisitConditionalOperator(const ConditionalOperator *E) { else // Perform promotions, to handle cases like "short ?: int" LHS = EmitScalarConversion(CondVal, E->getCond()->getType(), E->getType()); - Builder.CreateBr(ContBlock); LHSBlock = Builder.GetInsertBlock(); + CGF.EmitBranch(ContBlock); CGF.EmitBlock(RHSBlock); Value *RHS = Visit(E->getRHS()); - Builder.CreateBr(ContBlock); RHSBlock = Builder.GetInsertBlock(); + CGF.EmitBranch(ContBlock); CGF.EmitBlock(ContBlock); diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 903e92dfc2df..8722e15dc0c2 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1725,7 +1725,7 @@ void CodeGenFunction::EmitJumpThroughFinally(ObjCEHEntry *E, bool ExecuteTryExit) { llvm::BasicBlock *Src = Builder.GetInsertBlock(); - if (isDummyBlock(Src)) + if (!Src || isDummyBlock(Src)) return; // Find the destination code for this block. We always use 0 for the diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index b042261ec380..f2088f416d5f 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -149,24 +149,32 @@ 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)) { - // If the last block was an empty placeholder, remove it now. - // TODO: cache and reuse these. - LastBB->eraseFromParent(); - } else { - // Otherwise, create a fall-through branch. - Builder.CreateBr(BB); - } + // 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. + CurBB->eraseFromParent(); + Builder.ClearInsertionPoint(); + } else { + // Otherwise, create a fall-through branch. + Builder.CreateBr(Target); + } +} + void CodeGenFunction::EmitDummyBlock() { EmitBlock(createBasicBlock()); } @@ -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(); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 04d64e4ee13b..d482086e1a17 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -226,6 +226,11 @@ public: void EmitBlock(llvm::BasicBlock *BB); + /// EmitBranch - Emit a branch to the specified basic block from the + /// current insert block, taking care to avoid creation of branches + /// from dummy blocks. + void EmitBranch(llvm::BasicBlock *Block); + /// EmitDummyBlock - Emit a new block which will never be branched /// to. This is used to satisfy the invariant that codegen always /// has an active unterminated block to dump code into.