diff --git a/gen/abi-aarch64.cpp b/gen/abi-aarch64.cpp index f56383d9c1..7891c7bea4 100644 --- a/gen/abi-aarch64.cpp +++ b/gen/abi-aarch64.cpp @@ -93,9 +93,8 @@ struct AArch64TargetABI : TargetABI { LLValue *prepareVaStart(LLValue *pAp) override { // Since the user only created a char* pointer (ap) on the stack before - // invoking va_start, - // we first need to allocate the actual __va_list struct and set 'ap' to its - // address. + // invoking va_start, we first need to allocate the actual __va_list struct + // and set 'ap' to its address. LLValue *valistmem = DtoRawAlloca(getValistType(), 0, "__va_list_mem"); valistmem = DtoBitCast(valistmem, getVoidPtrType()); DtoStore(valistmem, pAp); // ap = (void*)__va_list_mem @@ -106,8 +105,7 @@ struct AArch64TargetABI : TargetABI { void vaCopy(LLValue *pDest, LLValue *src) override { // Analog to va_start, we need to allocate a new __va_list struct on the - // stack, - // fill it with a bitcopy of the source struct... + // stack, fill it with a bitcopy of the source struct... src = DtoLoad( DtoBitCast(src, getValistType()->getPointerTo())); // *(__va_list*)src LLValue *valistmem = DtoAllocaDump(src, 0, "__va_list_mem"); @@ -134,4 +132,4 @@ struct AArch64TargetABI : TargetABI { }; // The public getter for abi.cpp -TargetABI *getAArch64TargetABI() { return new AArch64TargetABI(); } \ No newline at end of file +TargetABI *getAArch64TargetABI() { return new AArch64TargetABI(); } diff --git a/gen/abi-generic.h b/gen/abi-generic.h index 548f2260cc..a1d440feb0 100644 --- a/gen/abi-generic.h +++ b/gen/abi-generic.h @@ -199,7 +199,7 @@ struct ExplicitByvalRewrite : ABIRewrite { } void getL(Type *dty, LLValue *v, LLValue *lval) override { - DtoAggrCopy(lval, v); + DtoMemCpy(lval, v); } LLValue *put(DValue *v) override { @@ -208,7 +208,7 @@ struct ExplicitByvalRewrite : ABIRewrite { LLType *type = originalPointer->getType()->getPointerElementType(); LLValue *copyForCallee = DtoRawAlloca(type, alignment, ".ExplicitByvalRewrite_putResult"); - DtoAggrCopy(copyForCallee, originalPointer); + DtoMemCpy(copyForCallee, originalPointer); return copyForCallee; } diff --git a/gen/abi-x86-64.cpp b/gen/abi-x86-64.cpp index c65c37e4b2..0f2c67059b 100644 --- a/gen/abi-x86-64.cpp +++ b/gen/abi-x86-64.cpp @@ -204,7 +204,7 @@ struct ImplicitByvalRewrite : ABIRewrite { } void getL(Type *dty, LLValue *v, LLValue *lval) override { - DtoAggrCopy(lval, v); + DtoMemCpy(lval, v); } LLValue *put(DValue *v) override { return getAddressOf(v); } diff --git a/gen/abi.cpp b/gen/abi.cpp index 4d2465ec76..583a4688cd 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -60,7 +60,7 @@ void ABIRewrite::storeToMemory(LLValue *rval, LLValue *address) { if (getTypeStoreSize(rvalType) > getTypeAllocSize(pointeeType)) { // not enough allocated memory LLValue *paddedDump = DtoAllocaDump(rval, 0, ".storeToMemory_paddedDump"); - DtoAggrCopy(address, paddedDump); + DtoMemCpy(address, paddedDump); return; } diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 9f1d3272f8..58d625511b 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -308,7 +308,7 @@ void DtoAssign(Loc &loc, DValue *lhs, DValue *rhs, int op, // time as to not emit an invalid (overlapping) memcpy on trivial // struct self-assignments like 'A a; a = a;'. if (src != dst) { - DtoAggrCopy(dst, src); + DtoMemCpy(dst, src); } } } else if (t->ty == Tarray || t->ty == Tsarray) { diff --git a/gen/nested.cpp b/gen/nested.cpp index 8fb5743b6c..2cfd4b1206 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -28,7 +28,7 @@ static void storeVariable(VarDeclaration *vd, LLValue *dst) { isaPointer(value->getType())) { // Copy structs and static arrays LLValue *mem = DtoGcMalloc(vd->loc, DtoType(vd->type), ".gc_mem"); - DtoAggrCopy(mem, value); + DtoMemCpy(mem, value); DtoAlignedStore(mem, dst); } else { // Store the address into the frame @@ -521,7 +521,7 @@ void DtoCreateNestedContext(FuncDeclaration *fd) { // The parameter value is an alloca'd stack slot. // Copy to the nesting frame and leave the alloca for // the optimizers to clean up. - DtoStore(DtoLoad(parm->value), gep); + DtoMemCpy(gep, parm->value); gep->takeName(parm->value); parm->value = gep; } diff --git a/gen/tocall.cpp b/gen/tocall.cpp index d003e01c1f..78782eac05 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -264,7 +264,7 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e, LLValue *pAp = toElem((*e->arguments)[0])->getLVal(); // va_list* // variadic extern(D) function with implicit _argptr? if (LLValue *pArgptr = p->func()->_argptr) { - DtoStore(DtoLoad(pArgptr), pAp); // ap = _argptr + DtoMemCpy(pAp, pArgptr); // ap = _argptr result = new DImValue(e->type, pAp); } else { LLValue *vaStartArg = gABI->prepareVaStart(pAp); diff --git a/gen/toir.cpp b/gen/toir.cpp index fa77a1b1c0..68f12d1d6f 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -578,7 +578,7 @@ public: if (e->e1->type->toBasetype()->ty == Tstruct && e->e2->op == TOKint64) { Logger::println("performing aggregate zero initialization"); assert(e->e2->toInteger() == 0); - DtoAggrZeroInit(l->getLVal()); + DtoMemSetZero(l->getLVal()); TypeStruct *ts = static_cast(e->e1->type); if (ts->sym->isNested() && ts->sym->vthis) { DtoResolveNestedContext(e->loc, ts->sym, l->getLVal()); @@ -2823,7 +2823,7 @@ public: DValue *ep = toElem(el); LLValue *gep = DtoGEPi(val, 0, i); if (DtoIsInMemoryOnly(el->type)) { - DtoStore(DtoLoad(ep->getRVal()), gep); + DtoMemCpy(gep, ep->getRVal()); } else if (el->type->ty != Tvoid) { DtoStoreZextI8(ep->getRVal(), gep); } else { diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index 7d266861a5..13064ddc90 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -324,18 +324,23 @@ LLConstant *DtoGEPi(LLConstant *ptr, unsigned i0, unsigned i1) { //////////////////////////////////////////////////////////////////////////////// -void DtoMemSet(LLValue *dst, LLValue *val, LLValue *nbytes) { +void DtoMemSet(LLValue *dst, LLValue *val, LLValue *nbytes, unsigned align) { LLType *VoidPtrTy = getVoidPtrType(); dst = DtoBitCast(dst, VoidPtrTy); - gIR->ir->CreateMemSet(dst, val, nbytes, 1 /*Align*/, false /*isVolatile*/); + gIR->ir->CreateMemSet(dst, val, nbytes, align, false /*isVolatile*/); } //////////////////////////////////////////////////////////////////////////////// -void DtoMemSetZero(LLValue *dst, LLValue *nbytes) { - DtoMemSet(dst, DtoConstUbyte(0), nbytes); +void DtoMemSetZero(LLValue *dst, LLValue *nbytes, unsigned align) { + DtoMemSet(dst, DtoConstUbyte(0), nbytes, align); +} + +void DtoMemSetZero(LLValue *dst, unsigned align) { + uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0)); + DtoMemSetZero(dst, DtoConstSize_t(n), align); } //////////////////////////////////////////////////////////////////////////////// @@ -349,6 +354,13 @@ void DtoMemCpy(LLValue *dst, LLValue *src, LLValue *nbytes, unsigned align) { gIR->ir->CreateMemCpy(dst, src, nbytes, align, false /*isVolatile*/); } +void DtoMemCpy(LLValue *dst, LLValue *src, bool withPadding, unsigned align) { + LLType *pointee = dst->getType()->getContainedType(0); + uint64_t n = + withPadding ? getTypeAllocSize(pointee) : getTypeStoreSize(pointee); + DtoMemCpy(dst, src, DtoConstSize_t(n), align); +} + //////////////////////////////////////////////////////////////////////////////// LLValue *DtoMemCmp(LLValue *lhs, LLValue *rhs, LLValue *nbytes) { @@ -376,20 +388,6 @@ LLValue *DtoMemCmp(LLValue *lhs, LLValue *rhs, LLValue *nbytes) { //////////////////////////////////////////////////////////////////////////////// -void DtoAggrZeroInit(LLValue *v) { - uint64_t n = getTypeStoreSize(v->getType()->getContainedType(0)); - DtoMemSetZero(v, DtoConstSize_t(n)); -} - -//////////////////////////////////////////////////////////////////////////////// - -void DtoAggrCopy(LLValue *dst, LLValue *src) { - uint64_t n = getTypeStoreSize(dst->getType()->getContainedType(0)); - DtoMemCpy(dst, src, DtoConstSize_t(n)); -} - -//////////////////////////////////////////////////////////////////////////////// - llvm::ConstantInt *DtoConstSize_t(uint64_t i) { return LLConstantInt::get(DtoSize_t(), i, false); } diff --git a/gen/tollvm.h b/gen/tollvm.h index 80dcd9d2ef..899804cf61 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -152,15 +152,25 @@ LLValue *DtoAggrPaint(LLValue *aggr, LLType *as); * @param dst Destination memory. * @param val The value to set. * @param nbytes Number of bytes to overwrite. + * @param align The minimum alignment of the destination memory. */ -void DtoMemSet(LLValue *dst, LLValue *val, LLValue *nbytes); +void DtoMemSet(LLValue *dst, LLValue *val, LLValue *nbytes, unsigned align = 1); /** * Generates a call to llvm.memset.i32 (or i64 depending on architecture). * @param dst Destination memory. * @param nbytes Number of bytes to overwrite. + * @param align The minimum alignment of the destination memory. */ -void DtoMemSetZero(LLValue *dst, LLValue *nbytes); +void DtoMemSetZero(LLValue *dst, LLValue *nbytes, unsigned align = 1); + +/** + * The same as DtoMemSetZero but figures out the size itself based on the + * dst pointee. + * @param dst Destination memory. + * @param align The minimum alignment of the destination memory. + */ +void DtoMemSetZero(LLValue *dst, unsigned align = 1); /** * Generates a call to llvm.memcpy.i32 (or i64 depending on architecture). @@ -171,24 +181,20 @@ void DtoMemSetZero(LLValue *dst, LLValue *nbytes); */ void DtoMemCpy(LLValue *dst, LLValue *src, LLValue *nbytes, unsigned align = 1); +/** + * The same as DtoMemCpy but figures out the size itself based on the dst + * pointee. + * @param dst Destination memory. + * @param src Source memory. + * @param withPadding Use the dst pointee's padded size, not its store size. + * @param align The minimum alignment of the source and destination memory. + */ +void DtoMemCpy(LLValue *dst, LLValue *src, bool withPadding = false, + unsigned align = 1); + /** * Generates a call to C memcmp. */ LLValue *DtoMemCmp(LLValue *lhs, LLValue *rhs, LLValue *nbytes); -/** - * The same as DtoMemSetZero but figures out the size itself by "dereferencing" - * the v pointer once. - * @param v Destination memory. - */ -void DtoAggrZeroInit(LLValue *v); - -/** - * The same as DtoMemCpy but figures out the size itself by "dereferencing" dst - * the pointer once. - * @param dst Destination memory. - * @param src Source memory. - */ -void DtoAggrCopy(LLValue *dst, LLValue *src); - #endif // LDC_GEN_TOLLVM_H