[cfe-commits] r63068 - in /cfe/trunk/lib/CodeGen: CodeGenFunction.cpp CodeGenFunction.h

Daniel Dunbar daniel at zuster.org
Mon Jan 26 15:27:53 PST 2009


Author: ddunbar
Date: Mon Jan 26 17:27:52 2009
New Revision: 63068

URL: http://llvm.org/viewvc/llvm-project?rev=63068&view=rev
Log:
Pull EmitReturnBlock out of FinishFunction and catch unified return
case correctly.

Modified:
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=63068&r1=63067&r2=63068&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Jan 26 17:27:52 2009
@@ -70,6 +70,45 @@
     !T->isBlockPointerType();
 }
 
+void CodeGenFunction::EmitReturnBlock() {
+  // For cleanliness, we try to avoid emitting the return block for
+  // simple cases.
+  llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
+
+  if (CurBB) {
+    assert(!CurBB->getTerminator() && "Unexpected terminated block.");
+
+    // We have a valid insert point, reuse it if there are no explicit
+    // jumps to the return block.
+    if (ReturnBlock->use_empty())
+      delete ReturnBlock;
+    else
+      EmitBlock(ReturnBlock);
+    return;
+  }
+
+  // Otherwise, if the return block is the target of a single direct
+  // branch then we can just put the code in that block instead. This
+  // cleans up functions which started with a unified return block.
+  if (ReturnBlock->hasOneUse()) {
+    llvm::BranchInst *BI = 
+      dyn_cast<llvm::BranchInst>(*ReturnBlock->use_begin());
+    if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock) {
+      // Reset insertion point and delete the branch.
+      Builder.SetInsertPoint(BI->getParent());
+      BI->eraseFromParent();
+      delete ReturnBlock;
+      return;
+    }
+  }
+
+  // FIXME: We are at an unreachable point, there is no reason to emit
+  // the block unless it has uses. However, we still need a place to
+  // put the debug region.end for now.
+
+  EmitBlock(ReturnBlock);
+}
+
 void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
   // Finish emission of indirect switches.
   EmitIndirectSwitches();
@@ -77,13 +116,8 @@
   assert(BreakContinueStack.empty() &&
          "mismatched push/pop in break/continue stack!");
 
-  // Emit function epilog (to return). For cleanliness, skip emission
-  // if we know it is safe (when it is unused and the current block is
-  // unterminated).
-  if (!ReturnBlock->use_empty() ||
-      !Builder.GetInsertBlock() ||
-      Builder.GetInsertBlock()->getTerminator())
-    EmitBlock(ReturnBlock);
+  // Emit function epilog (to return). 
+  EmitReturnBlock();
 
   // Emit debug descriptor for function end.
   if (CGDebugInfo *DI = CGM.getDebugInfo()) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=63068&r1=63067&r2=63068&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Jan 26 17:27:52 2009
@@ -206,6 +206,10 @@
                      const FunctionArgList &Args,
                      SourceLocation StartLoc);
 
+  /// EmitReturnBlock - Emit the unified return block, trying to avoid
+  /// its emission when possible.
+  void EmitReturnBlock();
+
   /// FinishFunction - Complete IR generation of the current
   /// function. It is legal to call this function even if there is no
   /// current insertion point.





More information about the cfe-commits mailing list