[cfe-commits] r59118 - in /cfe/trunk/lib/CodeGen: CGStmt.cpp CodeGenFunction.h

Daniel Dunbar daniel at zuster.org
Wed Nov 12 00:21:33 PST 2008


Author: ddunbar
Date: Wed Nov 12 02:21:33 2008
New Revision: 59118

URL: http://llvm.org/viewvc/llvm-project?rev=59118&view=rev
Log:
IRgen improvements on unreachable code:
 - Split out "simple" statements which can easily handle IR generation
   when there is no insert point. These are generally statements which
   start by emitting a new block or are only containers for other
   statements.

 - This fixes a regression in emitting dummy blocks, notably for case
   statements.

 - This also fixes spurious emission of a number of debug stoppoint
   intrinsic instructions.

Remove unneeded sw.body block, just clear the insertion point.

Lift out CodeGenFunction::EmitStopPoint which calls into the
CGDebugInfo class when generating debug info.

Normalize definitions of Emit{Break,Continue}Stmt and usage of
ErrorUnsupported.

Modified:
    cfe/trunk/lib/CodeGen/CGStmt.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Nov 12 02:21:33 2008
@@ -25,9 +25,21 @@
 //                              Statement Emission
 //===----------------------------------------------------------------------===//
 
+void CodeGenFunction::EmitStopPoint(const Stmt *S) {
+  if (CGDebugInfo *DI = CGM.getDebugInfo()) {
+    DI->setLocation(S->getLocStart());
+    DI->EmitStopPoint(CurFn, Builder);
+  }
+}
+
 void CodeGenFunction::EmitStmt(const Stmt *S) {
   assert(S && "Null statement?");
 
+  // Check if we can handle this without bothering to generate an
+  // insert point or debug info.
+  if (EmitSimpleStmt(S))
+    return;
+
   // 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
@@ -35,14 +47,8 @@
   // 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 
-  // executable code. So do not generate a stoppoint for that.
-  CGDebugInfo *DI = CGM.getDebugInfo();
-  if (DI && S->getStmtClass() != Stmt::CompoundStmtClass) {
-    DI->setLocation(S->getLocStart());
-    DI->EmitStopPoint(CurFn, Builder);
-  }
+  // Generate a stoppoint if we are emitting debug info.
+  EmitStopPoint(S);
 
   switch (S->getStmtClass()) {
   default:
@@ -59,10 +65,6 @@
       ErrorUnsupported(S, "statement");
     }
     break;
-  case Stmt::NullStmtClass: break;
-  case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
-  case Stmt::LabelStmtClass:    EmitLabelStmt(cast<LabelStmt>(*S));       break;
-  case Stmt::GotoStmtClass:     EmitGotoStmt(cast<GotoStmt>(*S));         break;
   case Stmt::IndirectGotoStmtClass:  
     EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break;
 
@@ -73,28 +75,8 @@
     
   case Stmt::ReturnStmtClass:   EmitReturnStmt(cast<ReturnStmt>(*S));     break;
   case Stmt::DeclStmtClass:     EmitDeclStmt(cast<DeclStmt>(*S));         break;
-      
-  case Stmt::BreakStmtClass:    
-    // FIXME: Implement break in @try or @catch blocks.
-    if (!ObjCEHStack.empty()) {
-      CGM.ErrorUnsupported(S, "continue inside an Obj-C exception block");
-      return;
-    }
-    EmitBreakStmt();                          
-    break;
-
-  case Stmt::ContinueStmtClass: 
-    // FIXME: Implement continue in @try or @catch blocks.
-    if (!ObjCEHStack.empty()) {
-      CGM.ErrorUnsupported(S, "continue inside an Obj-C exception block");
-      return;
-    }
-    EmitContinueStmt();                       
-    break;
 
   case Stmt::SwitchStmtClass:   EmitSwitchStmt(cast<SwitchStmt>(*S));     break;
-  case Stmt::DefaultStmtClass:  EmitDefaultStmt(cast<DefaultStmt>(*S));   break;
-  case Stmt::CaseStmtClass:     EmitCaseStmt(cast<CaseStmt>(*S));         break;
   case Stmt::AsmStmtClass:      EmitAsmStmt(cast<AsmStmt>(*S));           break;
 
   case Stmt::ObjCAtTryStmtClass:
@@ -118,6 +100,22 @@
   }
 }
 
