Fix #49: Static arrays that don't fit in a register should be passed using byval

This commit is contained in:
Dan Sanduleac 2012-06-05 02:42:34 +01:00
parent d24592b3e7
commit 2748cdaa88
5 changed files with 12 additions and 6 deletions

View file

@ -428,7 +428,8 @@ bool X86_64TargetABI::returnInArg(TypeFunction* tf) {
bool X86_64TargetABI::passByVal(Type* t) {
t = t->toBasetype();
if (linkage() == LINKd) {
return t->toBasetype()->ty == Tstruct;
// static arrays are also passed byval
return t->ty == Tstruct || t->ty == Tsarray;
} else {
// This implements the C calling convention for x86-64.
// It might not be correct for other calling conventions.
@ -598,6 +599,11 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
else
{
Logger::println("Putting static array in register");
// need to make sure type is not pointer
arg.ltype = DtoType(arg.type);
arg.byref = false;
// erase previous attributes
arg.attrs = 0;
}
arg.attrs |= llvm::Attribute::InReg;
--regcount;

View file

@ -108,7 +108,7 @@ struct X86TargetABI : TargetABI
bool passByVal(Type* t)
{
return t->toBasetype()->ty == Tstruct;
return t->toBasetype()->ty == Tstruct || t->toBasetype()->ty == Tsarray;
}
void rewriteFunctionType(TypeFunction* tf)

View file

@ -162,6 +162,7 @@ llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype,
else if (abi->passByVal(byref ? argtype->pointerTo() : argtype))
{
if (!byref) a |= llvm::Attribute::ByVal;
// set byref, because byval requires a pointed LLVM type
byref = true;
}
// sext/zext

View file

@ -13,9 +13,8 @@
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
IrFuncTyArg::IrFuncTyArg(Type* t, bool bref, unsigned a)
IrFuncTyArg::IrFuncTyArg(Type* t, bool bref, unsigned a) : type(t)
{
type = t;
ltype = t != Type::tvoid && bref ? DtoType(t->pointerTo()) : DtoType(t);
attrs = a;
byref = bref;

View file

@ -20,7 +20,7 @@ struct IrFuncTyArg : IrBase
{
/** This is the original D type as the frontend knows it
* May NOT be rewritten!!! */
Type* type;
Type* const type;
/// This is the final LLVM Type used for the parameter/return value type
llvm::Type* ltype;
@ -92,7 +92,7 @@ struct IrFuncTy : IrBase
{}
#if defined(_MSC_VER)
// Copy constructor and operator= seems to be requreid for MSC
// Copy constructor and operator= seems to be required for MSC
IrFuncTy(const IrFuncTy& rhs)
: ret(rhs.ret),