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

Mike Stump mrs at apple.com
Sun Feb 8 01:22:21 PST 2009


Author: mrs
Date: Sun Feb  8 03:22:19 2009
New Revision: 64079

URL: http://llvm.org/viewvc/llvm-project?rev=64079&view=rev
Log:
Wire up break and continue processing to the new stack depth adjuster.
If people could beat on it and let me know if there are any new
semantics required by newer language standards or DRs or any little
details I goofed on, I'd be happy to fix any issues found.

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=64079&r1=64078&r2=64079&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Sun Feb  8 03:22:19 2009
@@ -198,20 +198,7 @@
   Builder.SetInsertPoint(BB);
 }
 
-void CodeGenFunction::EmitStackUpdate(const LabelStmt &S) {
-  if (StackDepthMap.find(&S) == StackDepthMap.end()) {
-    // If we can't find it, just remember the depth now,
-    // so we can validate it later.
-    // FIXME: We need to save a place to insert the adjustment,
-    // if needed, here, sa that later in EmitLabel, we can
-    // backpatch the adjustment into that place, instead of
-    // saying unsupported.
-    StackDepthMap[&S] = StackDepth;
-    return;
-  }
-      
-  // Find applicable stack depth, if any...
-  llvm::Value *V = StackDepthMap[&S];
+bool CodeGenFunction::EmitStackUpdate(llvm::Value *V) {
   // V can be 0 here, if it is, be sure to start searching from the
   // top of the function, as we want the next save after that point.
   for (unsigned int i = 0; i < StackSaveValues.size(); ++i)
@@ -227,10 +214,25 @@
         llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
         Builder.CreateCall(F, V);
       }
-    } else
-      // FIXME: Move to semq and assert here, codegen isn't the right
-      // time to be checking.
-      CGM.ErrorUnsupported(&S, "invalid goto to VLA scope that has finished");
+    } else return true;
+  return false;
+}
+
+bool CodeGenFunction::EmitStackUpdate(const void  *S) {
+  if (StackDepthMap.find(S) == StackDepthMap.end()) {
+    // If we can't find it, just remember the depth now,
+    // so we can validate it later.
+    // FIXME: We need to save a place to insert the adjustment,
+    // if needed, here, sa that later in EmitLabel, we can
+    // backpatch the adjustment into that place, instead of
+    // saying unsupported.
+    StackDepthMap[S] = StackDepth;
+    return false;
+  }
+      
+  // Find applicable stack depth, if any...
+  llvm::Value *V = StackDepthMap[S];
+  return EmitStackUpdate(V);
 }
 
 void CodeGenFunction::EmitBranch(llvm::BasicBlock *Target) {
@@ -250,24 +252,30 @@
   Builder.ClearInsertionPoint();
 }
 
-void CodeGenFunction::EmitLabel(const LabelStmt &S) {
-  llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
-  if (StackDepthMap.find(&S) == StackDepthMap.end()) {
+bool CodeGenFunction::StackFixupAtLabel(const void *S) {
+  if (StackDepthMap.find(S) == StackDepthMap.end()) {
     // We need to remember the stack depth so that we can readjust the
     // stack back to the right depth for this label if we want to
     // transfer here from a different depth.
-    StackDepthMap[&S] = StackDepth;
+    StackDepthMap[S] = StackDepth;
   } else {
-    if (StackDepthMap[&S] != StackDepth) {
+    if (StackDepthMap[S] != StackDepth) {
       // FIXME: Sema needs to ckeck for jumps that cross decls with
       // initializations for C++, and all VLAs, not just the first in
       // a block that does a stacksave.
       // FIXME: We need to save a place to insert the adjustment
       // when we do a EmitStackUpdate on a forward jump, and then
       // backpatch the adjustment into that place.
-      CGM.ErrorUnsupported(&S, "forward goto inside scope with VLA");
+      return true;
     }
   }
+  return false;
+}
+
+void CodeGenFunction::EmitLabel(const LabelStmt &S) {
+  llvm::BasicBlock *NextBB = getBasicBlockForLabel(&S);
+  if (StackFixupAtLabel(&S))
+    CGM.ErrorUnsupported(&S, "forward goto inside scope with VLA");
   EmitBlock(NextBB);
 }
 
@@ -292,7 +300,11 @@
 
   // We need to adjust the stack, if the destination was (will be) at
   // a different depth.
-  EmitStackUpdate(*S.getLabel());
+  if (EmitStackUpdate(S.getLabel()))
+    // FIXME: Move to semq and assert here, codegen isn't the right
+    // time to be checking.
+    CGM.ErrorUnsupported(S.getLabel(),
+                         "invalid goto to VLA scope that has finished");
 
   EmitBranch(getBasicBlockForLabel(S.getLabel()));
 }
@@ -595,18 +607,17 @@
     return;
   }
 
-  for (unsigned i = 0; i < StackSaveValues.size(); i++) {
-    if (StackSaveValues[i]) {
-      CGM.ErrorUnsupported(&S, "break inside scope with VLA");
-      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);
+
+  // We need to adjust the stack, if the destination was (will be) at
+  // a different depth.
+  if (EmitStackUpdate(BreakContinueStack.back().SaveBreakStackDepth))
+    assert (0 && "break vla botch");
+
   llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
   EmitBranch(Block);
 }
@@ -620,18 +631,17 @@
     return;
   }
 
-  for (unsigned i = 0; i < StackSaveValues.size(); i++) {
-    if (StackSaveValues[i]) {
-      CGM.ErrorUnsupported(&S, "continue inside scope with VLA");
-      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);
+
+  // We need to adjust the stack, if the destination was (will be) at
+  // a different depth.
+  if (EmitStackUpdate(BreakContinueStack.back().SaveContinueStackDepth))
+    assert (0 && "continue vla botch");
+
   llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
   EmitBranch(Block);
 }

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sun Feb  8 03:22:19 2009
@@ -264,12 +264,28 @@
   /// the return value of llvm.stacksave() is stored at the top of this stack.
   llvm::SmallVector<llvm::Value*, 8> StackSaveValues;
   
-  llvm::DenseMap<const LabelStmt*, llvm::Value *> StackDepthMap;
+  llvm::DenseMap<const void*, llvm::Value *> StackDepthMap;
+
+  /// StackFixupAtLabel - Routine to adjust the stack to the depth the
+  /// stack should be at by the time we transfer control flow to the
+  /// label.  This is called as we emit destinations for control flow,
+  /// such as user labels for goto statements and compiler generated
+  /// labels for break and continue processsing.  We return true, if
+  /// for any reason we can't generate code for the construct yet.
+  /// See EmitStackUpdate for the paired routine to mark the branch.
+  bool StackFixupAtLabel(const void *);
 
   /// EmitStackUpdate - Routine to adjust the stack to the depth the
   /// stack should be at by the time we transfer control flow to the
-  /// label.
-  void EmitStackUpdate(const LabelStmt &S);
+  /// label.  This is called just before emitting branches for user
+  /// level goto processing, branhes for break or continue processing.
+  /// The llvm::value overload is used when handling break and
+  /// continue, as we know the stack depth directly.  We return true,
+  /// if for any reason we can't generate code for the construct yet.
+  /// See StackFixupAtLabel for the paired routine to mark the
+  /// destinations.
+  bool EmitStackUpdate(llvm::Value *V);
+  bool EmitStackUpdate(const void *S);
 
   struct CleanupEntry {
     /// CleanupBlock - The block of code that does the actual cleanup.





More information about the cfe-commits mailing list