Rename DtoAggrCopy/ZeroInit() to DtoMemCpy/SetZero() overloads

And replace some obvious load->store combos by a memcpy.
This commit is contained in:
Martin 2015-11-22 14:39:51 +01:00
parent 740a21eb8f
commit ddfaac10b3
10 changed files with 53 additions and 51 deletions

View file

@ -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(); }
TargetABI *getAArch64TargetABI() { return new AArch64TargetABI(); }

View file

@ -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;
}

View file

@ -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); }

View file

@ -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;
}

View file

@ -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) {

View file

@ -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;
}

View file

@ -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);

View file

@ -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<TypeStruct *>(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 {

View file

@ -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);
}

View file

@ -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