[cfe-commits] r59089 - in /cfe/trunk/lib/CodeGen: CGExprComplex.cpp CGExprScalar.cpp CGObjC.cpp CGObjCMac.cpp CGStmt.cpp CodeGenFunction.cpp CodeGenFunction.h

Daniel Dunbar daniel at zuster.org
Tue Nov 11 15:11:38 PST 2008


Author: ddunbar
Date: Tue Nov 11 17:11:34 2008
New Revision: 59089

URL: http://llvm.org/viewvc/llvm-project?rev=59089&view=rev
Log:
Rework IRgen invariant w.r.t. current insert point.
 - EmitStmt is no longer required to finish with a current insertion
   point defined (i.e. it does not need to make dummy
   blocks). Instead, it can clear the insertion point in the builder
   which indicates that the current insertion point is unreachable.
 - CodeGenFunction provides HaveInsertPoint and EnsureInsertPoint
   which respectively test if there is an insert point and ensure an
   insertion point exists (by making a dummy block).
 - Clearly mark functions in CodeGenFunction which can be called with
   no insertion point defined. Currently this is a limited set, and
   EmitStmt simply EnsureInsertPoint()s before emitting subsequent IR.

Remove EmitDummyBlock, which is no longer needed. Clients who haven't
already cleared the insertion point (typically via EmitBranch) can do
so by hand.

Remove isDummyBlock, which has effectively been renamed to
HaveInsertPoint.

The main thrust of this change is that we no longer have create dummy
blocks just to destroy them a short time later in EmitBlock in the
common case that there is no unreachable code following something like
a goto. 

Additionally, this means that we are not using the hokey condition in
isDummyBlock that a block without a name is a dummy block. Guess how
well that works when we never emit block names!

Modified:
    cfe/trunk/lib/CodeGen/CGExprComplex.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/lib/CodeGen/CGStmt.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=59089&r1=59088&r2=59089&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Tue Nov 11 17:11:34 2008
@@ -461,6 +461,7 @@
 
 ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
   CGF.EmitStmt(E->getLHS());
+  CGF.EnsureInsertPoint();
   return Visit(E->getRHS());
 }
 

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=59089&r1=59088&r2=59089&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Nov 11 17:11:34 2008
@@ -1101,6 +1101,7 @@
 
 Value *ScalarExprEmitter::VisitBinComma(const BinaryOperator *E) {
   CGF.EmitStmt(E->getLHS());
+  CGF.EnsureInsertPoint();
   return Visit(E->getRHS());
 }
 

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=59089&r1=59088&r2=59089&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Tue Nov 11 17:11:34 2008
@@ -334,6 +334,7 @@
 
   if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
     EmitStmt(SD);
+    assert(HaveInsertPoint() && "DeclStmt destroyed insert point!");
     const ScopedDecl* D = SD->getSolitaryDecl();
     ElementTy = cast<ValueDecl>(D)->getType();
     DeclAddress = LocalDeclMap[D];    

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=59089&r1=59088&r2=59089&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Nov 11 17:11:34 2008
@@ -1621,6 +1621,7 @@
       if (AllMatched) {   
         if (CatchParam) {
           CGF.EmitStmt(CatchParam);
+          assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
           CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(VD));
         }
         
@@ -1648,6 +1649,7 @@
       // Emit the @catch block.
       CGF.EmitBlock(MatchedBlock);
       CGF.EmitStmt(CatchParam);
+      assert(CGF.HaveInsertPoint() && "DeclStmt destroyed insert point?");
 
       llvm::Value *Tmp = 
         CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()), 
@@ -1717,15 +1719,15 @@
   
   CGF.Builder.CreateCall(ObjCTypes.ExceptionThrowFn, ExceptionAsObject);
   CGF.Builder.CreateUnreachable();
