diff options
author | John McCall <rjmccall@apple.com> | 2011-08-07 07:05:57 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-08-07 07:05:57 +0000 |
commit | f66a3ea8595d44843f43b8c4b0825b1f8ceeda78 (patch) | |
tree | e7980e73dc5ba2c95f87757f7fe90877db42332d /lib/CodeGen/CGCleanup.cpp | |
parent | e1f6dea1c9593651116fa9a5faa05647d18f3193 (diff) |
Avoid fallthrough-branching to an inactive cleanup even if it's
otherwise required.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137029 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCleanup.cpp')
-rw-r--r-- | lib/CodeGen/CGCleanup.cpp | 77 |
1 files changed, 33 insertions, 44 deletions
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp index 5e86d542ca..c1feb1446d 100644 --- a/lib/CodeGen/CGCleanup.cpp +++ b/lib/CodeGen/CGCleanup.cpp @@ -586,33 +586,32 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (Scope.isEHCleanup()) cleanupFlags.setIsEHCleanupKind(); - // Even if we don't need the normal cleanup, we might still have - // prebranched fallthrough to worry about. - if (Scope.isNormalCleanup() && !RequiresNormalCleanup && - HasPrebranchedFallthrough) { - assert(!IsActive); - - llvm::BasicBlock *NormalEntry = Scope.getNormalBlock(); - - // If we're branching through this cleanup, just forward the - // prebranched fallthrough to the next cleanup, leaving the insert - // point in the old block. + // If we have a prebranched fallthrough into an inactive normal + // cleanup, rewrite it so that it leads to the appropriate place. + if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) { + llvm::BasicBlock *prebranchDest; + + // If the prebranch is semantically branching through the next + // cleanup, just forward it to the next block, leaving the + // insertion point in the prebranched block. if (FallthroughIsBranchThrough) { - EHScope &S = *EHStack.find(Scope.getEnclosingNormalCleanup()); - llvm::BasicBlock *EnclosingEntry = - CreateNormalEntry(*this, cast<EHCleanupScope>(S)); + EHScope &enclosing = *EHStack.find(Scope.getEnclosingNormalCleanup()); + prebranchDest = CreateNormalEntry(*this, cast<EHCleanupScope>(enclosing)); - ForwardPrebranchedFallthrough(FallthroughSource, - NormalEntry, EnclosingEntry); - assert(NormalEntry->use_empty() && - "uses of entry remain after forwarding?"); - delete NormalEntry; - - // Otherwise, we're branching out; just emit the next block. + // Otherwise, we need to make a new block. If the normal cleanup + // isn't being used at all, we could actually reuse the normal + // entry block, but this is simpler, and it avoids conflicts with + // dead optimistic fixup branches. } else { - EmitBlock(NormalEntry); - SimplifyCleanupEntry(*this, NormalEntry); + prebranchDest = createBasicBlock("forwarded-prebranch"); + EmitBlock(prebranchDest); } + + llvm::BasicBlock *normalEntry = Scope.getNormalBlock(); + assert(normalEntry && !normalEntry->use_empty()); + + ForwardPrebranchedFallthrough(FallthroughSource, + normalEntry, prebranchDest); } // If we don't need the cleanup at all, we're done. @@ -713,18 +712,19 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // I. Set up the fallthrough edge in. + CGBuilderTy::InsertPoint savedInactiveFallthroughIP; + // If there's a fallthrough, we need to store the cleanup // destination index. For fall-throughs this is always zero. if (HasFallthrough) { if (!HasPrebranchedFallthrough) Builder.CreateStore(Builder.getInt32(0), getNormalCleanupDestSlot()); - // Otherwise, clear the IP if we don't have fallthrough because - // the cleanup is inactive. We don't need to save it because - // it's still just FallthroughSource. + // Otherwise, save and clear the IP if we don't have fallthrough + // because the cleanup is inactive. } else if (FallthroughSource) { assert(!IsActive && "source without fallthrough for active cleanup"); - Builder.ClearInsertionPoint(); + savedInactiveFallthroughIP = Builder.saveAndClearIP(); } // II. Emit the entry block. This implicitly branches to it if @@ -837,25 +837,14 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // V. Set up the fallthrough edge out. - // Case 1: a fallthrough source exists but shouldn't branch to - // the cleanup because the cleanup is inactive. + // Case 1: a fallthrough source exists but doesn't branch to the + // cleanup because the cleanup is inactive. if (!HasFallthrough && FallthroughSource) { + // Prebranched fallthrough was forwarded earlier. + // Non-prebranched fallthrough doesn't need to be forwarded. + // Either way, all we need to do is restore the IP we cleared before. assert(!IsActive); - - // If we have a prebranched fallthrough, that needs to be - // forwarded to the right block. - if (HasPrebranchedFallthrough) { - llvm::BasicBlock *Next; - if (FallthroughIsBranchThrough) { - Next = BranchThroughDest; - assert(!FallthroughDest); - } else { - Next = FallthroughDest; - } - - ForwardPrebranchedFallthrough(FallthroughSource, NormalEntry, Next); - } - Builder.SetInsertPoint(FallthroughSource); + Builder.restoreIP(savedInactiveFallthroughIP); // Case 2: a fallthrough source exists and should branch to the // cleanup, but we're not supposed to branch through to the next |