From: Anders Carlsson Date: Sun, 8 Feb 2009 00:50:42 +0000 (+0000) Subject: More cleanup stack work. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=87eaf17cc88516277e4389dfa15df93ecfdce559;p=clang More cleanup stack work. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64059 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 0e0140c9ad..e5dc97c3d0 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -560,3 +560,44 @@ void CodeGenFunction::EmitCleanupBlock() } } +void CodeGenFunction::AddBranchFixup(llvm::BranchInst *BI) +{ + assert(!CleanupEntries.empty() && + "Trying to add branch fixup without cleanup block!"); + + // FIXME: We could be more clever here and check if there's already a + // branch fixup for this destination and recycle it. + CleanupEntries.back().BranchFixups.push_back(BI); +} + +void CodeGenFunction::EmitBranchThroughCleanup(llvm::BasicBlock *Dest) +{ + llvm::BranchInst* BI = Builder.CreateBr(Dest); + + // The stack is empty, no need to do any cleanup. + if (CleanupEntries.empty()) + return; + + if (!Dest->getParent()) { + // We are trying to branch to a block that hasn't been inserted yet. + AddBranchFixup(BI); + return; + } + + BlockScopeMap::iterator I = BlockScopes.find(Dest); + if (I == BlockScopes.end()) { + // We are trying to jump to a block that is outside of any cleanup scope. + AddBranchFixup(BI); + return; + } + + assert(I->second < CleanupEntries.size() && + "Trying to branch into cleanup region"); + + if (I->second == CleanupEntries.size() - 1) { + // We have a branch to a block in the same scope. + return; + } + + AddBranchFixup(BI); +} diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 3dbc2c99e7..b37cf7b919 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -155,6 +155,13 @@ public: /// blocks that have been added. void EmitCleanupBlocks(size_t OldCleanupStackSize); + /// EmitBranchThroughCleanup - Emit a branch from the current insert block + /// through the cleanup handling code (if any) and then on to \arg Dest. + /// + /// FIXME: Maybe this should really be in EmitBranch? Don't we always want + /// this behavior for branches? + void EmitBranchThroughCleanup(llvm::BasicBlock *Dest); + private: /// LabelIDs - Track arbitrary ids assigned to labels for use in /// implementing the GCC address-of-label extension and indirect @@ -780,6 +787,10 @@ private: /// EmitCleanupBlock - emits a single cleanup block. void EmitCleanupBlock(); + /// AddBranchFixup - adds a branch instruction to the list of fixups for the + /// current cleanup scope. + void AddBranchFixup(llvm::BranchInst *BI); + }; } // end namespace CodeGen } // end namespace clang