]> granicus.if.org Git - clang/commitdiff
Add CodeGenFunction::EmitBranch.
authorDaniel Dunbar <daniel@zuster.org>
Tue, 11 Nov 2008 09:41:28 +0000 (09:41 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 11 Nov 2008 09:41:28 +0000 (09:41 +0000)
 - 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

lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGStmt.cpp
lib/CodeGen/CodeGenFunction.h

index b7139456b77956c421b24d3eef7874b9260df254..f531d3676f0aabc022810879d499fd1d34236704 100644 (file)
@@ -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);
 }
index d12d355ee70986dd047e18746d8b09ed5f150d7c..92226620269acb4615ddaae3aab221d09cf48f83 100644 (file)
@@ -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);
   
index 4a179383577784d272ac1c991a701468705d0af6..465574187aa9d2479e170ac26ed3e3efa9385f56 100644 (file)
@@ -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);
   
index 903e92dfc2df8377ecea1c2016117bd45895e627..8722e15dc0c26e13f0eb2a8a383b9b33dfe636ff 100644 (file)
@@ -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
index b042261ec380400eecabe02d0a6fb764965f5970..f2088f416d5f585cfd5b3243c56de2673e67de3b 100644 (file)
@@ -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();
 }
 
index 04d64e4ee13bdc476b5b5651e92be71a2e8c8480..d482086e1a17969552d85a61d314941d3f42b01e 100644 (file)
@@ -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.