diff options
author | John McCall <rjmccall@apple.com> | 2011-01-26 04:00:11 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-01-26 04:00:11 +0000 |
commit | 150b462afc7a713edd19bcbbbb22381fe060d4f5 (patch) | |
tree | d90a44bc497a080b64d9143f25f9ef32b6c1228f /lib/CodeGen/CGException.cpp | |
parent | 83f51722ed2b8134810cb178f39e44da811de7cd (diff) |
Better framework for conditional cleanups; untested as yet.
I'm separately committing this because it incidentally changes some
block orderings and minor IR issues, like using a phi instead of
an unnecessary alloca.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124277 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGException.cpp')
-rw-r--r-- | lib/CodeGen/CGException.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 78655bdc11..5845f1ec02 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -172,6 +172,22 @@ void EHScopeStack::popNullFixups() { BranchFixups.pop_back(); } +llvm::Value *CodeGenFunction::initFullExprCleanup() { + // Create a variable to decide whether the cleanup needs to be run. + llvm::AllocaInst *run = CreateTempAlloca(Builder.getInt1Ty(), "cleanup.cond"); + + // Initialize it to false at a site that's guaranteed to be run + // before each evaluation. + llvm::BasicBlock *block = OutermostConditional->getStartingBlock(); + new llvm::StoreInst(Builder.getFalse(), run, + block->getFirstNonPHIOrDbg()); + + // Initialize it to true at the current location. + Builder.CreateStore(Builder.getTrue(), run); + + return run; +} + static llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) { // void *__cxa_allocate_exception(size_t thrown_size); const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType()); @@ -1656,3 +1672,23 @@ CodeGenFunction::UnwindDest CodeGenFunction::getRethrowDest() { EHScopeStack::Cleanup::~Cleanup() { llvm_unreachable("Cleanup is indestructable"); } + +void EHScopeStack::ConditionalCleanup::Emit(CodeGenFunction &CGF, + bool IsForEHCleanup) { + // Determine whether we should run the cleanup. + llvm::Value *condVal = CGF.Builder.CreateLoad(cond, "cond.should-run"); + + llvm::BasicBlock *cleanup = CGF.createBasicBlock("cond-cleanup.run"); + llvm::BasicBlock *cont = CGF.createBasicBlock("cond-cleanup.cont"); + + // If we shouldn't run the cleanup, jump directly to the continuation block. + CGF.Builder.CreateCondBr(condVal, cleanup, cont); + CGF.EmitBlock(cleanup); + + // Emit the core of the cleanup. + EmitImpl(CGF, IsForEHCleanup); + assert(CGF.HaveInsertPoint() && "cleanup didn't end with valid IP!"); + + // Fall into the continuation block. + CGF.EmitBlock(cont); +} |