-  CGF.EmitDummyBlock();
+
+  // Clear the insertion point to indicate we are in unreachable code.
+  CGF.Builder.ClearInsertionPoint();
 }
 
 void CodeGenFunction::EmitJumpThroughFinally(ObjCEHEntry *E,
                                              llvm::BasicBlock *Dst,
                                              bool ExecuteTryExit) {
-  llvm::BasicBlock *Src = Builder.GetInsertBlock();
-    
-  if (!Src || isDummyBlock(Src))
+  if (!HaveInsertPoint())
     return;
   
   // Find the destination code for this block. We always use 0 for the
@@ -1746,7 +1748,7 @@
 
   // Set the destination code and branch.
   Builder.CreateStore(ID, E->DestCode);
-  Builder.CreateBr(ExecuteTryExit ? E->FinallyBlock : E->FinallyNoExit);
+  EmitBranch(ExecuteTryExit ? E->FinallyBlock : E->FinallyNoExit);
 }
 
 /* *** Private Interface *** */

Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=59089&r1=59088&r2=59089&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Tue Nov 11 17:11:34 2008
@@ -27,6 +27,13 @@
 
 void CodeGenFunction::EmitStmt(const Stmt *S) {
   assert(S && "Null statement?");
+
+  // If we happen to be at an unreachable point just create a dummy
+  // basic block to hold the code. We could change parts of irgen to
+  // simply not generate this code, but this situation is rare and
+  // probably not worth the effort.
+  // FIXME: Verify previous performance/effort claim.
+  EnsureInsertPoint();
   
   // Generate stoppoints if we are emitting debug info.
   // Beginning of a Compound Statement (e.g. an opening '{') does not produce 
@@ -128,6 +135,7 @@
     EmitStmt(*I);
 
   if (DI) {
+    EnsureInsertPoint();
     DI->setLocation(S.getRBracLoc());
     DI->EmitRegionEnd(CurFn, Builder);
   }
@@ -145,6 +153,8 @@
     LastStmt = LS->getSubStmt();
   }
   
+  EnsureInsertPoint();
+
   return EmitAnyExpr(cast<Expr>(LastStmt), AggLoc);
 }
 
@@ -164,10 +174,6 @@
   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();
   } else {
     // Otherwise, create a fall-through branch.
     Builder.CreateBr(Target);
@@ -176,10 +182,6 @@
   Builder.ClearInsertionPoint();
 }
 
-void CodeGenFunction::EmitDummyBlock() {
-  EmitBlock(createBasicBlock());
-}
-
 void CodeGenFunction::EmitLabel(const LabelStmt &S) {
   llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
   EmitBlock(NextBB);
@@ -199,10 +201,6 @@
   }
 
   EmitBranch(getBasicBlockForLabel(S.getLabel()));
-  
-  // Emit a block after the branch so that dead code after a goto has some place
-  // to go.
-  EmitDummyBlock();
 }
 
 void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
@@ -221,9 +219,8 @@
   llvm::SwitchInst *I = Builder.CreateSwitch(V, Builder.GetInsertBlock());
   IndirectSwitches.push_back(I);
 
-  // Emit a block after the branch so that dead code after a goto has some place
-  // to go.
-  EmitDummyBlock();
+  // Clear the insertion point to indicate we are in unreachable code.
+  Builder.ClearInsertionPoint();
 }
 
 void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
@@ -445,10 +442,6 @@
     StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false);
   }
   EmitBranch(ReturnBlock);
-
-  // Emit a block after the branch so that dead code after a return has some
-  // place to go.
-  EmitDummyBlock();
 }
 
 /// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
@@ -485,10 +478,6 @@
   } 
 
   EmitBranch(ReturnBlock);
-  
-  // Emit a block after the branch so that dead code after a return has some
-  // place to go.
-  EmitDummyBlock();
 }
 
 void CodeGenFunction::EmitDeclStmt(const DeclStmt &S) {
@@ -502,7 +491,6 @@
 
   llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
   EmitBranch(Block);
-  EmitDummyBlock();
 }
 
 void CodeGenFunction::EmitContinueStmt() {
@@ -510,7 +498,6 @@
 
   llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
   EmitBranch(Block);
-  EmitDummyBlock();
 }
 
 /// EmitCaseStmtRange - If case statement range is not too big then
@@ -566,7 +553,10 @@
   Builder.CreateCondBr(Cond, CaseDest, FalseDest);
 
   // Restore the appropriate insertion point.
-  Builder.SetInsertPoint(RestoreBB);
+  if (RestoreBB)
+    Builder.SetInsertPoint(RestoreBB);
+  else
+    Builder.ClearInsertionPoint();
 }
 
 void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=59089&r1=59088&r2=59089&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Nov 11 17:11:34 2008
@@ -156,14 +156,6 @@
   }
 }
 
