Safe some allocas+loads when creating LL slices

Create the LL pair directly instead.
This commit is contained in:
Martin 2016-07-20 22:30:12 +02:00
parent 126184a8b6
commit ca8c932d75
3 changed files with 24 additions and 34 deletions

View file

@ -29,32 +29,22 @@ static void DtoSetArray(DValue *array, LLValue *dim, LLValue *ptr);
////////////////////////////////////////////////////////////////////////////////
static LLValue *DtoSlice(Expression *e) {
namespace {
LLValue *DtoSlice(LLValue *ptr, LLValue *length, LLType *elemType = nullptr) {
if (!elemType)
elemType = ptr->getType()->getContainedType(0);
elemType = i1ToI8(voidToI8(elemType));
return DtoAggrPair(length, DtoBitCast(ptr, elemType->getPointerTo()));
}
LLValue *DtoSlice(Expression *e) {
DValue *dval = toElem(e);
if (dval->type->toBasetype()->ty == Tsarray) {
// Convert static array to slice
LLStructType *type = DtoArrayType(LLType::getInt8Ty(gIR->context()));
LLValue *array = DtoRawAlloca(type, 0, ".array");
DtoStore(DtoArrayLen(dval), DtoGEPi(array, 0, 0, ".len"));
DtoStore(DtoBitCast(DtoLVal(dval), getVoidPtrType()),
DtoGEPi(array, 0, 1, ".ptr"));
return DtoLoad(array);
return DtoSlice(DtoLVal(dval), DtoArrayLen(dval));
}
return DtoRVal(dval);
}
static LLValue *DtoSlice(LLValue *ptr, LLValue *length,
LLType *elemType = nullptr) {
if (elemType == nullptr) {
elemType = ptr->getType()->getContainedType(0);
}
elemType = i1ToI8(voidToI8(elemType));
LLStructType *type = DtoArrayType(elemType);
LLValue *array = DtoRawAlloca(type, 0, ".array");
DtoStore(length, DtoGEPi(array, 0, 0));
DtoStore(DtoBitCast(ptr, elemType->getPointerTo()), DtoGEPi(array, 0, 1));
return DtoLoad(array);
}
////////////////////////////////////////////////////////////////////////////////
@ -613,17 +603,15 @@ LLConstant *DtoConstSlice(LLConstant *dim, LLConstant *ptr, Type *type) {
////////////////////////////////////////////////////////////////////////////////
static DSliceValue *getSlice(Type *arrayType, LLValue *array) {
// Get ptr and length of the array
LLValue *arrayLen = DtoExtractValue(array, 0, ".len");
LLValue *newptr = DtoExtractValue(array, 1, ".ptr");
LLType *llArrayType = DtoType(arrayType);
if (array->getType() == llArrayType)
return new DSliceValue(arrayType, array);
// cast pointer to wanted type
LLType *dstType = DtoType(arrayType)->getContainedType(1);
if (newptr->getType() != dstType) {
newptr = DtoBitCast(newptr, dstType, ".gc_mem");
}
LLValue *len = DtoExtractValue(array, 0, ".len");
LLValue *ptr = DtoExtractValue(array, 1, ".ptr");
ptr = DtoBitCast(ptr, llArrayType->getContainedType(1));
return new DSliceValue(arrayType, arrayLen, newptr);
return new DSliceValue(arrayType, len, ptr);
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -73,12 +73,14 @@ DConstValue::DConstValue(Type *t, LLConstant *con) : DRValue(t, con) {
////////////////////////////////////////////////////////////////////////////////
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
: DRValue(t, DtoAggrPair(length, ptr)) {
assert(t->toBasetype()->ty == Tarray &&
ptr->getType() == DtoPtrToType(t->toBasetype()->nextOf()));
DSliceValue::DSliceValue(Type *t, LLValue *pair) : DRValue(t, pair) {
assert(t->toBasetype()->ty == Tarray);
assert(pair->getType() == DtoType(t));
}
DSliceValue::DSliceValue(Type *t, LLValue *length, LLValue *ptr)
: DSliceValue(t, DtoAggrPair(length, ptr)) {}
LLValue *DSliceValue::getLength() { return DtoExtractValue(val, 0, ".len"); }
LLValue *DSliceValue::getPtr() { return DtoExtractValue(val, 1, ".ptr"); }

View file

@ -119,6 +119,7 @@ public:
/// Represents a D slice (dynamic array).
class DSliceValue : public DRValue {
public:
DSliceValue(Type *t, llvm::Value *pair);
DSliceValue(Type *t, llvm::Value *length, llvm::Value *ptr);
DSliceValue *isSlice() override { return this; }
@ -172,7 +173,6 @@ public:
DSpecialRefValue *isSpecialRef() override { return this; }
};
inline llvm::Value *DtoRVal(DValue *v) { return v->getRVal()->val; }
llvm::Value *DtoLVal(DValue *v);