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

@ -87,12 +87,9 @@ DValue *DtoNewClass(const Loc &loc, TypeClass *tc, NewExp *newexp) {
const bool useEHAlloc = global.params.ehnogc && newexp->thrownew;
llvm::Function *fn = getRuntimeFunction(
loc, gIR->module, useEHAlloc ? "_d_newThrowable" : "_d_allocclass");
LLConstant *ci =
DtoBitCast(irClass->getClassInfoSymbol(), DtoType(getClassInfoType()));
LLConstant *ci = irClass->getClassInfoSymbol();
mem = gIR->CreateCallOrInvoke(
fn, ci, useEHAlloc ? ".newthrowable_alloc" : ".newclass_gc_alloc");
mem = DtoBitCast(mem, DtoType(tc),
useEHAlloc ? ".newthrowable" : ".newclass_gc");
fn, ci, useEHAlloc ? ".newthrowable" : ".newclass_gc");
doInit = !useEHAlloc;
}
@ -108,7 +105,7 @@ DValue *DtoNewClass(const Loc &loc, TypeClass *tc, NewExp *newexp) {
LLValue *src = DtoRVal(newexp->thisexp);
LLValue *dst = DtoGEP(irClass->getLLStructType(), mem, 0, idx);
IF_LOG Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
DtoStore(src, DtoBitCast(dst, getPtrToType(src->getType())));
DtoStore(src, dst);
}
// set the context for nested classes
else if (tc->sym->isNested() && tc->sym->vthis) {
@ -169,7 +166,6 @@ void DtoInitClass(TypeClass *tc, LLValue *dst) {
// init symbols might not have valid types
LLValue *initsym = irClass->getInitSymbol();
initsym = DtoBitCast(initsym, DtoType(tc));
LLValue *srcarr = DtoGEP(st, initsym, 0, firstDataIdx);
DtoMemCpy(dstarr, srcarr, DtoConstSize_t(dataBytes));
@ -182,8 +178,7 @@ void DtoFinalizeClass(const Loc &loc, LLValue *inst) {
llvm::Function *fn =
getRuntimeFunction(loc, gIR->module, "_d_callfinalizer");
gIR->CreateCallOrInvoke(
fn, DtoBitCast(inst, fn->getFunctionType()->getParamType(0)), "");
gIR->CreateCallOrInvoke(fn, inst, "");
}
////////////////////////////////////////////////////////////////////////////////
@ -244,9 +239,7 @@ DValue *DtoCastClass(const Loc &loc, DValue *val, Type *_to) {
// class -> pointer
if (to->ty == TY::Tpointer) {
IF_LOG Logger::println("to pointer");
LLType *tolltype = DtoType(_to);
LLValue *rval = DtoBitCast(DtoRVal(val), tolltype);
return new DImValue(_to, rval);
return new DImValue(_to, DtoRVal(val));
}
// class -> bool
if (to->ty == TY::Tbool) {
@ -288,7 +281,6 @@ DValue *DtoCastClass(const Loc &loc, DValue *val, Type *_to) {
// else if from is interface: _d_interface_cast(to)
// else if from is class: _d_dynamic_cast(to)
LLType *toType = DtoType(_to);
int offset = 0;
if (tc->sym->isBaseOf(fc->sym, &offset)) {
Logger::println("static down cast");
@ -300,14 +292,11 @@ DValue *DtoCastClass(const Loc &loc, DValue *val, Type *_to) {
LLValue *v = orig;
if (offset != 0) {
assert(offset > 0);
v = DtoBitCast(v, getVoidPtrType());
v = DtoGEP1(LLType::getInt8Ty(gIR->context()), v, DtoConstUint(offset));
v = DtoGEP1(getI8Type(), v, DtoConstUint(offset));
}
IF_LOG {
Logger::cout() << "V = " << *v << std::endl;
Logger::cout() << "T = " << *toType << std::endl;
}
v = DtoBitCast(v, toType);
// Check whether the original value was null, and return null if so.
// Sure we could have jumped over the code above in this case, but
@ -316,8 +305,8 @@ DValue *DtoCastClass(const Loc &loc, DValue *val, Type *_to) {
// null.
LLValue *isNull = gIR->ir->CreateICmpEQ(
orig, LLConstant::getNullValue(orig->getType()), ".nullcheck");
v = gIR->ir->CreateSelect(isNull, LLConstant::getNullValue(toType), v,
".interface");
v = gIR->ir->CreateSelect(
isNull, LLConstant::getNullValue(getVoidPtrType()), v, ".interface");
// return r-value
return new DImValue(_to, v);
}
@ -325,8 +314,8 @@ DValue *DtoCastClass(const Loc &loc, DValue *val, Type *_to) {
if (fc->sym->classKind == ClassKind::cpp) {
Logger::println("C++ class/interface cast");
LLValue *v = tc->sym->classKind == ClassKind::cpp
? DtoBitCast(DtoRVal(val), toType)
: LLConstant::getNullValue(toType);
? DtoRVal(val)
: LLConstant::getNullValue(getVoidPtrType());
return new DImValue(_to, v);
}
@ -363,7 +352,6 @@ DValue *DtoDynamicCastObject(const Loc &loc, DValue *val, Type *_to) {
// Object o
LLValue *obj = DtoRVal(val);
obj = DtoBitCast(obj, funcTy->getParamType(0));
assert(funcTy->getParamType(0) == obj->getType());
// ClassInfo c
@ -371,18 +359,11 @@ DValue *DtoDynamicCastObject(const Loc &loc, DValue *val, Type *_to) {
DtoResolveClass(to->sym);
LLValue *cinfo = getIrAggr(to->sym)->getClassInfoSymbol();
// unfortunately this is needed as the implementation of object differs
// somehow from the declaration
// this could happen in user code as well :/
cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
assert(funcTy->getParamType(1) == cinfo->getType());
// call it
LLValue *ret = gIR->CreateCallOrInvoke(func, obj, cinfo);
// cast return value
ret = DtoBitCast(ret, DtoType(_to));
return new DImValue(_to, ret);
}
@ -400,23 +381,15 @@ DValue *DtoDynamicCastInterface(const Loc &loc, DValue *val, Type *_to) {
// void* p
LLValue *ptr = DtoRVal(val);
ptr = DtoBitCast(ptr, funcTy->getParamType(0));
// ClassInfo c
TypeClass *to = static_cast<TypeClass *>(_to->toBasetype());
DtoResolveClass(to->sym);
LLValue *cinfo = getIrAggr(to->sym)->getClassInfoSymbol();
// unfortunately this is needed as the implementation of object differs
// somehow from the declaration
// this could happen in user code as well :/
cinfo = DtoBitCast(cinfo, funcTy->getParamType(1));
// call it
LLValue *ret = gIR->CreateCallOrInvoke(func, ptr, cinfo);
// cast return value
ret = DtoBitCast(ret, DtoType(_to));
return new DImValue(_to, ret);
}
@ -460,9 +433,6 @@ DtoVirtualFunctionPointer(DValue *inst, FuncDeclaration *fdecl) {
IF_LOG Logger::cout() << "funcval: " << *funcval << '\n';
// cast to funcptr type
funcval = DtoBitCast(funcval, getPtrToType(DtoFunctionType(fdecl)));
// postpone naming until after casting to get the name in call instructions
funcval->setName(name);