mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 16:11:08 +03:00
Skip some obsolete muls and divs for arrays with element size = 1
This commit is contained in:
parent
1621bed1f4
commit
de26dd6747
1 changed files with 21 additions and 10 deletions
|
@ -248,6 +248,12 @@ void DtoArrayAssign(Loc &loc, DValue *lhs, DValue *rhs, int op,
|
||||||
LLValue *lhsPtr = DtoBitCast(realLhsPtr, getVoidPtrType());
|
LLValue *lhsPtr = DtoBitCast(realLhsPtr, getVoidPtrType());
|
||||||
LLValue *lhsLength = DtoArrayLen(lhs);
|
LLValue *lhsLength = DtoArrayLen(lhs);
|
||||||
|
|
||||||
|
auto computeSize = [](LLValue *length, size_t elementSize) {
|
||||||
|
return elementSize == 1
|
||||||
|
? length
|
||||||
|
: gIR->ir->CreateMul(length, DtoConstSize_t(elementSize));
|
||||||
|
};
|
||||||
|
|
||||||
// Be careful to handle void arrays correctly when modifying this (see tests
|
// Be careful to handle void arrays correctly when modifying this (see tests
|
||||||
// for DMD issue 7493).
|
// for DMD issue 7493).
|
||||||
// TODO: This should use AssignExp::memset.
|
// TODO: This should use AssignExp::memset.
|
||||||
|
@ -264,14 +270,13 @@ void DtoArrayAssign(Loc &loc, DValue *lhs, DValue *rhs, int op,
|
||||||
|
|
||||||
if (!needsDestruction && !needsPostblit) {
|
if (!needsDestruction && !needsPostblit) {
|
||||||
// fast version
|
// fast version
|
||||||
LLValue *elemSize =
|
const size_t elementSize = getTypeAllocSize(DtoMemType(elemType));
|
||||||
DtoConstSize_t(getTypeAllocSize(DtoMemType(elemType)));
|
LLValue *lhsSize = computeSize(lhsLength, elementSize);
|
||||||
LLValue *lhsSize = gIR->ir->CreateMul(elemSize, lhsLength);
|
|
||||||
|
|
||||||
if (rhs->isNull()) {
|
if (rhs->isNull()) {
|
||||||
DtoMemSetZero(lhsPtr, lhsSize);
|
DtoMemSetZero(lhsPtr, lhsSize);
|
||||||
} else {
|
} else {
|
||||||
LLValue *rhsSize = gIR->ir->CreateMul(elemSize, rhsLength);
|
LLValue *rhsSize = computeSize(rhsLength, elementSize);
|
||||||
const bool knownInBounds =
|
const bool knownInBounds =
|
||||||
isConstructing || (t->ty == Tsarray && t2->ty == Tsarray);
|
isConstructing || (t->ty == Tsarray && t2->ty == Tsarray);
|
||||||
copySlice(loc, lhsPtr, lhsSize, rhsPtr, rhsSize, knownInBounds);
|
copySlice(loc, lhsPtr, lhsSize, rhsPtr, rhsSize, knownInBounds);
|
||||||
|
@ -302,13 +307,19 @@ void DtoArrayAssign(Loc &loc, DValue *lhs, DValue *rhs, int op,
|
||||||
|
|
||||||
if (!needsDestruction && !needsPostblit) {
|
if (!needsDestruction && !needsPostblit) {
|
||||||
// fast version
|
// fast version
|
||||||
LLValue *elemSize = DtoConstSize_t(
|
const size_t lhsElementSize =
|
||||||
getTypeAllocSize(realLhsPtr->getType()->getContainedType(0)));
|
getTypeAllocSize(realLhsPtr->getType()->getContainedType(0));
|
||||||
LLValue *lhsSize = gIR->ir->CreateMul(elemSize, lhsLength);
|
|
||||||
LLType *rhsType = DtoMemType(t2);
|
LLType *rhsType = DtoMemType(t2);
|
||||||
LLValue *rhsSize = DtoConstSize_t(getTypeAllocSize(rhsType));
|
const size_t rhsSize = getTypeAllocSize(rhsType);
|
||||||
LLValue *actualPtr = DtoBitCast(lhsPtr, rhsType->getPointerTo());
|
LLValue *actualPtr = DtoBitCast(realLhsPtr, rhsType->getPointerTo());
|
||||||
LLValue *actualLength = gIR->ir->CreateExactUDiv(lhsSize, rhsSize);
|
LLValue *actualLength = lhsLength;
|
||||||
|
if (rhsSize != lhsElementSize) {
|
||||||
|
LLValue *lhsSize = computeSize(lhsLength, lhsElementSize);
|
||||||
|
actualLength =
|
||||||
|
rhsSize == 1
|
||||||
|
? lhsSize
|
||||||
|
: gIR->ir->CreateExactUDiv(lhsSize, DtoConstSize_t(rhsSize));
|
||||||
|
}
|
||||||
DtoArrayInit(loc, actualPtr, actualLength, rhs);
|
DtoArrayInit(loc, actualPtr, actualLength, rhs);
|
||||||
} else {
|
} else {
|
||||||
LLFunction *fn = getRuntimeFunction(loc, gIR->module,
|
LLFunction *fn = getRuntimeFunction(loc, gIR->module,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue