[cfe-commits] [PATCH] Emit returned aggregates directly into sret slot when applicable

Eli Friedman eli.friedman at gmail.com
Wed Dec 2 22:59:05 PST 2009


Patch attached.  This seems blindingly obvious, but since it hasn't
been done yet, I have a feeling I'm missing something.

-Eli
-------------- next part --------------
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp	(revision 90412)
+++ lib/CodeGen/CodeGenFunction.cpp	(working copy)
@@ -179,9 +179,6 @@
     AllocaInsertPt->setName("allocapt");
 
   ReturnBlock = createBasicBlock("return");
-  ReturnValue = 0;
-  if (!RetTy->isVoidType())
-    ReturnValue = CreateTempAlloca(ConvertType(RetTy), "retval");
 
   Builder.SetInsertPoint(EntryBB);
 
@@ -204,6 +201,19 @@
 
   // FIXME: Leaked.
   CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args);
+
+  if (RetTy->isVoidType()) {
+    // Void type; nothing to return.
+    ReturnValue = 0;
+  } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+             hasAggregateLLVMType(CurFnInfo->getReturnType())) {
+    // Indirect aggregate return; emit returned value directly into sret slot.
+    // This reduces code size, and is also affects correctness in C++.
+    ReturnValue = CurFn->arg_begin();
+  } else {
+    ReturnValue = CreateTempAlloca(ConvertType(RetTy), "retval");
+  }
+
   EmitFunctionProlog(*CurFnInfo, CurFn, Args);
 
   // If any of the arguments have a variably modified type, make sure to
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp	(revision 90412)
+++ lib/CodeGen/CGCall.cpp	(working copy)
@@ -764,7 +764,7 @@
         ComplexPairTy RT = LoadComplexFromAddr(ReturnValue, false);
         StoreComplexToAddr(RT, CurFn->arg_begin(), false);
       } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
-        EmitAggregateCopy(CurFn->arg_begin(), ReturnValue, RetTy);
+        // Do nothing; aggregrates get evaluated directly into the destination.
       } else {
         EmitStoreOfScalar(Builder.CreateLoad(ReturnValue), CurFn->arg_begin(),
                           false, RetTy);
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h	(revision 90412)
+++ lib/CodeGen/CodeGenFunction.h	(working copy)
@@ -92,7 +92,7 @@
   llvm::BasicBlock *ReturnBlock;
   /// ReturnValue - The temporary alloca to hold the return value. This is null
   /// iff the function has no return value.
-  llvm::Instruction *ReturnValue;
+  llvm::Value *ReturnValue;
 
   /// AllocaInsertPoint - This is an instruction in the entry block before which
   /// we prefer to insert allocas.


More information about the cfe-commits mailing list