diff --git a/gen/abi-generic.h b/gen/abi-generic.h index 3cd65048f2..548f2260cc 100644 --- a/gen/abi-generic.h +++ b/gen/abi-generic.h @@ -203,7 +203,7 @@ struct ExplicitByvalRewrite : ABIRewrite { } LLValue *put(DValue *v) override { - if (DtoIsPassedByRef(v->getType())) { + if (DtoIsInMemoryOnly(v->getType())) { LLValue *originalPointer = v->getRVal(); LLType *type = originalPointer->getType()->getPointerElementType(); LLValue *copyForCallee = diff --git a/gen/abi.cpp b/gen/abi.cpp index 60c1be9f97..4d2465ec76 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -38,7 +38,7 @@ void ABIRewrite::getL(Type *dty, LLValue *v, LLValue *lval) { LLValue *ABIRewrite::getAddressOf(DValue *v) { Type *dty = v->getType(); - if (DtoIsPassedByRef(dty)) { + if (DtoIsInMemoryOnly(dty)) { // v is lowered to a LL pointer to the struct/static array return v->getRVal(); } diff --git a/gen/dvalue.cpp b/gen/dvalue.cpp index cd92977650..60f4f78ea3 100644 --- a/gen/dvalue.cpp +++ b/gen/dvalue.cpp @@ -67,7 +67,7 @@ LLValue *DVarValue::getRVal() { storage = DtoLoad(storage); } - if (DtoIsPassedByRef(type->toBasetype())) { + if (DtoIsInMemoryOnly(type->toBasetype())) { return storage; } diff --git a/gen/functions.cpp b/gen/functions.cpp index c5e9a4516f..8cc46e5532 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -951,7 +951,7 @@ DValue *DtoArgument(Parameter *fnarg, Expression *argexp) { } // byval arg, but expr has no storage yet - if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isNull())) { + if (DtoIsInMemoryOnly(argexp->type) && (arg->isSlice() || arg->isNull())) { LLValue *alloc = DtoAlloca(argexp->type, ".tmp_arg"); auto vv = new DVarValue(argexp->type, alloc); DtoAssign(argexp->loc, vv, arg); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index ffdea3f923..9f1d3272f8 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -1346,7 +1346,7 @@ LLValue *makeLValue(Loc &loc, DValue *value) { LLValue *valuePointer; if (value->isIm()) { valuePointer = value->getRVal(); - needsMemory = !DtoIsPassedByRef(valueType); + needsMemory = !DtoIsInMemoryOnly(valueType); } else if (value->isVar()) { valuePointer = value->getLVal(); needsMemory = false; @@ -1533,7 +1533,7 @@ DValue *DtoSymbolAddress(Loc &loc, Type *type, Declaration *decl) { assert(type->ty == Tdelegate); return new DVarValue(type, getIrValue(vd)); } - if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || + if (vd->isRef() || vd->isOut() || DtoIsInMemoryOnly(vd->type) || llvm::isa(getIrValue(vd))) { return new DVarValue(type, vd, getIrValue(vd)); } diff --git a/gen/tocall.cpp b/gen/tocall.cpp index 69dd605979..d003e01c1f 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -172,7 +172,7 @@ static void addExplicitArguments(std::vector &args, AttrSet &attrs, // Hack around LDC assuming structs and static arrays are in memory: // If the function wants a struct, and the argument value is a // pointer to a struct, load from it before passing it in. - if (isaPointer(llVal) && DtoIsPassedByRef(argType) && + if (isaPointer(llVal) && DtoIsInMemoryOnly(argType) && ((!isVararg && !isaPointer(callableArgType)) || (isVararg && !irArg->byref && !irArg->isByVal()))) { Logger::println("Loading struct type for function argument"); @@ -297,7 +297,7 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e, LLValue *pAp = toElem((*e->arguments)[0])->getLVal(); // va_list* LLValue *vaArgArg = gABI->prepareVaArg(pAp); LLType *llType = DtoType(e->type); - if (DtoIsPassedByRef(e->type)) { + if (DtoIsInMemoryOnly(e->type)) { llType = getPtrToType(llType); } result = new DImValue(e->type, p->ir->CreateVAArg(vaArgArg, llType)); diff --git a/gen/toir.cpp b/gen/toir.cpp index a715ac3c23..fa77a1b1c0 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2822,7 +2822,7 @@ public: Expression *el = (*e->exps)[i]; DValue *ep = toElem(el); LLValue *gep = DtoGEPi(val, 0, i); - if (DtoIsPassedByRef(el->type)) { + if (DtoIsInMemoryOnly(el->type)) { DtoStore(DtoLoad(ep->getRVal()), gep); } else if (el->type->ty != Tvoid) { DtoStoreZextI8(ep->getRVal(), gep); diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 1c587b78c9..7d266861a5 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -34,7 +34,7 @@ #include "ir/irtypefunction.h" #include "ir/irtypestruct.h" -bool DtoIsPassedByRef(Type *type) { +bool DtoIsInMemoryOnly(Type *type) { Type *typ = type->toBasetype(); TY t = typ->ty; return (t == Tstruct || t == Tsarray); diff --git a/gen/tollvm.h b/gen/tollvm.h index fc0cca63b5..80dcd9d2ef 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -41,11 +41,13 @@ LLPointerType *DtoPtrToType(Type *t); LLType *voidToI8(LLType *t); LLType *i1ToI8(LLType *t); -// returns true if the type must be passed by pointer -bool DtoIsPassedByRef(Type *type); +// Returns true if the type is a value type which LDC keeps exclusively in +// memory, referencing all values via LL pointers (structs and static arrays). +bool DtoIsInMemoryOnly(Type *type); -// returns true if the return value of the call expression -// is passed in a register +// Returns true if the callee uses sret (struct return). +// In that case, the caller needs to allocate the return value and pass its +// address as additional parameter to the callee, which will set it up. bool DtoIsReturnInArg(CallExp *ce); // should argument be zero or sign extended