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) { bool X86_64TargetABI::passByVal(Type* t) {
t = t->toBasetype(); t = t->toBasetype();
if (linkage() == LINKd) { if (linkage() == LINKd) {
return t->toBasetype()->ty == Tstruct; // static arrays are also passed byval
return t->ty == Tstruct || t->ty == Tsarray;
} else { } else {
// This implements the C calling convention for x86-64. // This implements the C calling convention for x86-64.
// It might not be correct for other calling conventions. // It might not be correct for other calling conventions.
@ -598,6 +599,11 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
else else
{ {
Logger::println("Putting static array in register"); 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; arg.attrs |= llvm::Attribute::InReg;
--regcount; --regcount;

View file

@ -108,7 +108,7 @@ struct X86TargetABI : TargetABI
bool passByVal(Type* t) bool passByVal(Type* t)
{ {
return t->toBasetype()->ty == Tstruct; return t->toBasetype()->ty == Tstruct || t->toBasetype()->ty == Tsarray;
} }
void rewriteFunctionType(TypeFunction* tf) 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)) else if (abi->passByVal(byref ? argtype->pointerTo() : argtype))
{ {
if (!byref) a |= llvm::Attribute::ByVal; if (!byref) a |= llvm::Attribute::ByVal;
// set byref, because byval requires a pointed LLVM type
byref = true; byref = true;
} }
// sext/zext // 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); ltype = t != Type::tvoid && bref ? DtoType(t->pointerTo()) : DtoType(t);
attrs = a; attrs = a;
byref = bref; byref = bref;

View file

@ -20,7 +20,7 @@ struct IrFuncTyArg : IrBase
{ {
/** This is the original D type as the frontend knows it /** This is the original D type as the frontend knows it
* May NOT be rewritten!!! */ * May NOT be rewritten!!! */
Type* type; Type* const type;
/// This is the final LLVM Type used for the parameter/return value type /// This is the final LLVM Type used for the parameter/return value type
llvm::Type* ltype; llvm::Type* ltype;
@ -92,7 +92,7 @@ struct IrFuncTy : IrBase
{} {}
#if defined(_MSC_VER) #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) IrFuncTy(const IrFuncTy& rhs)
: ret(rhs.ret), : ret(rhs.ret),