mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 08:30:47 +03:00
Fix #49: Static arrays that don't fit in a register should be passed using byval
This commit is contained in:
parent
d24592b3e7
commit
2748cdaa88
5 changed files with 12 additions and 6 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue