mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +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) {
|
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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue