Optimize initializations of byte arrays with non-const byte to memset()

It was previously restricted to a compile-time-constant right-hand-side byte.
This commit is contained in:
Martin 2017-01-21 19:42:27 +01:00
parent 5fcfd96560
commit f95d5fdf1d

View file

@ -107,28 +107,24 @@ void DtoSetArrayToNull(LLValue *v) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void DtoArrayInit(Loc &loc, LLValue *ptr, LLValue *length, static void DtoArrayInit(Loc &loc, LLValue *ptr, LLValue *length,
DValue *dvalue) { DValue *elementValue) {
IF_LOG Logger::println("DtoArrayInit"); IF_LOG Logger::println("DtoArrayInit");
LOG_SCOPE; LOG_SCOPE;
// lets first optimize all zero/constant i8 initializations down to a memset. // Let's first optimize all zero/i8 initializations down to a memset.
// this simplifies codegen later on as llvm null's have no address! // This simplifies codegen later on as llvm null's have no address!
if (!dvalue->isLVal()) { if (!elementValue->isLVal() || !DtoIsInMemoryOnly(elementValue->type)) {
LLConstant *constantVal = isaConstant(DtoRVal(dvalue)); LLValue *val = DtoRVal(elementValue);
if (constantVal && LLConstant *constantVal = isaConstant(val);
(constantVal->isNullValue() || bool isNullConstant = (constantVal && constantVal->isNullValue());
constantVal->getType() == LLType::getInt8Ty(gIR->context()))) { if (isNullConstant || val->getType() == LLType::getInt8Ty(gIR->context())) {
LLValue *size = length; LLValue *size = length;
size_t elementSize = getTypeAllocSize(constantVal->getType()); size_t elementSize = getTypeAllocSize(val->getType());
if (elementSize != 1) { if (elementSize != 1) {
size = gIR->ir->CreateMul(length, DtoConstSize_t(elementSize), size = gIR->ir->CreateMul(length, DtoConstSize_t(elementSize),
".arraysize"); ".arraysize");
} }
if (constantVal->isNullValue()) { DtoMemSet(ptr, isNullConstant ? DtoConstUbyte(0) : val, size);
DtoMemSetZero(ptr, size);
} else {
DtoMemSet(ptr, constantVal, size);
}
return; return;
} }
} }
@ -161,9 +157,9 @@ static void DtoArrayInit(Loc &loc, LLValue *ptr, LLValue *length,
LLValue *itr_val = DtoLoad(itr); LLValue *itr_val = DtoLoad(itr);
// assign array element value // assign array element value
DLValue arrayelem(dvalue->type->toBasetype(), DLValue arrayelem(elementValue->type->toBasetype(),
DtoGEP1(ptr, itr_val, true, "arrayinit.arrayelem")); DtoGEP1(ptr, itr_val, true, "arrayinit.arrayelem"));
DtoAssign(loc, &arrayelem, dvalue, TOKblit); DtoAssign(loc, &arrayelem, elementValue, TOKblit);
// increment iterator // increment iterator
DtoStore(gIR->ir->CreateAdd(itr_val, DtoConstSize_t(1), "arrayinit.new_itr"), DtoStore(gIR->ir->CreateAdd(itr_val, DtoConstSize_t(1), "arrayinit.new_itr"),