-/// isDummyBlock - Return true if BB is an empty basic block
-/// with no predecessors.
-bool CodeGenFunction::isDummyBlock(const llvm::BasicBlock *BB) {
-  if (BB->empty() && pred_begin(BB) == pred_end(BB) && !BB->hasName()) 
-    return true;
-  return false;
-}
-
 /// ContainsLabel - Return true if the statement contains a label in it.  If
 /// this statement is not executed normally, it not containing a label means
 /// that we can just remove the code.

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=59089&r1=59088&r2=59089&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Nov 11 17:11:34 2008
@@ -119,7 +119,8 @@
 
   /// EmitJumpThroughFinally - Emit a branch from the current insert
   /// point through the finally handling code for \arg Entry and then
-  /// on to \arg Dest.
+  /// on to \arg Dest. It is legal to call this function even if there
+  /// is no current insertion point.
   ///
   /// \param ExecuteTryExit - When true, the try_exit runtime function
   /// should be called prior to executing the finally code.
@@ -186,6 +187,10 @@
                      llvm::Function *Fn,
                      const FunctionArgList &Args,
                      SourceLocation StartLoc);
+
+  /// FinishFunction - Complete IR generation of the current
+  /// function. It is legal to call this function even if there is no
+  /// current insertion point.
   void FinishFunction(SourceLocation EndLoc=SourceLocation());
 
   /// EmitFunctionProlog - Emit the target specific LLVM code to load
@@ -224,21 +229,38 @@
   /// label maps to.
   llvm::BasicBlock *getBasicBlockForLabel(const LabelStmt *S);
   
+  /// EmitBlock - Emit the given block \arg BB and set it as the
+  /// insert point, adding a fall-through branch from the current
+  /// insert block if necessary. It is legal to call this function
+  /// even if there is no current insertion point.
   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.
+  /// from dummy blocks. It is legal to call this function even if
+  /// there is no current insertion point.
   ///
   /// This function clears the current insertion point. The caller
   /// should follow calls to this function with calls to Emit*Block
   /// prior to generation new code.
   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.
-  void EmitDummyBlock();
+  /// HaveInsertPoint - True if an insertion point is defined. If not,
+  /// this indicates that the current code being emitted is
+  /// unreachable.
+  bool HaveInsertPoint() const { 
+    return Builder.GetInsertBlock() != 0;
+  }
+
+  /// EnsureInsertPoint - Ensure that an insertion point is defined so
+  /// that emitted IR has a place to go. Note that by definition, if
+  /// this function creates a block then that block is unreachable;
+  /// callers may do better to detect when no insertion point is
+  /// defined and simply skip IR generation.
+  void EnsureInsertPoint() {
+    if (!HaveInsertPoint())
+      EmitBlock(createBasicBlock());
+  }
   
   /// ErrorUnsupported - Print out an error that codegen doesn't support the
   /// specified stmt yet.
@@ -276,10 +298,6 @@
 
   void EmitAggregateClear(llvm::Value *DestPtr, QualType Ty);
 
-  /// isDummyBlock - Return true if BB is an empty basic block
-  /// with no predecessors.
-  static bool isDummyBlock(const llvm::BasicBlock *BB);
-
   /// StartBlock - Start new block named N. If insert block is a dummy block
   /// then reuse it.
   void StartBlock(const char *N);
@@ -324,10 +342,24 @@
   //                             Statement Emission
   //===--------------------------------------------------------------------===//
 
+  /// EmitStmt - Emit the code for the statement \arg S. It is legal
+  /// to call this function even if there is no current insertion
+  /// point.
+  /// 
+  /// This function may clear the current insertion point; callers
+  /// should use EnsureInsertPoint if they wish to subsequently
+  /// generate code without first calling EmitBlock, EmitBranch, or
+  /// EmitStmt.
   void EmitStmt(const Stmt *S);
+
   RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
                           llvm::Value *AggLoc = 0, bool isAggVol = false);
+
+  /// EmitLabel - Emit the block for the given label. It is legal
+  /// to call this function even if there is no current insertion
+  /// point.
   void EmitLabel(const LabelStmt &S); // helper for EmitLabelStmt.
+
   void EmitLabelStmt(const LabelStmt &S);
   void EmitGotoStmt(const GotoStmt &S);
   void EmitIndirectGotoStmt(const IndirectGotoStmt &S);





More information about the cfe-commits mailing list