aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGException.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-07-21 05:47:49 +0000
committerJohn McCall <rjmccall@apple.com>2010-07-21 05:47:49 +0000
commit77199713ab56f87ffad9a535ff2a0877704eed87 (patch)
treedb449c91096ce8cf08792c82048150a206a04888 /lib/CodeGen/CGException.cpp
parent50da2cadcc6da86abff6772de65280ace2cabc94 (diff)
Switch finally cleanups over to being lazy cleanups. We get basically nothing
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
Diffstat (limited to 'lib/CodeGen/CGException.cpp')
-rw-r--r--lib/CodeGen/CGException.cpp108
1 files changed, 62 insertions, 46 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index f0c1d5193d..352b324ae2 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -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");