mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 10:57:35 +03:00
D2: pass static arrays into functions by value
This commit is contained in:
parent
069f0a6262
commit
805fb5cfc1
5 changed files with 22 additions and 27 deletions
|
@ -1193,10 +1193,9 @@ LLValue* DtoArrayLen(DValue* v)
|
||||||
else if (t->ty == Tsarray) {
|
else if (t->ty == Tsarray) {
|
||||||
assert(!v->isSlice());
|
assert(!v->isSlice());
|
||||||
assert(!v->isNull());
|
assert(!v->isNull());
|
||||||
LLValue* rv = v->getRVal();
|
assert(v->type->toBasetype()->ty == Tsarray);
|
||||||
const LLArrayType* t = isaArray(rv->getType()->getContainedType(0));
|
TypeSArray *sarray = (TypeSArray*)v->type->toBasetype();
|
||||||
assert(t);
|
return DtoConstSize_t(sarray->dim->toUInteger());
|
||||||
return DtoConstSize_t(t->getNumElements());
|
|
||||||
}
|
}
|
||||||
assert(0 && "unsupported array for len");
|
assert(0 && "unsupported array for len");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1278,7 +1277,8 @@ DValue* DtoCastArray(Loc& loc, DValue* u, Type* to)
|
||||||
fatal();
|
fatal();
|
||||||
}
|
}
|
||||||
|
|
||||||
rval2 = LLConstantInt::get(DtoSize_t(), arrty->getNumElements(), false);
|
uinteger_t len = ((TypeSArray*)fromtype)->dim->toUInteger();
|
||||||
|
rval2 = LLConstantInt::get(DtoSize_t(), len, false);
|
||||||
if (fromtype->nextOf()->size() != totype->nextOf()->size())
|
if (fromtype->nextOf()->size() != totype->nextOf()->size())
|
||||||
rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
|
rval2 = DtoArrayCastLength(rval2, ety, ptrty->getContainedType(0));
|
||||||
rval = DtoBitCast(uval, ptrty);
|
rval = DtoBitCast(uval, ptrty);
|
||||||
|
|
|
@ -144,8 +144,11 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
|
||||||
// get argument
|
// get argument
|
||||||
Parameter* arg = Parameter::getNth(f->parameters, i);
|
Parameter* arg = Parameter::getNth(f->parameters, i);
|
||||||
|
|
||||||
// reference semantics? ref, out and static arrays are
|
// reference semantics? ref, out and d1 static arrays are
|
||||||
bool byref = (arg->storageClass & (STCref|STCout)) || (arg->type->toBasetype()->ty == Tsarray);
|
bool byref = arg->storageClass & (STCref|STCout);
|
||||||
|
#if !SARRAYVALUE
|
||||||
|
byref = byref || (arg->type->toBasetype()->ty == Tsarray);
|
||||||
|
#endif
|
||||||
|
|
||||||
Type* argtype = arg->type;
|
Type* argtype = arg->type;
|
||||||
unsigned a = 0;
|
unsigned a = 0;
|
||||||
|
@ -157,9 +160,6 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
|
||||||
TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd);
|
TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd);
|
||||||
TypeDelegate *ltd = new TypeDelegate(ltf);
|
TypeDelegate *ltd = new TypeDelegate(ltf);
|
||||||
argtype = ltd;
|
argtype = ltd;
|
||||||
#if DMDV2
|
|
||||||
byref = byref && arg->type->toBasetype()->ty != Tsarray;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
// byval
|
// byval
|
||||||
else if (abi->passByVal(byref ? argtype->pointerTo() : argtype))
|
else if (abi->passByVal(byref ? argtype->pointerTo() : argtype))
|
||||||
|
@ -745,12 +745,7 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||||
|
|
||||||
bool refout = vd->storage_class & (STCref | STCout);
|
bool refout = vd->storage_class & (STCref | STCout);
|
||||||
bool lazy = vd->storage_class & STClazy;
|
bool lazy = vd->storage_class & STClazy;
|
||||||
#if DMDV2
|
|
||||||
bool isStaticArray = vd->type->toBasetype()->ty == Tsarray;
|
|
||||||
if (!refout && (!f->fty.args[i]->byref || lazy || isStaticArray))
|
|
||||||
#else
|
|
||||||
if (!refout && (!f->fty.args[i]->byref || lazy))
|
if (!refout && (!f->fty.args[i]->byref || lazy))
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
// alloca a stack slot for this first class value arg
|
// alloca a stack slot for this first class value arg
|
||||||
const LLType* argt;
|
const LLType* argt;
|
||||||
|
@ -760,12 +755,6 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
||||||
argt = DtoType(vd->type);
|
argt = DtoType(vd->type);
|
||||||
LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars());
|
LLValue* mem = DtoRawAlloca(argt, 0, vd->ident->toChars());
|
||||||
|
|
||||||
#if DMDV2
|
|
||||||
// if it is a static array, load from it, because static arrays
|
|
||||||
// are always passed by reference
|
|
||||||
if (isStaticArray && !lazy)
|
|
||||||
irloc->value = DtoLoad(irloc->value);
|
|
||||||
#endif
|
|
||||||
// let the abi transform the argument back first
|
// let the abi transform the argument back first
|
||||||
DImValue arg_dval(vd->type, irloc->value);
|
DImValue arg_dval(vd->type, irloc->value);
|
||||||
f->fty.getParam(vd->type, i, &arg_dval, mem);
|
f->fty.getParam(vd->type, i, &arg_dval, mem);
|
||||||
|
|
|
@ -144,7 +144,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||||
// If the function returns a struct or a static array, and the return
|
// If the function returns a struct or a static array, and the return
|
||||||
// value is a pointer to a struct or a static array, load from it
|
// value is a pointer to a struct or a static array, load from it
|
||||||
// before returning.
|
// before returning.
|
||||||
int ty = f->type->next->ty;
|
int ty = f->type->next->toBasetype()->ty;
|
||||||
if (v->getType() != p->topfunc()->getReturnType() &&
|
if (v->getType() != p->topfunc()->getReturnType() &&
|
||||||
(ty == Tstruct
|
(ty == Tstruct
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
|
|
|
@ -139,11 +139,17 @@ static LLValue *fixArgument(DValue *argval, TypeFunction* tf, const LLType *call
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Hack around LDC assuming structs are in memory:
|
// Hack around LDC assuming structs and static arrays are in memory:
|
||||||
// If the function wants a struct, and the argument value is a
|
// If the function wants a struct, and the argument value is a
|
||||||
// pointer to a struct, load from it before passing it in.
|
// pointer to a struct, load from it before passing it in.
|
||||||
if (argval->getType()->ty == Tstruct
|
int ty = argval->getType()->toBasetype()->ty;
|
||||||
&& isaPointer(arg) && !isaPointer(callableArgType)) {
|
if (isaPointer(arg) && !isaPointer(callableArgType) &&
|
||||||
|
#if DMDV2
|
||||||
|
(ty == Tstruct || ty == Tsarray))
|
||||||
|
#else
|
||||||
|
ty == Tstruct)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
Logger::println("Loading struct type for function argument");
|
Logger::println("Loading struct type for function argument");
|
||||||
arg = DtoLoad(arg);
|
arg = DtoLoad(arg);
|
||||||
}
|
}
|
||||||
|
@ -586,7 +592,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
|
||||||
// If the function returns a struct or a static array, and the return
|
// If the function returns a struct or a static array, and the return
|
||||||
// value is not a pointer to a struct or a static array, store it to
|
// value is not a pointer to a struct or a static array, store it to
|
||||||
// a stack slot before continuing.
|
// a stack slot before continuing.
|
||||||
int ty = tf->next->ty;
|
int ty = tf->next->toBasetype()->ty;
|
||||||
if ((ty == Tstruct && !isaPointer(retllval))
|
if ((ty == Tstruct && !isaPointer(retllval))
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
|| (ty == Tsarray && isaArray(retllval))
|
|| (ty == Tsarray && isaArray(retllval))
|
||||||
|
|
|
@ -176,7 +176,7 @@ const llvm::Type * IrTypeSArray::sarray2llvm(Type * t)
|
||||||
const llvm::Type* elemType = DtoType(t->nextOf());
|
const llvm::Type* elemType = DtoType(t->nextOf());
|
||||||
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
if (elemType == llvm::Type::getVoidTy(llvm::getGlobalContext()))
|
||||||
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
elemType = llvm::Type::getInt8Ty(llvm::getGlobalContext());
|
||||||
return llvm::ArrayType::get(elemType, dim);
|
return llvm::ArrayType::get(elemType, dim == 0 ? 1 : dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue