Implement Direct ABIInfo semantics.

- No intended functionality change, this is essentially enabling
   direct passing of complex and aggregate values, which no ABI is
   using.

llvm-svn: 63863
This commit is contained in:
Daniel Dunbar 2009-02-05 11:13:54 +00:00
parent 2a3173287f
commit 5d3dbd64e1
1 changed files with 29 additions and 17 deletions

View File

@ -1219,10 +1219,18 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
case ABIArgInfo::Direct: { case ABIArgInfo::Direct: {
assert(AI != Fn->arg_end() && "Argument mismatch!"); assert(AI != Fn->arg_end() && "Argument mismatch!");
llvm::Value* V = AI; llvm::Value* V = AI;
if (!getContext().typesAreCompatible(Ty, Arg->getType())) { if (hasAggregateLLVMType(Ty)) {
// This must be a promotion, for something like // Create a temporary alloca to hold the argument; the rest of
// "void a(x) short x; {..." // codegen expects to access aggregates & complex values by
V = EmitScalarConversion(V, Ty, Arg->getType()); // reference.
V = CreateTempAlloca(ConvertType(Ty));
Builder.CreateStore(AI, V);
} else {
if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
// This must be a promotion, for something like
// "void a(x) short x; {..."
V = EmitScalarConversion(V, Ty, Arg->getType());
}
} }
EmitParmDecl(*Arg, V); EmitParmDecl(*Arg, V);
break; break;
@ -1288,10 +1296,8 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
const ABIArgInfo &RetAI = FI.getReturnInfo(); const ABIArgInfo &RetAI = FI.getReturnInfo();
switch (RetAI.getKind()) { switch (RetAI.getKind()) {
// FIXME: Implement correct [in]direct semantics.
case ABIArgInfo::Indirect: case ABIArgInfo::Indirect:
if (RetTy->isAnyComplexType()) { if (RetTy->isAnyComplexType()) {
// FIXME: Volatile
ComplexPairTy RT = LoadComplexFromAddr(ReturnValue, false); ComplexPairTy RT = LoadComplexFromAddr(ReturnValue, false);
StoreComplexToAddr(RT, CurFn->arg_begin(), false); StoreComplexToAddr(RT, CurFn->arg_begin(), false);
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) { } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
@ -1303,6 +1309,8 @@ void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
break; break;
case ABIArgInfo::Direct: case ABIArgInfo::Direct:
// The internal return value temp always will have
// pointer-to-return-type type.
RV = Builder.CreateLoad(ReturnValue); RV = Builder.CreateLoad(ReturnValue);
break; break;
@ -1368,11 +1376,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (RV.isScalar()) { if (RV.isScalar()) {
Args.push_back(RV.getScalarVal()); Args.push_back(RV.getScalarVal());
} else if (RV.isComplex()) { } else if (RV.isComplex()) {
// Make a temporary alloca to pass the argument. llvm::Value *Tmp = llvm::UndefValue::get(ConvertType(I->second));
Args.push_back(CreateTempAlloca(ConvertType(I->second))); Tmp = Builder.CreateInsertValue(Tmp, RV.getComplexVal().first, 0);
StoreComplexToAddr(RV.getComplexVal(), Args.back(), false); Tmp = Builder.CreateInsertValue(Tmp, RV.getComplexVal().second, 1);
Args.push_back(Tmp);
} else { } else {
Args.push_back(RV.getAggregateAddr()); Args.push_back(Builder.CreateLoad(RV.getAggregateAddr()));
} }
break; break;
@ -1415,7 +1424,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
CI->setName("call"); CI->setName("call");
switch (RetAI.getKind()) { switch (RetAI.getKind()) {
// FIXME: Implement correct [in]direct semantics.
case ABIArgInfo::Indirect: case ABIArgInfo::Indirect:
if (RetTy->isAnyComplexType()) if (RetTy->isAnyComplexType())
return RValue::getComplex(LoadComplexFromAddr(Args[0], false)); return RValue::getComplex(LoadComplexFromAddr(Args[0], false));
@ -1425,17 +1433,21 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
return RValue::get(Builder.CreateLoad(Args[0])); return RValue::get(Builder.CreateLoad(Args[0]));
case ABIArgInfo::Direct: case ABIArgInfo::Direct:
assert((!RetTy->isAnyComplexType() && if (RetTy->isAnyComplexType()) {
!CodeGenFunction::hasAggregateLLVMType(RetTy)) && llvm::Value *Real = Builder.CreateExtractValue(CI, 0);
"FIXME: Implement return for non-scalar direct types."); llvm::Value *Imag = Builder.CreateExtractValue(CI, 1);
return RValue::get(CI); return RValue::getComplex(std::make_pair(Real, Imag));
} else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "agg.tmp");
Builder.CreateStore(CI, V);
return RValue::getAggregate(V);
} else
return RValue::get(CI);
case ABIArgInfo::Ignore: case ABIArgInfo::Ignore:
// If we are ignoring an argument that had a result, make sure to // If we are ignoring an argument that had a result, make sure to
// construct the appropriate return value for our caller. // construct the appropriate return value for our caller.
return GetUndefRValue(RetTy); return GetUndefRValue(RetTy);
if (RetTy->isVoidType())
return RValue::get(0);
case ABIArgInfo::Coerce: { case ABIArgInfo::Coerce: {
// FIXME: Avoid the conversion through memory if possible. // FIXME: Avoid the conversion through memory if possible.