]> granicus.if.org Git - clang/commitdiff
More cleanup enabling.
authorJohn McCall <rjmccall@apple.com>
Sat, 14 Aug 2010 07:46:19 +0000 (07:46 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 14 Aug 2010 07:46:19 +0000 (07:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111070 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGException.h
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h

index f40e3e32c2081bfdf46f48bdaf4fa9db9c393730..f1294746a42deb14e023b60774dadd8be01364b2 100644 (file)
@@ -565,6 +565,28 @@ EHScopeStack::stabilize(iterator ir) const {
   return stable_iterator(EndOfBuffer - ir.Ptr);
 }
 
+inline EHScopeStack::stable_iterator
+EHScopeStack::getInnermostActiveNormalCleanup() const {
+  for (EHScopeStack::stable_iterator
+         I = getInnermostNormalCleanup(), E = stable_end(); I != E; ) {
+    EHCleanupScope &S = cast<EHCleanupScope>(*find(I));
+    if (S.isActive()) return I;
+    I = S.getEnclosingNormalCleanup();
+  }
+  return stable_end();
+}
+
+inline EHScopeStack::stable_iterator
+EHScopeStack::getInnermostActiveEHCleanup() const {
+  for (EHScopeStack::stable_iterator
+         I = getInnermostEHCleanup(), E = stable_end(); I != E; ) {
+    EHCleanupScope &S = cast<EHCleanupScope>(*find(I));
+    if (S.isActive()) return I;
+    I = S.getEnclosingEHCleanup();
+  }
+  return stable_end();
+}
+
 }
 }
 
index b3ac8f1ddbef02542e3af186b4566baeef065322..5bee016d7e5093511fba321843659c6cc88f14b5 100644 (file)
@@ -805,6 +805,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) {
   assert(isa<EHCleanupScope>(*EHStack.begin()) && "top not a cleanup!");
   EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin());
   assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups());
+  assert(Scope.isActive() && "cleanup was still inactive when popped!");
 
   // Check whether we need an EH cleanup.  This is only true if we've
   // generated a lazy EH cleanup block.
@@ -1100,11 +1101,15 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) {
   // Create the branch.
   llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
 
-  // If we're not in a cleanup scope, or if the destination scope is
-  // the current normal-cleanup scope, we don't need to worry about
-  // fixups.
-  if (!EHStack.hasNormalCleanups() ||
-      Dest.getScopeDepth() == EHStack.getInnermostNormalCleanup()) {
+  // Calculate the innermost active normal cleanup.
+  EHScopeStack::stable_iterator
+    TopCleanup = EHStack.getInnermostActiveNormalCleanup();
+
+  // If we're not in an active normal cleanup scope, or if the
+  // destination scope is within the innermost active normal cleanup
+  // scope, we don't need to worry about fixups.
+  if (TopCleanup == EHStack.stable_end() ||
+      TopCleanup.encloses(Dest.getScopeDepth())) { // works for invalid
     Builder.ClearInsertionPoint();
     return;
   }
@@ -1131,12 +1136,12 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) {
   // Adjust BI to point to the first cleanup block.
   {
     EHCleanupScope &Scope =
-      cast<EHCleanupScope>(*EHStack.find(EHStack.getInnermostNormalCleanup()));
+      cast<EHCleanupScope>(*EHStack.find(TopCleanup));
     BI->setSuccessor(0, CreateNormalEntry(*this, Scope));
   }
 
   // Add this destination to all the scopes involved.
-  EHScopeStack::stable_iterator I = EHStack.getInnermostNormalCleanup();
+  EHScopeStack::stable_iterator I = TopCleanup;
   EHScopeStack::stable_iterator E = Dest.getScopeDepth();
   if (E.strictlyEncloses(I)) {
     while (true) {
@@ -1173,13 +1178,17 @@ void CodeGenFunction::EmitBranchThroughEHCleanup(UnwindDest Dest) {
   // Create the branch.
   llvm::BranchInst *BI = Builder.CreateBr(Dest.getBlock());
 
+  // Calculate the innermost active cleanup.
+  EHScopeStack::stable_iterator
+    InnermostCleanup = EHStack.getInnermostActiveEHCleanup();
+
   // If the destination is in the same EH cleanup scope as us, we
   // don't need to thread through anything.
-  if (Dest.getScopeDepth() == EHStack.getInnermostEHCleanup()) {
+  if (InnermostCleanup.encloses(Dest.getScopeDepth())) {
     Builder.ClearInsertionPoint();
     return;
   }
-  assert(EHStack.hasEHCleanups());
+  assert(InnermostCleanup != EHStack.stable_end());
 
   // Store the index at the start.
   llvm::ConstantInt *Index = Builder.getInt32(Dest.getDestIndex());
@@ -1188,14 +1197,13 @@ void CodeGenFunction::EmitBranchThroughEHCleanup(UnwindDest Dest) {
   // Adjust BI to point to the first cleanup block.
   {
     EHCleanupScope &Scope =
-      cast<EHCleanupScope>(*EHStack.find(EHStack.getInnermostEHCleanup()));
+      cast<EHCleanupScope>(*EHStack.find(InnermostCleanup));
     BI->setSuccessor(0, CreateEHEntry(*this, Scope));
   }
   
   // Add this destination to all the scopes involved.
   for (EHScopeStack::stable_iterator
-         I = EHStack.getInnermostEHCleanup(),
-         E = Dest.getScopeDepth(); ; ) {
+         I = InnermostCleanup, E = Dest.getScopeDepth(); ; ) {
     assert(E.strictlyEncloses(I));
     EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(I));
     assert(Scope.isEHCleanup());
index 3d212b5f7824c8acb6a449afe38158dac0657dfe..a7c3a289daf6ce08c3088fc0330018835b92dcf3 100644 (file)
@@ -127,7 +127,15 @@ public:
 
     bool isValid() const { return Size >= 0; }
 
+    /// Returns true if this scope encloses I.
+    /// Returns false if I is invalid.
+    /// This scope must be valid.
     bool encloses(stable_iterator I) const { return Size <= I.Size; }
+
+    /// Returns true if this scope strictly encloses I: that is,
+    /// if it encloses I and is not I.
+    /// Returns false is I is invalid.
+    /// This scope must be valid.
     bool strictlyEncloses(stable_iterator I) const { return Size < I.Size; }
 
     friend bool operator==(stable_iterator A, stable_iterator B) {
@@ -317,6 +325,7 @@ public:
   stable_iterator getInnermostNormalCleanup() const {
     return InnermostNormalCleanup;
   }
+  stable_iterator getInnermostActiveNormalCleanup() const; // CGException.h
 
   /// Determines whether there are any EH cleanups on the stack.
   bool hasEHCleanups() const {
@@ -328,6 +337,7 @@ public:
   stable_iterator getInnermostEHCleanup() const {
     return InnermostEHCleanup;
   }
+  stable_iterator getInnermostActiveEHCleanup() const; // CGException.h
 
   /// An unstable reference to a scope-stack depth.  Invalidated by
   /// pushes but not pops.