]> granicus.if.org Git - clang/commitdiff
Switch finally cleanups over to being lazy cleanups. We get basically nothing
authorJohn McCall <rjmccall@apple.com>
Wed, 21 Jul 2010 05:47:49 +0000 (05:47 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 21 Jul 2010 05:47:49 +0000 (05:47 +0000)
from the laziness features here except better block ordering, but it removes yet
another CleanupBlock use.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108990 91177308-0d34-0410-b5e6-96231b3b80d8

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

index f0c1d5193d0b06553a3f67afeac4024555a88fb0..352b324ae2912e27b292a72cd32de0aeb673e188 100644 (file)
@@ -1357,6 +1357,65 @@ namespace {
       CGF.EmitBlock(CleanupContBB);
     }
   };
+
+  struct PerformFinally : EHScopeStack::LazyCleanup {
+    const Stmt *Body;
+    llvm::Value *ForEHVar;
+    llvm::Value *EndCatchFn;
+    llvm::Value *RethrowFn;
+    llvm::Value *SavedExnVar;
+
+    PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
+                   llvm::Value *EndCatchFn,
+                   llvm::Value *RethrowFn, llvm::Value *SavedExnVar)
+      : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
+        RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
+
+    void Emit(CodeGenFunction &CGF, bool IsForEH) {
+      // Enter a cleanup to call the end-catch function if one was provided.
+      if (EndCatchFn)
+        CGF.EHStack.pushLazyCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
+                                                         ForEHVar, EndCatchFn);
+
+      // Emit the finally block.
+      CGF.EmitStmt(Body);
+
+      // If the end of the finally is reachable, check whether this was
+      // for EH.  If so, rethrow.
+      if (CGF.HaveInsertPoint()) {
+        llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
+        llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
+
+        llvm::Value *ShouldRethrow =
+          CGF.Builder.CreateLoad(ForEHVar, "finally.shouldthrow");
+        CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
+
+        CGF.EmitBlock(RethrowBB);
+        if (SavedExnVar) {
+          llvm::Value *Args[] = { CGF.Builder.CreateLoad(SavedExnVar) };
+          CGF.EmitCallOrInvoke(RethrowFn, Args, Args+1);
+        } else {
+          CGF.EmitCallOrInvoke(RethrowFn, 0, 0);
+        }
+        CGF.Builder.CreateUnreachable();
+
+        CGF.EmitBlock(ContBB);
+      }
+
+      // Leave the end-catch cleanup.  As an optimization, pretend that
+      // the fallthrough path was inaccessible; we've dynamically proven
+      // that we're not in the EH case along that path.
+      if (EndCatchFn) {
+        CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
+        CGF.PopCleanupBlock();
+        CGF.Builder.restoreIP(SavedIP);
+      }
+    
+      // Now make sure we actually have an insertion point or the
+      // cleanup gods will hate us.
+      CGF.EnsureInsertPoint();
+    }
+  };
 }
 
 /// Enters a finally block for an implementation using zero-cost
@@ -1410,52 +1469,9 @@ CodeGenFunction::EnterFinallyBlock(const Stmt *Body,
   InitTempAlloca(ForEHVar, llvm::ConstantInt::getFalse(getLLVMContext()));
 
   // Enter a normal cleanup which will perform the @finally block.
-  {
-    CodeGenFunction::CleanupBlock Cleanup(*this, NormalCleanup);
-
-    // Enter a cleanup to call the end-catch function if one was provided.
-    if (EndCatchFn)
-      EHStack.pushLazyCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
-                                                      ForEHVar, EndCatchFn);
-
-    // Emit the finally block.
-    EmitStmt(Body);
-
-    // If the end of the finally is reachable, check whether this was
-    // for EH.  If so, rethrow.
-    if (HaveInsertPoint()) {
-      llvm::BasicBlock *RethrowBB = createBasicBlock("finally.rethrow");
-      llvm::BasicBlock *ContBB = createBasicBlock("finally.cont");
-
-      llvm::Value *ShouldRethrow =
-        Builder.CreateLoad(ForEHVar, "finally.shouldthrow");
-      Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
-
-      EmitBlock(RethrowBB);
-      if (SavedExnVar) {
-        llvm::Value *Args[] = { Builder.CreateLoad(SavedExnVar) };
-        EmitCallOrInvoke(RethrowFn, Args, Args+1);
-      } else {
-        EmitCallOrInvoke(RethrowFn, 0, 0);
-      }
-      Builder.CreateUnreachable();
-
-      EmitBlock(ContBB);
-    }
-
-    // Leave the end-catch cleanup.  As an optimization, pretend that
-    // the fallthrough path was inaccessible; we've dynamically proven
-    // that we're not in the EH case along that path.
-    if (EndCatchFn) {
-      CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
-      PopCleanupBlock();
-      Builder.restoreIP(SavedIP);
-    }
-    
-    // Now make sure we actually have an insertion point or the
-    // cleanup gods will hate us.
-    EnsureInsertPoint();
-  }
+  EHStack.pushLazyCleanup<PerformFinally>(NormalCleanup, Body,
+                                          ForEHVar, EndCatchFn,
+                                          RethrowFn, SavedExnVar);
 
   // Enter a catch-all scope.
   llvm::BasicBlock *CatchAllBB = createBasicBlock("finally.catchall");
index 26f6b63eeb6ae03174543d98606182cdd5c86cb0..60fd3a34bde528d8d7ad9e8d610d244f21260edc 100644 (file)
@@ -255,6 +255,14 @@ public:
     (void) Obj;
   }
 
+  /// Push a lazily-created cleanup on the stack.
+  template <class T, class A0, class A1, class A2, class A3, class A4>
+  void pushLazyCleanup(CleanupKind Kind, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+    void *Buffer = pushLazyCleanup(Kind, sizeof(T));
+    LazyCleanup *Obj = new(Buffer) T(a0, a1, a2, a3, a4);
+    (void) Obj;
+  }
+
   /// Push a cleanup on the stack.
   void pushCleanup(llvm::BasicBlock *NormalEntry,
                    llvm::BasicBlock *NormalExit,