diff options
author | John McCall <rjmccall@apple.com> | 2010-07-21 07:11:21 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-07-21 07:11:21 +0000 |
commit | 7495f22934d577c71b4b5bae82142ad54ccb1d59 (patch) | |
tree | 8077797e0eb07b68f4ae0bfd5e04f3e04fa5e8b0 /lib/CodeGen/CodeGenFunction.cpp | |
parent | 6962f8d156735172146ae812732f4c4ddc13e91b (diff) |
Rip out EHCleanupScope.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108999 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 187 |
1 files changed, 4 insertions, 183 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index baa8c6d58b..af53f6d114 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -671,35 +671,6 @@ void CodeGenFunction::PopCleanupBlocks(EHScopeStack::stable_iterator Old) { PopCleanupBlock(); } -/// Destroys a cleanup if it was unused. -static void DestroyCleanup(CodeGenFunction &CGF, - llvm::BasicBlock *Entry, - llvm::BasicBlock *Exit) { - assert(Entry->use_empty() && "destroying cleanup with uses!"); - assert(Exit->getTerminator() == 0 && - "exit has terminator but entry has no predecessors!"); - - // This doesn't always remove the entire cleanup, but it's much - // safer as long as we don't know what blocks belong to the cleanup. - // A *much* better approach if we care about this inefficiency would - // be to lazily emit the cleanup. - - // If the exit block is distinct from the entry, give it a branch to - // an unreachable destination. This preserves the well-formedness - // of the IR. - if (Entry != Exit) - llvm::BranchInst::Create(CGF.getUnreachableBlock(), Exit); - - assert(!Entry->getParent() && "cleanup entry already positioned?"); - // We can't just delete the entry; we have to kill any references to - // its instructions in other blocks. - for (llvm::BasicBlock::iterator I = Entry->begin(), E = Entry->end(); - I != E; ++I) - if (!I->use_empty()) - I->replaceAllUsesWith(llvm::UndefValue::get(I->getType())); - delete Entry; -} - /// Creates a switch instruction to thread branches out of the given /// block (which is the exit block of a cleanup). static void CreateCleanupSwitch(CodeGenFunction &CGF, @@ -984,148 +955,8 @@ static void PopLazyCleanupBlock(CodeGenFunction &CGF) { /// any branch fixups on the cleanup. void CodeGenFunction::PopCleanupBlock() { assert(!EHStack.empty() && "cleanup stack is empty!"); - if (isa<EHLazyCleanupScope>(*EHStack.begin())) - return PopLazyCleanupBlock(*this); - - assert(isa<EHCleanupScope>(*EHStack.begin()) && "top not a cleanup!"); - EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.begin()); - assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups()); - - // Handle the EH cleanup if (1) there is one and (2) it's different - // from the normal cleanup. - if (Scope.isEHCleanup() && - Scope.getEHEntry() != Scope.getNormalEntry()) { - llvm::BasicBlock *EHEntry = Scope.getEHEntry(); - llvm::BasicBlock *EHExit = Scope.getEHExit(); - - if (EHEntry->use_empty()) { - DestroyCleanup(*this, EHEntry, EHExit); - } else { - // TODO: this isn't really the ideal location to put this EH - // cleanup, but lazy emission is a better solution than trying - // to pick a better spot. - CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); - EmitBlock(EHEntry); - Builder.restoreIP(SavedIP); - - SimplifyCleanupEdges(*this, EHEntry, EHExit); - } - } - - // If we only have an EH cleanup, we don't really need to do much - // here. Branch fixups just naturally drop down to the enclosing - // cleanup scope. - if (!Scope.isNormalCleanup()) { - EHStack.popCleanup(); - assert(EHStack.getNumBranchFixups() == 0 || EHStack.hasNormalCleanups()); - return; - } - - // Check whether the scope has any fixups that need to be threaded. - unsigned FixupDepth = Scope.getFixupDepth(); - bool HasFixups = EHStack.getNumBranchFixups() != FixupDepth; - - // Grab the entry and exit blocks. - llvm::BasicBlock *Entry = Scope.getNormalEntry(); - llvm::BasicBlock *Exit = Scope.getNormalExit(); - - // Check whether anything's been threaded through the cleanup already. - assert((Exit->getTerminator() == 0) == Entry->use_empty() && - "cleanup entry/exit mismatch"); - bool HasExistingBranches = !Entry->use_empty(); - - // Check whether we need to emit a "fallthrough" branch through the - // cleanup for the current insertion point. - llvm::BasicBlock *FallThrough = Builder.GetInsertBlock(); - if (FallThrough && FallThrough->getTerminator()) - FallThrough = 0; - - // If *nothing* is using the cleanup, kill it. - if (!FallThrough && !HasFixups && !HasExistingBranches) { - EHStack.popCleanup(); - DestroyCleanup(*this, Entry, Exit); - return; - } - - // Otherwise, add the block to the function. - EmitBlock(Entry); - - if (FallThrough) - Builder.SetInsertPoint(Exit); - else - Builder.ClearInsertionPoint(); - - // Fast case: if we don't have to add any fixups, and either - // we don't have a fallthrough or the cleanup wasn't previously - // used, then the setup above is sufficient. - if (!HasFixups) { - if (!FallThrough) { - assert(HasExistingBranches && "no reason for cleanup but didn't kill before"); - EHStack.popCleanup(); - SimplifyCleanupEdges(*this, Entry, Exit); - return; - } else if (!HasExistingBranches) { - assert(FallThrough && "no reason for cleanup but didn't kill before"); - // We can't simplify the exit edge in this case because we're - // already inserting at the end of the exit block. - EHStack.popCleanup(); - SimplifyCleanupEntry(*this, Entry); - return; - } - } - - // Otherwise we're going to have to thread things through the cleanup. - llvm::SmallVector<BranchFixup*, 8> Fixups; - - // Synthesize a fixup for the current insertion point. - BranchFixup Cur; - if (FallThrough) { - Cur.Destination = createBasicBlock("cleanup.cont"); - Cur.LatestBranch = FallThrough->getTerminator(); - Cur.LatestBranchIndex = 0; - Cur.Origin = Cur.LatestBranch; - - // Restore fixup invariant. EmitBlock added a branch to the cleanup - // which we need to redirect to the destination. - cast<llvm::BranchInst>(Cur.LatestBranch)->setSuccessor(0, Cur.Destination); - - Fixups.push_back(&Cur); - } else { - Cur.Destination = 0; - } - - // Collect any "real" fixups we need to thread. - for (unsigned I = FixupDepth, E = EHStack.getNumBranchFixups(); - I != E; ++I) - if (EHStack.getBranchFixup(I).Destination) - Fixups.push_back(&EHStack.getBranchFixup(I)); - - assert(!Fixups.empty() && "no fixups, invariants broken!"); - - // If there's only a single fixup to thread through, do so with - // unconditional branches. This only happens if there's a single - // branch and no fallthrough. - if (Fixups.size() == 1 && !HasExistingBranches) { - Fixups[0]->LatestBranch->setSuccessor(Fixups[0]->LatestBranchIndex, Entry); - llvm::BranchInst *Br = - llvm::BranchInst::Create(Fixups[0]->Destination, Exit); - Fixups[0]->LatestBranch = Br; - Fixups[0]->LatestBranchIndex = 0; - - // Otherwise, force a switch statement and thread everything through - // the switch. - } else { - CreateCleanupSwitch(*this, Exit); - for (unsigned I = 0, E = Fixups.size(); I != E; ++I) - ThreadFixupThroughCleanup(*this, *Fixups[I], Entry, Exit); - } - - // Emit the fallthrough destination block if necessary. - if (Cur.Destination) - EmitBlock(Cur.Destination); - - // We're finally done with the cleanup. - EHStack.popCleanup(); + assert(isa<EHLazyCleanupScope>(*EHStack.begin())); + return PopLazyCleanupBlock(*this); } void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { @@ -1159,12 +990,7 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.find(Dest.ScopeDepth); I != E; ++I) { - if (isa<EHCleanupScope>(*I)) { - EHCleanupScope &Scope = cast<EHCleanupScope>(*I); - if (Scope.isNormalCleanup()) - ThreadFixupThroughCleanup(*this, Fixup, Scope.getNormalEntry(), - Scope.getNormalExit()); - } else if (isa<EHLazyCleanupScope>(*I)) { + if (isa<EHLazyCleanupScope>(*I)) { EHLazyCleanupScope &Scope = cast<EHLazyCleanupScope>(*I); if (Scope.isNormalCleanup()) { llvm::BasicBlock *Block = Scope.getNormalBlock(); @@ -1208,12 +1034,7 @@ void CodeGenFunction::EmitBranchThroughEHCleanup(JumpDest Dest) { for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.find(Dest.ScopeDepth); I != E; ++I) { - if (isa<EHCleanupScope>(*I)) { - EHCleanupScope &Scope = cast<EHCleanupScope>(*I); - if (Scope.isEHCleanup()) - ThreadFixupThroughCleanup(*this, Fixup, Scope.getEHEntry(), - Scope.getEHExit()); - } else if (isa<EHLazyCleanupScope>(*I)) { + if (isa<EHLazyCleanupScope>(*I)) { EHLazyCleanupScope &Scope = cast<EHLazyCleanupScope>(*I); if (Scope.isEHCleanup()) { llvm::BasicBlock *Block = Scope.getEHBlock(); |