Skip superfluous IR pointer bitcasts, now that they are always opaque

This commit is contained in:
Martin Kinkelin 2024-05-19 17:59:21 +02:00
parent ee9f3a142c
commit d140f2a283
28 changed files with 182 additions and 399 deletions

View file

@ -36,15 +36,6 @@ static void DtoSetArray(DValue *array, DValue *rhs);
////////////////////////////////////////////////////////////////////////////////
namespace {
LLValue *DtoSlice(LLValue *ptr, LLValue *length, LLType *elemType) {
elemType = i1ToI8(voidToI8(elemType));
return DtoAggrPair(length, DtoBitCast(ptr, elemType->getPointerTo()));
}
}
////////////////////////////////////////////////////////////////////////////////
LLStructType *DtoArrayType(Type *arrayTy) {
assert(arrayTy->nextOf());
llvm::Type *elems[] = {DtoSize_t(), DtoPtrToType(arrayTy->nextOf())};
@ -223,20 +214,19 @@ void DtoArrayAssign(const Loc &loc, DValue *lhs, DValue *rhs, EXP op,
Type *const elemType = t->nextOf()->toBasetype();
const bool needsDestruction =
(!isConstructing && elemType->needsDestruction());
LLValue *realLhsPtr = DtoArrayPtr(lhs);
LLValue *lhsPtr = DtoBitCast(realLhsPtr, getVoidPtrType());
LLValue *lhsPtr = DtoArrayPtr(lhs);
LLValue *lhsLength = DtoArrayLen(lhs);
// Be careful to handle void arrays correctly when modifying this (see tests
// for DMD issue 7493).
// TODO: This should use AssignExp::memset.
LLValue *realRhsArrayPtr = (t2->ty == TY::Tarray || t2->ty == TY::Tsarray)
? DtoArrayPtr(rhs)
: nullptr;
if (realRhsArrayPtr && DtoMemType(t2->nextOf()) == DtoMemType(t->nextOf())) {
LLValue *rhsArrayPtr = (t2->ty == TY::Tarray || t2->ty == TY::Tsarray)
? DtoArrayPtr(rhs)
: nullptr;
if (rhsArrayPtr && DtoMemType(t2->nextOf()) == DtoMemType(t->nextOf())) {
// T[] = T[] T[] = T[n]
// T[n] = T[n] T[n] = T[]
LLValue *rhsPtr = DtoBitCast(realRhsArrayPtr, getVoidPtrType());
LLValue *rhsPtr = rhsArrayPtr;
LLValue *rhsLength = DtoArrayLen(rhs);
const bool needsPostblit = (op != EXP::blit && arrayNeedsPostblit(t) &&
@ -274,9 +264,9 @@ void DtoArrayAssign(const Loc &loc, DValue *lhs, DValue *rhs, EXP op,
LLFunction *fn = getRuntimeFunction(
loc, gIR->module,
!canSkipPostblit ? "_d_arrayassign_l" : "_d_arrayassign_r");
gIR->CreateCallOrInvoke(
fn, DtoTypeInfoOf(loc, elemType), DtoSlice(rhsPtr, rhsLength, getI8Type()),
DtoSlice(lhsPtr, lhsLength, getI8Type()), DtoBitCast(tmpSwap, getVoidPtrType()));
gIR->CreateCallOrInvoke(fn, DtoTypeInfoOf(loc, elemType),
DtoAggrPair(rhsLength, rhsPtr),
DtoAggrPair(lhsLength, lhsPtr), tmpSwap);
}
} else {
// scalar rhs:
@ -291,7 +281,6 @@ void DtoArrayAssign(const Loc &loc, DValue *lhs, DValue *rhs, EXP op,
getTypeAllocSize(DtoMemType(lhs->type->nextOf()));
LLType *rhsType = DtoMemType(t2);
const size_t rhsSize = getTypeAllocSize(rhsType);
LLValue *actualPtr = DtoBitCast(realLhsPtr, rhsType->getPointerTo());
LLValue *actualLength = lhsLength;
if (rhsSize != lhsElementSize) {
LLValue *lhsSize = computeSize(lhsLength, lhsElementSize);
@ -300,7 +289,7 @@ void DtoArrayAssign(const Loc &loc, DValue *lhs, DValue *rhs, EXP op,
? lhsSize
: gIR->ir->CreateExactUDiv(lhsSize, DtoConstSize_t(rhsSize));
}
DtoArrayInit(loc, actualPtr, actualLength, rhs);
DtoArrayInit(loc, lhsPtr, actualLength, rhs);
} else if (isConstructing) {
error(loc, "ICE: array construction should have been lowered to "
"`_d_arraysetctor`");
@ -309,7 +298,7 @@ void DtoArrayAssign(const Loc &loc, DValue *lhs, DValue *rhs, EXP op,
LLFunction *fn =
getRuntimeFunction(loc, gIR->module, "_d_arraysetassign");
gIR->CreateCallOrInvoke(
fn, lhsPtr, DtoBitCast(makeLValue(loc, rhs), getVoidPtrType()),
fn, lhsPtr, makeLValue(loc, rhs),
gIR->ir->CreateTruncOrBitCast(lhsLength,
LLType::getInt32Ty(gIR->context())),
DtoTypeInfoOf(loc, stripModifiers(t2)));
@ -461,7 +450,7 @@ LLConstant *DtoConstArrayInitializer(ArrayInitializer *arrinit,
if (arrty->ty == TY::Tpointer) {
// we need to return pointer to the static array.
return DtoBitCast(gvar, DtoType(arrty));
return gvar;
}
LLConstant *gep = DtoGEP(gvar->getValueType(), gvar, 0u, 0u);
@ -607,7 +596,7 @@ void initializeArrayLiteral(IRState *p, ArrayLiteralExp *ale,
// optimizer can still decide to promote the memcpy intrinsic, so
// the cutoff merely affects compilation speed.
if (elemCount <= 4) {
DtoStore(constarr, DtoBitCast(dstMem, getPtrToType(constarr->getType())));
DtoStore(constarr, dstMem);
} else {
auto gvar = new llvm::GlobalVariable(gIR->module, constarr->getType(),
true, LLGlobalValue::InternalLinkage,
@ -622,7 +611,7 @@ void initializeArrayLiteral(IRState *p, ArrayLiteralExp *ale,
Expression *rhsExp = indexArrayLiteral(ale, i);
LLValue *lhsPtr = DtoGEP(dstType, dstMem, 0, i, "", p->scopebb());
DLValue lhs(rhsExp->type, DtoBitCast(lhsPtr, DtoPtrToType(rhsExp->type)));
DLValue lhs(rhsExp->type, lhsPtr);
// try to construct it in-place
if (!toInPlaceConstruction(&lhs, rhsExp))
@ -640,20 +629,6 @@ LLConstant *DtoConstSlice(LLConstant *dim, LLConstant *ptr, Type *type) {
return LLConstantStruct::get(lltype, values);
}
////////////////////////////////////////////////////////////////////////////////
static DSliceValue *getSlice(Type *arrayType, LLValue *array) {
LLType *llArrayType = DtoType(arrayType);
if (array->getType() == llArrayType)
return new DSliceValue(arrayType, array);
LLValue *len = DtoExtractValue(array, 0, ".len");
LLValue *ptr = DtoExtractValue(array, 1, ".ptr");
ptr = DtoBitCast(ptr, llArrayType->getContainedType(1));
return new DSliceValue(arrayType, len, ptr);
}
////////////////////////////////////////////////////////////////////////////////
DSliceValue *DtoNewDynArray(const Loc &loc, Type *arrayType, DValue *dim,
bool defaultInit) {
@ -684,8 +659,7 @@ DSliceValue *DtoNewDynArray(const Loc &loc, Type *arrayType, DValue *dim,
gIR->CreateCallOrInvoke(fn, arrayTypeInfo, arrayLen, ".gc_mem");
// return a DSliceValue with the well-known length for better optimizability
auto ptr =
DtoBitCast(DtoExtractValue(newArray, 1, ".ptr"), DtoPtrToType(eltType));
auto ptr = DtoExtractValue(newArray, 1, ".ptr");
return new DSliceValue(arrayType, arrayLen, ptr);
}
@ -700,11 +674,11 @@ DSliceValue *DtoAppendDChar(const Loc &loc, DValue *arr, Expression *exp,
// Call function (ref string x, dchar c)
LLValue *newArray = gIR->CreateCallOrInvoke(
fn, DtoBitCast(DtoLVal(arr), fn->getFunctionType()->getParamType(0)),
fn, DtoLVal(arr),
DtoBitCast(valueToAppend, fn->getFunctionType()->getParamType(1)),
".appendedArray");
return getSlice(arr->type, newArray);
return new DSliceValue(arr->type, newArray);
}
////////////////////////////////////////////////////////////////////////////////
@ -753,7 +727,7 @@ LLValue *DtoArrayEqCmp_impl(const Loc &loc, const char *func, DValue *l,
// pass array typeinfo ?
if (useti) {
LLValue *tival = DtoTypeInfoOf(loc, l->type);
args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(2)));
args.push_back(tival);
}
return gIR->CreateCallOrInvoke(fn, args);
@ -833,8 +807,7 @@ llvm::CallInst *callMemcmp(const Loc &loc, IRState &irs, LLValue *l_ptr,
sizeInBytes = irs.ir->CreateMul(sizeInBytes, DtoConstSize_t(elementSize));
}
// Call memcmp.
LLValue *args[] = {DtoBitCast(l_ptr, getVoidPtrType()),
DtoBitCast(r_ptr, getVoidPtrType()), sizeInBytes};
LLValue *args[] = {l_ptr, r_ptr, sizeInBytes};
return irs.ir->CreateCall(fn, args);
}
@ -983,7 +956,7 @@ LLValue *DtoArrayPtr(DValue *v) {
llvm_unreachable("Unexpected array type.");
}
return DtoBitCast(ptr, wantedLLPtrType);
return ptr;
}
////////////////////////////////////////////////////////////////////////////////
@ -991,8 +964,6 @@ DValue *DtoCastArray(const Loc &loc, DValue *u, Type *to) {
IF_LOG Logger::println("DtoCastArray");
LOG_SCOPE;
LLType *tolltype = DtoType(to);
Type *totype = to->toBasetype();
Type *fromtype = u->type->toBasetype();
if (fromtype->ty != TY::Tarray && fromtype->ty != TY::Tsarray) {
@ -1005,9 +976,6 @@ DValue *DtoCastArray(const Loc &loc, DValue *u, Type *to) {
if (totype->ty == TY::Tpointer) {
IF_LOG Logger::cout() << "to pointer" << '\n';
LLValue *ptr = DtoArrayPtr(u);
if (ptr->getType() != tolltype) {
ptr = gIR->ir->CreateBitCast(ptr, tolltype);
}
return new DImValue(to, ptr);
}
@ -1047,8 +1015,7 @@ DValue *DtoCastArray(const Loc &loc, DValue *u, Type *to) {
}
}
LLType *ptrty = tolltype->getStructElementType(1);
return new DSliceValue(to, length, DtoBitCast(ptr, ptrty));
return new DSliceValue(to, length, ptr);
}
if (totype->ty == TY::Tsarray) {
@ -1066,7 +1033,7 @@ DValue *DtoCastArray(const Loc &loc, DValue *u, Type *to) {
ptr = DtoArrayPtr(u);
}
return new DLValue(to, DtoBitCast(ptr, getPtrToType(tolltype)));
return new DLValue(to, ptr);
}
if (totype->ty == TY::Tbool) {
@ -1076,7 +1043,7 @@ DValue *DtoCastArray(const Loc &loc, DValue *u, Type *to) {
return new DImValue(to, gIR->ir->CreateICmpNE(ptr, nul));
}
const auto castedPtr = DtoBitCast(DtoArrayPtr(u), getPtrToType(tolltype));
const auto castedPtr = DtoArrayPtr(u);
return new DLValue(to, castedPtr);
}