Simplify generation of a call's return value

This commit is contained in:
Martin 2016-05-29 13:47:39 +02:00
parent 0f41c0c681
commit 7778db00a8
3 changed files with 8 additions and 36 deletions

View file

@ -1600,7 +1600,6 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) {
if (vd->storage_class & STClazy) {
Logger::println("lazy parameter");
assert(type->ty == Tdelegate);
return new DVarValue(type, getIrValue(vd));
}
assert(!isSpecialRefVar(vd) && "Code not expected to handle special "
"ref vars, although it can easily be "

View file

@ -168,7 +168,7 @@ void DtoPaddedStruct(Type *dty, LLValue *v, LLValue *lval) {
// Nested structs are the only members that can contain padding
DtoPaddedStruct(fields[i]->type, fieldval, fieldptr);
} else {
DtoStore(fieldval, fieldptr);
DtoStoreZextI8(fieldval, fieldptr);
}
}
}

View file

@ -882,45 +882,21 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
: 0);
LLValue *retllval =
(irFty.arg_sret ? args[sretArgIndex] : call.getInstruction());
bool retValIsLVal = (tf->isref && returnTy != Tvoid) || (irFty.arg_sret != nullptr);
// Hack around LDC assuming structs and static arrays are in memory:
// 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
// a stack slot before continuing.
bool storeReturnValueOnStack =
(returnTy == Tstruct && !isaPointer(retllval)) ||
(returnTy == Tsarray && isaArray(retllval));
bool retValIsAlloca = false;
// ignore ABI for intrinsics
const bool intrinsic =
(dfnval && dfnval->func && DtoIsIntrinsic(dfnval->func));
if (!intrinsic && !irFty.arg_sret) {
// do ABI specific return value fixups
if (storeReturnValueOnStack) {
Logger::println("Storing return value to stack slot");
if (!retValIsLVal) {
// let the ABI transform the return value back
if (DtoIsInMemoryOnly(returntype)) {
retllval = irFty.getRetLVal(returntype, retllval);
retValIsAlloca = true;
storeReturnValueOnStack = false;
retValIsLVal = true;
} else {
retllval = irFty.getRetRVal(returntype, retllval);
storeReturnValueOnStack =
(returnTy == Tstruct && !isaPointer(retllval)) ||
(returnTy == Tsarray && isaArray(retllval));
}
}
if (storeReturnValueOnStack) {
Logger::println("Storing return value to stack slot");
retllval = DtoAllocaDump(retllval, returntype);
retValIsAlloca = true;
}
// repaint the type if necessary
Type *rbase = stripModifiers(resulttype->toBasetype(), true);
Type *nextbase = stripModifiers(returntype->toBasetype(), true);
bool retinptr = irFty.arg_sret;
if (!rbase->equals(nextbase)) {
IF_LOG Logger::println("repainting return value from '%s' to '%s'",
returntype->toChars(), rbase->toChars());
@ -958,7 +934,7 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
LLValue *val =
DtoInsertValue(llvm::UndefValue::get(DtoType(rbase)), retllval, 0);
retllval = DtoAllocaDump(val, rbase, ".aalvaluetmp");
retinptr = true;
retValIsLVal = true;
break;
}
// Fall through.
@ -1033,10 +1009,7 @@ DValue *DtoCallFunction(Loc &loc, Type *resulttype, DValue *fnval,
return new DVarValue(resulttype, dfnval->vthis);
}
// if we are returning through a pointer arg
// or if we are returning a reference
// make sure we provide a lvalue back!
if (retinptr || (tf->isref && returnTy != Tvoid) || retValIsAlloca) {
if (retValIsLVal) {
return new DVarValue(resulttype, retllval);
}