[cfe-commits] r92142 - in /cfe/trunk: lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CGCXX.cpp lib/CodeGen/CGCall.cpp lib/CodeGen/CGCall.h lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprAgg.cpp lib/CodeGen/CodeGenFunction.h test/CodeGenObjC/x86-64-struct-return-gc.m test/CodeGenObjC/x86_64-struct-return-gc.m
Anders Carlsson
andersca at mac.com
Thu Dec 24 12:40:37 PST 2009
Author: andersca
Date: Thu Dec 24 14:40:36 2009
New Revision: 92142
URL: http://llvm.org/viewvc/llvm-project?rev=92142&view=rev
Log:
Fill in the return value slot in CGExprAgg::VisitCallExpr. This takes us halfway towards fixing PR5824.
Added:
cfe/trunk/test/CodeGenObjC/x86_64-struct-return-gc.m
- copied unchanged from r92140, cfe/trunk/test/CodeGenObjC/x86-64-struct-return-gc.m
Removed:
cfe/trunk/test/CodeGenObjC/x86-64-struct-return-gc.m
Modified:
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/lib/CodeGen/CGCall.h
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprAgg.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=92142&r1=92141&r2=92142&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Thu Dec 24 14:40:36 2009
@@ -581,6 +581,7 @@
getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
return EmitCall(E->getCallee()->getType(),
CGM.getBuiltinLibFunction(FD, BuiltinID),
+ ReturnValueSlot(),
E->arg_begin(), E->arg_end());
// See if we have a target specific intrinsic.
Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=92142&r1=92141&r2=92142&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Thu Dec 24 14:40:36 2009
@@ -89,7 +89,7 @@
// The method is static, emit it as we would a regular call.
llvm::Value *Callee = CGM.GetAddrOfFunction(MD);
return EmitCall(getContext().getPointerType(MD->getType()), Callee,
- CE->arg_begin(), CE->arg_end());
+ ReturnValueSlot(), CE->arg_begin(), CE->arg_end());
}
const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=92142&r1=92141&r2=92142&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Dec 24 14:40:36 2009
@@ -346,6 +346,7 @@
/// destination type; the upper bits of the src will be lost.
static void CreateCoercedStore(llvm::Value *Src,
llvm::Value *DstPtr,
+ bool DstIsVolatile,
CodeGenFunction &CGF) {
const llvm::Type *SrcTy = Src->getType();
const llvm::Type *DstTy =
@@ -359,7 +360,7 @@
llvm::Value *Casted =
CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy));
// FIXME: Use better alignment / avoid requiring aligned store.
- CGF.Builder.CreateStore(Src, Casted)->setAlignment(1);
+ CGF.Builder.CreateStore(Src, Casted, DstIsVolatile)->setAlignment(1);
} else {
// Otherwise do coercion through memory. This is stupid, but
// simple.
@@ -377,7 +378,7 @@
llvm::LoadInst *Load = CGF.Builder.CreateLoad(Casted);
// FIXME: Use better alignment / avoid requiring aligned load.
Load->setAlignment(1);
- CGF.Builder.CreateStore(Load, DstPtr);
+ CGF.Builder.CreateStore(Load, DstPtr, DstIsVolatile);
}
}
@@ -732,7 +733,7 @@
// result in a new alloca anyway, so we could just store into that
// directly if we broke the abstraction down more.
llvm::Value *V = CreateTempAlloca(ConvertTypeForMem(Ty), "coerce");
- CreateCoercedStore(AI, V, *this);
+ CreateCoercedStore(AI, V, /*DestIsVolatile=*/false, *this);
// Match to what EmitParmDecl is expecting for this type.
if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
V = EmitLoadOfScalar(V, false, Ty);
@@ -822,9 +823,13 @@
// If the call returns a temporary with struct return, create a temporary
- // alloca to hold the result.
- if (CGM.ReturnTypeUsesSret(CallInfo))
- Args.push_back(CreateTempAlloca(ConvertTypeForMem(RetTy)));
+ // alloca to hold the result, unless one is given to us.
+ if (CGM.ReturnTypeUsesSret(CallInfo)) {
+ llvm::Value *Value = ReturnValue.getValue();
+ if (!Value)
+ Value = CreateTempAlloca(ConvertTypeForMem(RetTy));
+ Args.push_back(Value);
+ }
assert(CallInfo.arg_size() == CallArgs.size() &&
"Mismatch between function signature & arguments.");
@@ -973,9 +978,15 @@
return RValue::getComplex(std::make_pair(Real, Imag));
}
if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
- llvm::Value *V = CreateTempAlloca(ConvertTypeForMem(RetTy), "agg.tmp");
- Builder.CreateStore(CI, V);
- return RValue::getAggregate(V);
+ llvm::Value *DestPtr = ReturnValue.getValue();
+ bool DestIsVolatile = ReturnValue.isVolatile();
+
+ if (!DestPtr) {
+ DestPtr = CreateTempAlloca(ConvertTypeForMem(RetTy), "agg.tmp");
+ DestIsVolatile = false;
+ }
+ Builder.CreateStore(CI, DestPtr, DestIsVolatile);
+ return RValue::getAggregate(DestPtr);
}
return RValue::get(CI);
@@ -985,14 +996,20 @@
return GetUndefRValue(RetTy);
case ABIArgInfo::Coerce: {
- // FIXME: Avoid the conversion through memory if possible.
- llvm::Value *V = CreateTempAlloca(ConvertTypeForMem(RetTy), "coerce");
- CreateCoercedStore(CI, V, *this);
+ llvm::Value *DestPtr = ReturnValue.getValue();
+ bool DestIsVolatile = ReturnValue.isVolatile();
+
+ if (!DestPtr) {
+ DestPtr = CreateTempAlloca(ConvertTypeForMem(RetTy), "coerce");
+ DestIsVolatile = false;
+ }
+
+ CreateCoercedStore(CI, DestPtr, DestIsVolatile, *this);
if (RetTy->isAnyComplexType())
- return RValue::getComplex(LoadComplexFromAddr(V, false));
+ return RValue::getComplex(LoadComplexFromAddr(DestPtr, false));
if (CodeGenFunction::hasAggregateLLVMType(RetTy))
- return RValue::getAggregate(V);
- return RValue::get(EmitLoadOfScalar(V, false, RetTy));
+ return RValue::getAggregate(DestPtr);
+ return RValue::get(EmitLoadOfScalar(DestPtr, false, RetTy));
}
case ABIArgInfo::Expand:
Modified: cfe/trunk/lib/CodeGen/CGCall.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.h?rev=92142&r1=92141&r2=92142&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.h (original)
+++ cfe/trunk/lib/CodeGen/CGCall.h Thu Dec 24 14:40:36 2009
@@ -125,6 +125,8 @@
}
};
+ /// ReturnValueSlot - Contains the address where the return value of a
+ /// function can be stored, and whether the address is volatile or not.
class ReturnValueSlot {
llvm::PointerIntPair<llvm::Value *, 1, bool> Value;
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=92142&r1=92141&r2=92142&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Dec 24 14:40:36 2009
@@ -1518,7 +1518,8 @@
//===--------------------------------------------------------------------===//
-RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
+RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
+ ReturnValueSlot ReturnValue) {
// Builtins never have block type.
if (E->getCallee()->getType()->isBlockPointerType())
return EmitBlockCallExpr(E);
@@ -1551,7 +1552,7 @@
}
llvm::Value *Callee = EmitScalarExpr(E->getCallee());
- return EmitCall(E->getCallee()->getType(), Callee,
+ return EmitCall(E->getCallee()->getType(), Callee, ReturnValue,
E->arg_begin(), E->arg_end(), TargetDecl);
}
@@ -1713,6 +1714,7 @@
}
RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
+ ReturnValueSlot ReturnValue,
CallExpr::const_arg_iterator ArgBeg,
CallExpr::const_arg_iterator ArgEnd,
const Decl *TargetDecl) {
@@ -1737,7 +1739,7 @@
CallingConvention = F->getCallingConv();
return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args,
CallingConvention),
- Callee, ReturnValueSlot(), Args, TargetDecl);
+ Callee, ReturnValue, Args, TargetDecl);
}
LValue CodeGenFunction::
Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=92142&r1=92141&r2=92142&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Dec 24 14:40:36 2009
@@ -272,6 +272,13 @@
return;
}
+ // If the struct doesn't require GC, we can just pass the destination
+ // directly to EmitCall.
+ if (!RequiresGCollection) {
+ CGF.EmitCallExpr(E, ReturnValueSlot(DestPtr, VolatileDest));
+ return;
+ }
+
RValue RV = CGF.EmitCallExpr(E);
EmitFinalDestCopy(E, RV);
}
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=92142&r1=92141&r2=92142&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Dec 24 14:40:36 2009
@@ -1041,10 +1041,12 @@
const Decl *TargetDecl = 0);
RValue EmitCall(QualType FnType, llvm::Value *Callee,
+ ReturnValueSlot ReturnValue,
CallExpr::const_arg_iterator ArgBeg,
CallExpr::const_arg_iterator ArgEnd,
const Decl *TargetDecl = 0);
- RValue EmitCallExpr(const CallExpr *E);
+ RValue EmitCallExpr(const CallExpr *E,
+ ReturnValueSlot ReturnValue = ReturnValueSlot());
llvm::Value *BuildVirtualCall(const CXXMethodDecl *MD, llvm::Value *This,
const llvm::Type *Ty);
Removed: cfe/trunk/test/CodeGenObjC/x86-64-struct-return-gc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/x86-64-struct-return-gc.m?rev=92141&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/x86-64-struct-return-gc.m (original)
+++ cfe/trunk/test/CodeGenObjC/x86-64-struct-return-gc.m (removed)
@@ -1,31 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-gc -emit-llvm -o - %s | FileCheck %s
-struct Coerce {
- id a;
-};
-
-struct Coerce coerce_func(void);
-
-// CHECK: define void @Coerce_test()
-void Coerce_test(void) {
- struct Coerce c;
-
- // CHECK: call i64 @coerce_func
- // CHECK: call i8* @objc_memmove_collectable(
- c = coerce_func();
-}
-
-struct Indirect {
- id a;
- int b[10];
-};
-
-struct Indirect indirect_func(void);
-
-// CHECK: define void @Indirect_test()
-void Indirect_test(void) {
- struct Indirect i;
-
- // CHECK: call void @indirect_func(%struct.Indirect* noalias sret
- // CHECK: call i8* @objc_memmove_collectable(
- i = indirect_func();
-}
More information about the cfe-commits
mailing list