+bool CodeGenFunction::EmitSimpleStmt(const Stmt *S) {
+  switch (S->getStmtClass()) {
+  default: return false;
+  case Stmt::NullStmtClass: break;
+  case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
+  case Stmt::LabelStmtClass:    EmitLabelStmt(cast<LabelStmt>(*S));       break;
+  case Stmt::GotoStmtClass:     EmitGotoStmt(cast<GotoStmt>(*S));         break;
+  case Stmt::BreakStmtClass:    EmitBreakStmt(cast<BreakStmt>(*S));       break;
+  case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break;
+  case Stmt::DefaultStmtClass:  EmitDefaultStmt(cast<DefaultStmt>(*S));   break;
+  case Stmt::CaseStmtClass:     EmitCaseStmt(cast<CaseStmt>(*S));         break;
+  }
+
+  return true;
+}
+
 /// EmitCompoundStmt - Emit a compound statement {..} node.  If GetLast is true,
 /// this captures the expression result of the last sub-statement and returns it
 /// (for use by the statement expression extension).
@@ -126,6 +124,7 @@
   // FIXME: handle vla's etc.
   CGDebugInfo *DI = CGM.getDebugInfo();
   if (DI) {
+    EnsureInsertPoint();
     DI->setLocation(S.getLBracLoc());
     DI->EmitRegionStart(CurFn, Builder);
   }
@@ -200,6 +199,11 @@
     return;
   }
 
+  // If this code is reachable then emit a stop point (if generating
+  // debug info). We have to do this ourselves because we are on the
+  // "simple" statement path.
+  if (HaveInsertPoint())
+    EmitStopPoint(&S);
   EmitBranch(getBasicBlockForLabel(S.getLabel()));
 }
 
@@ -485,16 +489,38 @@
     EmitDecl(**I);
 }
 
-void CodeGenFunction::EmitBreakStmt() {
+void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {
   assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
 
+  // FIXME: Implement break in @try or @catch blocks.
+  if (!ObjCEHStack.empty()) {
+    CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block");
+    return;
+  }
+
+  // If this code is reachable then emit a stop point (if generating
+  // debug info). We have to do this ourselves because we are on the
+  // "simple" statement path.
+  if (HaveInsertPoint())
+    EmitStopPoint(&S);
   llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
   EmitBranch(Block);
 }
 
-void CodeGenFunction::EmitContinueStmt() {
+void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) {
   assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
 
+  // FIXME: Implement continue in @try or @catch blocks.
+  if (!ObjCEHStack.empty()) {
+    CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block");
+    return;
+  }
+
+  // If this code is reachable then emit a stop point (if generating
+  // debug info). We have to do this ourselves because we are on the
+  // "simple" statement path.
+  if (HaveInsertPoint())
+    EmitStopPoint(&S);
   llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
   EmitBranch(Block);
 }
@@ -595,8 +621,8 @@
   SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
   CaseRangeBlock = DefaultBlock;
 
-  // Create basic block for body of switch
-  EmitBlock(createBasicBlock("sw.body"));
+  // Clear the insertion point to indicate we are in unreachable code.
+  Builder.ClearInsertionPoint();
 
   // All break statements jump to NextBlock. If BreakContinueStack is non empty
   // then reuse last ContinueBlock.

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Nov 12 02:21:33 2008
@@ -346,6 +346,10 @@
   //                             Statement Emission
   //===--------------------------------------------------------------------===//
 
+  /// EmitStopPoint - Emit a debug stoppoint if we are emitting debug
+  /// info.
+  void EmitStopPoint(const Stmt *S);
+
   /// EmitStmt - Emit the code for the statement \arg S. It is legal
   /// to call this function even if there is no current insertion
   /// point.
@@ -356,6 +360,14 @@
   /// EmitStmt.
   void EmitStmt(const Stmt *S);
 
+  /// EmitSimpleStmt - Try to emit a "simple" statement which does not
+  /// necessarily require an insertion point or debug information;
+  /// typically because the statement amounts to a jump or a container
+  /// of other statements.
+  ///
+  /// \return True if the statement was handled.
+  bool EmitSimpleStmt(const Stmt *S);
+
   RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
                           llvm::Value *AggLoc = 0, bool isAggVol = false);
 
@@ -373,8 +385,8 @@
   void EmitForStmt(const ForStmt &S);
   void EmitReturnStmt(const ReturnStmt &S);
   void EmitDeclStmt(const DeclStmt &S);
-  void EmitBreakStmt();
-  void EmitContinueStmt();
+  void EmitBreakStmt(const BreakStmt &S);
+  void EmitContinueStmt(const ContinueStmt &S);
   void EmitSwitchStmt(const SwitchStmt &S);
   void EmitDefaultStmt(const DefaultStmt &S);
   void EmitCaseStmt(const CaseStmt &S);





More information about the cfe-commits mailing list