summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-02-08 00:50:42 +0000
committerAnders Carlsson <andersca@mac.com>2009-02-08 00:50:42 +0000
commit7d70fd27a4bdd37366920b5da1d2f87984563e92 (patch)
tree560e162a6892132f76ca9118055c978c6eb247bd /clang/lib/CodeGen
parent9fc4c68380fb2e890e4e64894c1e3b339864f45d (diff)
downloadbcm5719-llvm-7d70fd27a4bdd37366920b5da1d2f87984563e92.tar.gz
bcm5719-llvm-7d70fd27a4bdd37366920b5da1d2f87984563e92.zip
More cleanup stack work.
llvm-svn: 64059
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp41
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h11
2 files changed, 52 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 0e0140c9ad7..e5dc97c3d0b 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/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/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 3dbc2c99e71..b37cf7b919d 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/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
OpenPOWER on IntegriCloud