]> granicus.if.org Git - clang/commitdiff
More cleanup stack work.
authorAnders Carlsson <andersca@mac.com>
Sun, 8 Feb 2009 00:50:42 +0000 (00:50 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 8 Feb 2009 00:50:42 +0000 (00:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64059 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h

index 0e0140c9ad77284760f68b2bd38abc4ceacbd237..e5dc97c3d0b209773928cc45684cb4c6081159a6 100644 (file)
@@ -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);
+}
index 3dbc2c99e7166a6d94ea019fd8433a91e6ba77f1..b37cf7b919d76fd0495cce6159c925c71412270a 100644 (file)
@@ -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