mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 10:57:35 +03:00
Optimize some slice copies
Cache length & ptr in DSliceValue, so that e.g. a pair constructed from a constant length and some ptr keeps returning a constant length instead of an extractvalue instruction every time the length is needed. This enables checking for matching constant lengths when copying slices and makes `test1()` in runnable/betterc.d work (memcpy instead of _d_array_slice_copy call): ``` int[10] a1 = void; int[10] a2 = void; a1[] = a2[]; ``` (more or less equivalent to `a1 = a2`, which is already optimized)
This commit is contained in:
parent
a911e72c86
commit
2fb5098f48
3 changed files with 34 additions and 6 deletions
|
@ -275,8 +275,18 @@ void DtoArrayAssign(Loc &loc, DValue *lhs, DValue *rhs, int op,
|
||||||
LLValue *lhsSize = computeSize(lhsLength, elementSize);
|
LLValue *lhsSize = computeSize(lhsLength, elementSize);
|
||||||
DtoMemSetZero(lhsPtr, lhsSize);
|
DtoMemSetZero(lhsPtr, lhsSize);
|
||||||
} else {
|
} else {
|
||||||
const bool knownInBounds =
|
bool knownInBounds =
|
||||||
isConstructing || (t->ty == Tsarray && t2->ty == Tsarray);
|
isConstructing || (t->ty == Tsarray && t2->ty == Tsarray);
|
||||||
|
if (!knownInBounds) {
|
||||||
|
if (auto constLhsLength = llvm::dyn_cast<LLConstantInt>(lhsLength)) {
|
||||||
|
if (auto constRhsLength =
|
||||||
|
llvm::dyn_cast<LLConstantInt>(rhsLength)) {
|
||||||
|
if (constLhsLength->getValue() == constRhsLength->getValue()) {
|
||||||
|
knownInBounds = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
copySlice(loc, lhsPtr, lhsLength, rhsPtr, rhsLength, elementSize,
|
copySlice(loc, lhsPtr, lhsLength, rhsPtr, rhsLength, elementSize,
|
||||||
knownInBounds);
|
knownInBounds);
|
||||||
}
|
}
|
||||||
|
@ -1194,7 +1204,9 @@ LLValue *DtoArrayLen(DValue *v) {
|
||||||
if (v->isLVal()) {
|
if (v->isLVal()) {
|
||||||
return DtoLoad(DtoGEPi(DtoLVal(v), 0, 0), ".len");
|
return DtoLoad(DtoGEPi(DtoLVal(v), 0, 0), ".len");
|
||||||
}
|
}
|
||||||
return gIR->ir->CreateExtractValue(DtoRVal(v), 0, ".len");
|
auto slice = v->isSlice();
|
||||||
|
assert(slice);
|
||||||
|
return slice->getLength();
|
||||||
}
|
}
|
||||||
if (t->ty == Tsarray) {
|
if (t->ty == Tsarray) {
|
||||||
assert(!v->isSlice());
|
assert(!v->isSlice());
|
||||||
|
@ -1222,7 +1234,9 @@ LLValue *DtoArrayPtr(DValue *v) {
|
||||||
} else if (v->isLVal()) {
|
} else if (v->isLVal()) {
|
||||||
ptr = DtoLoad(DtoGEPi(DtoLVal(v), 0, 1), ".ptr");
|
ptr = DtoLoad(DtoGEPi(DtoLVal(v), 0, 1), ".ptr");
|
||||||
} else {
|
} else {
|
||||||
ptr = gIR->ir->CreateExtractValue(DtoRVal(v), 1, ".ptr");
|
auto slice = v->isSlice();
|
||||||
|
assert(slice);
|
||||||
|
ptr = slice->getPtr();
|
||||||
}
|
}
|
||||||
} else if (t->ty == Tsarray) {
|
} else if (t->ty == Tsarray) {
|
||||||
assert(!v->isSlice());
|
assert(!v->isSlice());
|
||||||
|
|
|
@ -87,11 +87,22 @@ DSliceValue::DSliceValue(Type *t, LLValue *pair) : DRValue(t, pair) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
|
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
|
||||||
: DSliceValue(t, DtoAggrPair(length, ptr)) {}
|
: DSliceValue(t, DtoAggrPair(length, ptr)) {
|
||||||
|
cachedLength = length;
|
||||||
|
cachedPtr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
LLValue *DSliceValue::getLength() { return DtoExtractValue(val, 0, ".len"); }
|
LLValue *DSliceValue::getLength() {
|
||||||
|
if (!cachedLength)
|
||||||
|
cachedLength = DtoExtractValue(val, 0, ".len");
|
||||||
|
return cachedLength;
|
||||||
|
}
|
||||||
|
|
||||||
LLValue *DSliceValue::getPtr() { return DtoExtractValue(val, 1, ".ptr"); }
|
LLValue *DSliceValue::getPtr() {
|
||||||
|
if (!cachedPtr)
|
||||||
|
cachedPtr = DtoExtractValue(val, 1, ".ptr");
|
||||||
|
return cachedPtr;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,9 @@ public:
|
||||||
|
|
||||||
/// Represents a D slice (dynamic array).
|
/// Represents a D slice (dynamic array).
|
||||||
class DSliceValue : public DRValue {
|
class DSliceValue : public DRValue {
|
||||||
|
llvm::Value *cachedLength = nullptr;
|
||||||
|
llvm::Value *cachedPtr = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DSliceValue(Type *t, llvm::Value *pair);
|
DSliceValue(Type *t, llvm::Value *pair);
|
||||||
DSliceValue(Type *t, llvm::Value *length, llvm::Value *ptr);
|
DSliceValue(Type *t, llvm::Value *length, llvm::Value *ptr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue