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

@ -27,12 +27,11 @@
using namespace dmd;
// returns the keytype typeinfo
static LLConstant *to_keyti(const Loc &loc, DValue *aa, LLType *targetType) {
static LLConstant *to_keyti(const Loc &loc, DValue *aa) {
// keyti param
assert(aa->type->toBasetype()->ty == TY::Taarray);
TypeAArray *aatype = static_cast<TypeAArray *>(aa->type->toBasetype());
LLConstant *ti = DtoTypeInfoOf(loc, aatype->index, /*base=*/false);
return DtoBitCast(ti, targetType);
return DtoTypeInfoOf(loc, aatype->index, /*base=*/false);
}
////////////////////////////////////////////////////////////////////////////////
@ -53,31 +52,25 @@ DLValue *DtoAAIndex(const Loc &loc, Type *type, DValue *aa, DValue *key,
// aa param
LLValue *aaval = lvalue ? DtoLVal(aa) : DtoRVal(aa);
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
assert(aaval->getType()->isPointerTy());
// pkey param
LLValue *pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2));
// call runtime
LLValue *ret;
if (lvalue) {
auto t = mutableOf(unSharedOf(aa->type));
LLValue *rawAATI = DtoTypeInfoOf(loc, t, /*base=*/false);
LLValue *castedAATI = DtoBitCast(rawAATI, funcTy->getParamType(1));
LLValue *aati = DtoTypeInfoOf(loc, t, /*base=*/false);
LLValue *valsize = DtoConstSize_t(getTypeAllocSize(DtoType(type)));
ret = gIR->CreateCallOrInvoke(func, aaval, castedAATI, valsize, pkey,
ret = gIR->CreateCallOrInvoke(func, aaval, aati, valsize, pkey,
"aa.index");
} else {
LLValue *keyti = to_keyti(loc, aa, funcTy->getParamType(1));
LLValue *keyti = to_keyti(loc, aa);
ret = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey, "aa.index");
}
// cast return value
LLType *targettype = DtoPtrToType(type);
if (ret->getType() != targettype) {
ret = DtoBitCast(ret, targettype);
}
assert(ret->getType()->isPointerTy());
// Only check bounds for rvalues ('aa[key]').
// Lvalue use ('aa[key] = value') auto-adds an element.
@ -118,28 +111,20 @@ DValue *DtoAAIn(const Loc &loc, Type *type, DValue *aa, DValue *key) {
// aa param
LLValue *aaval = DtoRVal(aa);
assert(aaval->getType()->isPointerTy());
IF_LOG {
Logger::cout() << "aaval: " << *aaval << '\n';
Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
}
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
// keyti param
LLValue *keyti = to_keyti(loc, aa, funcTy->getParamType(1));
LLValue *keyti = to_keyti(loc, aa);
// pkey param
LLValue *pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, getVoidPtrType());
// call runtime
LLValue *ret = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey, "aa.in");
// cast return value
LLType *targettype = DtoType(type);
if (ret->getType() != targettype) {
ret = DtoBitCast(ret, targettype);
}
return new DImValue(type, ret);
}
@ -162,18 +147,16 @@ DValue *DtoAARemove(const Loc &loc, DValue *aa, DValue *key) {
// aa param
LLValue *aaval = DtoRVal(aa);
assert(aaval->getType()->isPointerTy());
IF_LOG {
Logger::cout() << "aaval: " << *aaval << '\n';
Logger::cout() << "totype: " << *funcTy->getParamType(0) << '\n';
}
aaval = DtoBitCast(aaval, funcTy->getParamType(0));
// keyti param
LLValue *keyti = to_keyti(loc, aa, funcTy->getParamType(1));
LLValue *keyti = to_keyti(loc, aa);
// pkey param
LLValue *pkey = makeLValue(loc, key);
pkey = DtoBitCast(pkey, funcTy->getParamType(2));
// call runtime
LLValue *res = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey);
@ -190,8 +173,10 @@ LLValue *DtoAAEquals(const Loc &loc, EXP op, DValue *l, DValue *r) {
llvm::Function *func = getRuntimeFunction(loc, gIR->module, "_aaEqual");
LLFunctionType *funcTy = func->getFunctionType();
LLValue *aaval = DtoBitCast(DtoRVal(l), funcTy->getParamType(1));
LLValue *abval = DtoBitCast(DtoRVal(r), funcTy->getParamType(2));
LLValue *aaval = DtoRVal(l);
assert(aaval->getType()->isPointerTy());
LLValue *abval = DtoRVal(r);
assert(abval->getType()->isPointerTy());
LLValue *aaTypeInfo = DtoTypeInfoOf(loc, t);
LLValue *res =
gIR->CreateCallOrInvoke(func, aaTypeInfo, aaval, abval, "aaEqRes");

View file

@ -32,7 +32,7 @@ using namespace dmd;
llvm::Value *ABIRewrite::getRVal(Type *dty, LLValue *v) {
llvm::Type *t = DtoType(dty);
return DtoLoad(t, DtoBitCast(getLVal(dty, v), t->getPointerTo()));
return DtoLoad(t, getLVal(dty, v));
}
//////////////////////////////////////////////////////////////////////////////
@ -191,8 +191,8 @@ void TargetABI::rewriteVarargs(IrFuncTy &fty,
//////////////////////////////////////////////////////////////////////////////
LLValue *TargetABI::prepareVaStart(DLValue *ap) {
// pass a i8* pointer to ap to LLVM's va_start intrinsic
return DtoBitCast(DtoLVal(ap), getVoidPtrType());
// pass an opaque pointer to ap to LLVM's va_start intrinsic
return DtoLVal(ap);
}
//////////////////////////////////////////////////////////////////////////////
@ -209,8 +209,8 @@ void TargetABI::vaCopy(DLValue *dest, DValue *src) {
//////////////////////////////////////////////////////////////////////////////
LLValue *TargetABI::prepareVaArg(DLValue *ap) {
// pass a i8* pointer to ap to LLVM's va_arg intrinsic
return DtoBitCast(DtoLVal(ap), getVoidPtrType());
// pass an opaque pointer to ap to LLVM's va_arg intrinsic
return DtoLVal(ap);
}
//////////////////////////////////////////////////////////////////////////////

View file

@ -148,7 +148,6 @@ struct BaseBitcastABIRewrite : ABIRewrite {
return DtoLoad(asType, paddedDump, name);
}
address = DtoBitCast(address, getPtrToType(asType));
return DtoLoad(asType, address, name);
}
@ -248,7 +247,7 @@ struct IndirectByvalRewrite : ABIRewrite {
}
LLValue *getLVal(Type *dty, LLValue *v) override {
return DtoBitCast(v, DtoPtrToType(dty));
return v;
}
LLType *type(Type *t) override { return DtoPtrToType(t); }

View file

@ -110,8 +110,7 @@ struct HardfloatRewrite : ABIRewrite {
DtoRawAlloca(asType, alignment, ".HardfloatRewrite_arg_storage");
for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
DtoMemCpy(DtoGEP(asType, buffer, 0, i),
DtoGEP1(getI8Type(), DtoBitCast(address, getVoidPtrType()),
flat.fields[i].offset),
DtoGEP1(getI8Type(), address, flat.fields[i].offset),
DtoConstSize_t(flat.fields[i].ty->size()));
}
return DtoLoad(asType, buffer, ".HardfloatRewrite_arg");
@ -126,8 +125,7 @@ struct HardfloatRewrite : ABIRewrite {
LLValue *ret = DtoRawAlloca(DtoType(dty), alignment,
".HardfloatRewrite_param_storage");
for (unsigned i = 0; i < (unsigned)flat.length; ++i) {
DtoMemCpy(DtoGEP1(getI8Type(), DtoBitCast(ret, getVoidPtrType()),
flat.fields[i].offset),
DtoMemCpy(DtoGEP1(getI8Type(), ret, flat.fields[i].offset),
DtoGEP(asType, buffer, 0, i),
DtoConstSize_t(flat.fields[i].ty->size()));
}

View file

@ -352,27 +352,25 @@ LLValue *X86_64TargetABI::prepareVaStart(DLValue *ap) {
// invoking va_start, we first need to allocate the actual __va_list_tag struct
// and set `ap` to its address.
LLValue *valistmem = DtoRawAlloca(getValistType(), 0, "__va_list_mem");
DtoStore(valistmem,
DtoBitCast(DtoLVal(ap), getPtrToType(valistmem->getType())));
// Pass a i8* pointer to the actual struct to LLVM's va_start intrinsic.
return DtoBitCast(valistmem, getVoidPtrType());
DtoStore(valistmem, DtoLVal(ap));
// Pass an opaque pointer to the actual struct to LLVM's va_start intrinsic.
return valistmem;
}
void X86_64TargetABI::vaCopy(DLValue *dest, DValue *src) {
// Analog to va_start, we first need to allocate a new __va_list_tag struct on
// the stack and set `dest` to its address.
LLValue *valistmem = DtoRawAlloca(getValistType(), 0, "__va_list_mem");
DtoStore(valistmem,
DtoBitCast(DtoLVal(dest), getPtrToType(valistmem->getType())));
DtoStore(valistmem, DtoLVal(dest));
// Then fill the new struct with a bitcopy of the source struct.
// `src` is a __va_list_tag* pointer to the source struct.
DtoMemCpy(getValistType(), valistmem, DtoRVal(src));
}
LLValue *X86_64TargetABI::prepareVaArg(DLValue *ap) {
// Pass a i8* pointer to the actual __va_list_tag struct to LLVM's va_arg
// Pass an opaque pointer to the actual __va_list_tag struct to LLVM's va_arg
// intrinsic.
return DtoBitCast(DtoRVal(ap), getVoidPtrType());
return DtoRVal(ap);
}
Type *X86_64TargetABI::vaListType() {

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);
}

View file

@ -96,7 +96,6 @@ DValue *emitPointerOffset(Loc loc, DValue *base, Expression *offset,
llOffset = DtoConstSize_t(byteOffset / pointeeSize);
} else { // need to cast base to i8*
llBaseTy = getI8Type();
llBase = DtoBitCast(llBase, getVoidPtrType());
llOffset = DtoConstSize_t(byteOffset);
}
}
@ -109,7 +108,6 @@ DValue *emitPointerOffset(Loc loc, DValue *base, Expression *offset,
llOffset = DtoRVal(rvals.rhs);
if (!noStrideInc) { // byte offset => cast base to i8*
llBaseTy = getI8Type();
llBase = DtoBitCast(llBase, getVoidPtrType());
}
}
@ -119,7 +117,7 @@ DValue *emitPointerOffset(Loc loc, DValue *base, Expression *offset,
llResult = DtoGEP1(llBaseTy, llBase, llOffset);
}
return new DImValue(resultType, DtoBitCast(llResult, DtoType(resultType)));
return new DImValue(resultType, llResult);
}
// LDC issue #2537 / DMD issue #18317: associative arrays can be

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);

View file

@ -181,7 +181,7 @@ DBitFieldLValue::DBitFieldLValue(Type *t, LLValue *ptr, BitFieldDeclaration *bf)
DRValue *DBitFieldLValue::getRVal() {
const auto sizeInBits = intType->getBitWidth();
const auto ptr = DtoBitCast(val, getPtrToType(intType));
const auto ptr = val;
LLValue *v = gIR->ir->CreateAlignedLoad(intType, ptr, llvm::MaybeAlign(1));
if (bf->type->isunsigned()) {
@ -206,7 +206,7 @@ DRValue *DBitFieldLValue::getRVal() {
void DBitFieldLValue::store(LLValue *value) {
assert(value->getType()->isIntegerTy());
const auto ptr = DtoBitCast(val, getPtrToType(intType));
const auto ptr = val;
const auto mask =
llvm::APInt::getLowBitsSet(intType->getBitWidth(), bf->fieldWidth);

View file

@ -1221,11 +1221,8 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
if (!irFty.arg_this->byref) {
if (fd->interfaceVirtual) {
// Adjust the 'this' pointer instead of using a thunk
LLType *targetThisType = thismem->getType();
thismem = DtoBitCast(thismem, getVoidPtrType());
auto off = DtoConstInt(-fd->interfaceVirtual->offset);
thismem = DtoGEP1(llvm::Type::getInt8Ty(gIR->context()), thismem, off);
thismem = DtoBitCast(thismem, targetThisType);
thismem = DtoGEP1(getI8Type(), thismem, off);
}
thismem = DtoAllocaDump(thismem, 0, "this");
irFunc->thisArg = thismem;

View file

@ -238,7 +238,7 @@ DValue *DtoInlineIRExpr(const Loc &loc, FuncDeclaration *fdecl,
Type *type = fdecl->type->nextOf();
if (sretPointer) {
DtoStore(rv, DtoBitCast(sretPointer, getPtrToType(rv->getType())));
DtoStore(rv, sretPointer);
return new DLValue(type, sretPointer);
}

View file

@ -155,17 +155,16 @@ IRState::setGlobalVarInitializer(LLGlobalVariable *&globalVar,
defineGlobal(globalHelperVar, initializer, symbolForLinkageAndVisibility);
// Replace all existing uses of globalVar by the bitcast pointer.
auto castHelperVar = DtoBitCast(globalHelperVar, globalVar->getType());
globalVar->replaceAllUsesWith(castHelperVar);
// Replace all existing uses of globalVar by the helper variable.
globalVar->replaceAllUsesWith(globalHelperVar);
// Register replacement for later occurrences of the original globalVar.
globalsToReplace.emplace_back(globalVar, castHelperVar);
globalsToReplace.emplace_back(globalVar, globalHelperVar);
// Reset globalVar to the helper variable.
globalVar = globalHelperVar;
return castHelperVar;
return globalHelperVar;
}
void IRState::replaceGlobals() {

View file

@ -90,39 +90,31 @@ LLValue *DtoNew(const Loc &loc, Type *newtype) {
LLConstant *ti = DtoTypeInfoOf(loc, newtype);
assert(isaPointer(ti));
// call runtime allocator
LLValue *mem = gIR->CreateCallOrInvoke(fn, ti, ".gc_mem");
// cast
return DtoBitCast(mem, DtoPtrToType(newtype), ".gc_mem");
return gIR->CreateCallOrInvoke(fn, ti, ".gc_mem");
}
void DtoDeleteMemory(const Loc &loc, DValue *ptr) {
llvm::Function *fn = getRuntimeFunction(loc, gIR->module, "_d_delmemory");
LLValue *lval = (ptr->isLVal() ? DtoLVal(ptr) : makeLValue(loc, ptr));
gIR->CreateCallOrInvoke(
fn, DtoBitCast(lval, fn->getFunctionType()->getParamType(0)));
gIR->CreateCallOrInvoke(fn, lval);
}
void DtoDeleteStruct(const Loc &loc, DValue *ptr) {
llvm::Function *fn = getRuntimeFunction(loc, gIR->module, "_d_delstruct");
LLValue *lval = (ptr->isLVal() ? DtoLVal(ptr) : makeLValue(loc, ptr));
gIR->CreateCallOrInvoke(
fn, DtoBitCast(lval, fn->getFunctionType()->getParamType(0)),
DtoBitCast(DtoTypeInfoOf(loc, ptr->type->nextOf()),
fn->getFunctionType()->getParamType(1)));
gIR->CreateCallOrInvoke(fn, lval, DtoTypeInfoOf(loc, ptr->type->nextOf()));
}
void DtoDeleteClass(const Loc &loc, DValue *inst) {
llvm::Function *fn = getRuntimeFunction(loc, gIR->module, "_d_delclass");
LLValue *lval = (inst->isLVal() ? DtoLVal(inst) : makeLValue(loc, inst));
gIR->CreateCallOrInvoke(
fn, DtoBitCast(lval, fn->getFunctionType()->getParamType(0)));
gIR->CreateCallOrInvoke(fn, lval);
}
void DtoDeleteInterface(const Loc &loc, DValue *inst) {
llvm::Function *fn = getRuntimeFunction(loc, gIR->module, "_d_delinterface");
LLValue *lval = (inst->isLVal() ? DtoLVal(inst) : makeLValue(loc, inst));
gIR->CreateCallOrInvoke(
fn, DtoBitCast(lval, fn->getFunctionType()->getParamType(0)));
gIR->CreateCallOrInvoke(fn, lval);
}
void DtoDeleteArray(const Loc &loc, DValue *arr) {
@ -137,8 +129,7 @@ void DtoDeleteArray(const Loc &loc, DValue *arr) {
: DtoTypeInfoOf(loc, elementType);
LLValue *lval = (arr->isLVal() ? DtoLVal(arr) : makeLValue(loc, arr));
gIR->CreateCallOrInvoke(fn, DtoBitCast(lval, fty->getParamType(0)),
DtoBitCast(typeInfo, fty->getParamType(1)));
gIR->CreateCallOrInvoke(fn, lval, typeInfo);
}
/******************************************************************************
@ -249,8 +240,8 @@ LLValue *DtoAllocaDump(LLValue *val, LLType *asType, int alignment,
(getTypeStoreSize(memType) <= getTypeAllocSize(asMemType) ? asMemType
: memType);
LLValue *mem = DtoRawAlloca(allocaType, alignment, name);
DtoStoreZextI8(val, DtoBitCast(mem, memType->getPointerTo()));
return DtoBitCast(mem, asMemType->getPointerTo());
DtoStoreZextI8(val, mem);
return mem;
}
/******************************************************************************
@ -337,7 +328,7 @@ void DtoCAssert(Module *M, const Loc &loc, LLValue *msg) {
void DtoThrow(const Loc &loc, DValue *e) {
LLFunction *fn = getRuntimeFunction(loc, gIR->module, "_d_throw_exception");
LLValue *arg = DtoBitCast(DtoRVal(e), fn->getFunctionType()->getParamType(0));
LLValue *arg = DtoRVal(e);
gIR->CreateCallOrInvoke(fn, arg);
gIR->ir->CreateUnreachable();
@ -426,7 +417,6 @@ void DtoAssign(const Loc &loc, DValue *lhs, DValue *rhs, EXP op,
Logger::cout() << "l : " << *l << '\n';
Logger::cout() << "r : " << *r << '\n';
}
r = DtoBitCast(r, DtoType(lhs->type));
DtoStore(r, l);
} else if (t->iscomplex()) {
LLValue *dst = DtoLVal(lhs);
@ -680,9 +670,7 @@ DValue *DtoCastStruct(const Loc &loc, DValue *val, Type *to) {
// allows for identical layouts (opCast() and so on have been lowered
// earlier by the frontend).
llvm::Value *lval = DtoLVal(val);
llvm::Value *result = DtoBitCast(lval, DtoType(to)->getPointerTo(),
lval->getName() + ".repaint");
return new DLValue(to, result);
return new DLValue(to, lval);
}
error(loc, "Internal Compiler Error: Invalid struct cast from `%s` to `%s`",
@ -705,8 +693,7 @@ DValue *DtoCast(const Loc &loc, DValue *val, Type *to) {
// implemented as structs.
if (totype->ty == TY::Tpointer) {
IF_LOG Logger::println("Casting AA to pointer.");
LLValue *rval = DtoBitCast(DtoRVal(val), DtoType(to));
return new DImValue(to, rval);
return new DImValue(to, DtoRVal(val));
}
if (totype->ty == TY::Tbool) {
IF_LOG Logger::println("Casting AA to bool.");
@ -771,20 +758,16 @@ DValue *DtoPaintType(const Loc &loc, DValue *val, Type *to) {
Type *tb = to->toBasetype();
if (val->isLVal()) {
auto ptr = DtoBitCast(DtoLVal(val), DtoPtrToType(tb));
return new DLValue(to, ptr);
return new DLValue(to, DtoLVal(val));
}
if (auto slice = val->isSlice()) {
if (tb->ty == TY::Tarray) {
auto ptr = DtoBitCast(slice->getPtr(), DtoPtrToType(tb->nextOf()));
return new DSliceValue(to, slice->getLength(), ptr);
return new DSliceValue(to, slice->getLength(), slice->getPtr());
}
} else if (auto func = val->isFunc()) {
if (tb->ty == TY::Tdelegate) {
auto funcptr =
DtoBitCast(DtoRVal(func), DtoType(tb)->getContainedType(1));
return new DFuncValue(to, func->func, funcptr, func->vthis);
return new DFuncValue(to, func->func, DtoRVal(func), func->vthis);
}
} else { // generic rvalue
LLValue *rval = DtoRVal(val);
@ -794,12 +777,11 @@ DValue *DtoPaintType(const Loc &loc, DValue *val, Type *to) {
return new DImValue(to, rval);
}
if (rval->getType()->isPointerTy() && tll->isPointerTy()) {
return new DImValue(to, DtoBitCast(rval, tll));
return new DImValue(to, rval);
}
if (from->ty == TY::Tdelegate && tb->ty == TY::Tdelegate) {
LLValue *context = gIR->ir->CreateExtractValue(rval, 0, ".context");
LLValue *funcptr = gIR->ir->CreateExtractValue(rval, 1, ".funcptr");
funcptr = DtoBitCast(funcptr, tll->getContainedType(1));
return new DImValue(to, DtoAggrPair(context, funcptr));
}
}
@ -1520,8 +1502,7 @@ DValue *DtoSymbolAddress(const Loc &loc, Type *type, Declaration *decl) {
if (vd->isClassMember() && vd == vd->isClassMember()->vtblsym) {
Logger::println("vtbl symbol");
auto cd = vd->isClassMember();
return new DLValue(
type, DtoBitCast(getIrAggr(cd)->getVtblSymbol(), DtoPtrToType(type)));
return new DLValue(type, getIrAggr(cd)->getVtblSymbol());
}
// nested variable
if (vd->nestedrefs.length) {
@ -1546,7 +1527,7 @@ DValue *DtoSymbolAddress(const Loc &loc, Type *type, Declaration *decl) {
assert(!isSpecialRefVar(vd) && "Code not expected to handle special "
"ref vars, although it can easily be "
"made to.");
return new DLValue(type, DtoBitCast(getIrValue(vd), DtoPtrToType(type)));
return new DLValue(type, getIrValue(vd));
}
Logger::println("a normal variable");
@ -1597,10 +1578,9 @@ DValue *DtoSymbolAddress(const Loc &loc, Type *type, Declaration *decl) {
if (tb->ty != TY::Tstruct) {
assert(tb->ty == TY::Tarray && tb->nextOf()->ty == TY::Tvoid);
const auto size = DtoConstSize_t(ad->structsize);
llvm::Constant *ptr =
sd && sd->zeroInit()
? getNullValue(getVoidPtrType())
: DtoBitCast(getIrAggr(ad)->getInitSymbol(), getVoidPtrType());
llvm::Constant *ptr = sd && sd->zeroInit()
? getNullValue(getVoidPtrType())
: getIrAggr(ad)->getInitSymbol();
return new DSliceValue(type, size, ptr);
}
@ -1611,7 +1591,7 @@ DValue *DtoSymbolAddress(const Loc &loc, Type *type, Declaration *decl) {
}
LLValue *initsym = getIrAggr(sd)->getInitSymbol();
return new DLValue(type, DtoBitCast(initsym, DtoPtrToType(sd->type)));
return new DLValue(type, initsym);
}
llvm_unreachable("Unimplemented VarExp type");
@ -1878,9 +1858,8 @@ DLValue *DtoIndexAggregate(LLValue *src, AggregateDeclaration *ad,
LLValue *ptr = src;
LLType * ty = nullptr;
if (!isFieldIdx) {
// Cast to void* to apply byte-wise offset from object start.
ptr = DtoBitCast(ptr, getVoidPtrType());
ptr = DtoGEP1(llvm::Type::getInt8Ty(gIR->context()), ptr, off);
// apply byte-wise offset from object start
ptr = DtoGEP1(getI8Type(), ptr, off);
ty = DtoType(vd->type);
} else {
if (ad->structsize == 0) { // can happen for extern(C) structs
@ -1894,15 +1873,11 @@ DLValue *DtoIndexAggregate(LLValue *src, AggregateDeclaration *ad,
} else {
st = irTypeAggr->getLLType();
}
ptr = DtoBitCast(ptr, st->getPointerTo());
ptr = DtoGEP(st, ptr, 0, off);
ty = isaStruct(st)->getElementType(off);
}
}
// Cast the (possibly void*) pointer to the canonical variable type.
ptr = DtoBitCast(ptr, DtoPtrToType(vd->type));
IF_LOG Logger::cout() << "Pointer: " << *ptr << '\n';
if (auto p = isaPointer(ty)) {
if (p->getAddressSpace())

View file

@ -160,30 +160,25 @@ llvm::Function *buildOrderIndependentModuleCtor(Module *m) {
/// Builds the (constant) data content for the importedModules[] array.
llvm::Constant *buildImportedModules(Module *m, size_t &count) {
const auto moduleInfoPtrTy = DtoPtrToType(getModuleInfoType());
std::vector<LLConstant *> importInits;
for (auto mod : m->aimports) {
if (!mod->needModuleInfo() || mod == m) {
continue;
}
importInits.push_back(
DtoBitCast(getIrModule(mod)->moduleInfoSymbol(), moduleInfoPtrTy));
importInits.push_back(getIrModule(mod)->moduleInfoSymbol());
}
count = importInits.size();
if (importInits.empty())
return nullptr;
const auto type = llvm::ArrayType::get(moduleInfoPtrTy, importInits.size());
const auto type = llvm::ArrayType::get(getVoidPtrType(), importInits.size());
return LLConstantArray::get(type, importInits);
}
/// Builds the (constant) data content for the localClasses[] array.
llvm::Constant *buildLocalClasses(Module *m, size_t &count) {
const auto classinfoTy = DtoType(getClassInfoType());
ClassDeclarations aclasses;
getLocalClasses(m, aclasses);
@ -205,15 +200,14 @@ llvm::Constant *buildLocalClasses(Module *m, size_t &count) {
}
IF_LOG Logger::println("class: %s", cd->toPrettyChars());
classInfoRefs.push_back(
DtoBitCast(getIrAggr(cd)->getClassInfoSymbol(), classinfoTy));
classInfoRefs.push_back(getIrAggr(cd)->getClassInfoSymbol());
}
count = classInfoRefs.size();
if (classInfoRefs.empty())
return nullptr;
const auto type = llvm::ArrayType::get(classinfoTy, classInfoRefs.size());
const auto type = llvm::ArrayType::get(getVoidPtrType(), classInfoRefs.size());
return LLConstantArray::get(type, classInfoRefs);
}
}

View file

@ -151,13 +151,12 @@ LLFunction *build_module_reference_and_ctor(const char *moduleMangle,
// make sure _Dmodule_ref is declared
const auto mrefIRMangle = getIRMangledVarName("_Dmodule_ref", LINK::c);
LLConstant *mref = gIR->module.getNamedGlobal(mrefIRMangle);
LLType *modulerefPtrTy = getPtrToType(modulerefTy);
LLType *modulerefPtrTy = getVoidPtrType();
if (!mref) {
mref =
declareGlobal(Loc(), gIR->module, modulerefPtrTy, mrefIRMangle, false,
false, global.params.dllimport != DLLImport::none);
}
mref = DtoBitCast(mref, getPtrToType(modulerefPtrTy));
// make the function insert this moduleinfo as the beginning of the
// _Dmodule_ref linked list
@ -199,9 +198,9 @@ void emitModuleRefToSection(std::string moduleMangle,
const auto thismrefIRMangle =
getIRMangledModuleRefSymbolName(moduleMangle.c_str());
auto thismref = defineGlobal(Loc(), gIR->module, thismrefIRMangle,
DtoBitCast(thisModuleInfo, moduleInfoPtrTy),
LLGlobalValue::LinkOnceODRLinkage, false, false);
auto thismref =
defineGlobal(Loc(), gIR->module, thismrefIRMangle, thisModuleInfo,
LLGlobalValue::LinkOnceODRLinkage, false, false);
thismref->setVisibility(LLGlobalValue::HiddenVisibility);
thismref->setSection(sectionName);
gIR->usedArray.push_back(thismref);

View file

@ -482,7 +482,7 @@ DValue *DtoInlineAsmExpr(const Loc &loc, FuncDeclaration *fd,
auto lvalue = sretPointer;
if (!lvalue)
lvalue = DtoAlloca(returnType, ".__asm_tuple_ret");
DtoStore(rv, DtoBitCast(lvalue, getPtrToType(irReturnType)));
DtoStore(rv, lvalue);
return new DLValue(returnType, lvalue);
}

View file

@ -138,9 +138,8 @@ DValue *DtoNestedVariable(const Loc &loc, Type *astype, VarDeclaration *vd,
// Extract variable from nested context
assert(irfunc->frameType);
const auto pframeType = LLPointerType::getUnqual(irfunc->frameType);
IF_LOG { Logger::cout() << "casting to: " << *irfunc->frameType << '\n'; }
LLValue *val = DtoBitCast(ctx, pframeType);
LLValue *val = ctx;
llvm::StructType *currFrame = irfunc->frameType;
// Make the DWARF variable address relative to the context pointer (ctx);
// register all ops (offsetting, dereferencing) required to get there in the
@ -228,7 +227,7 @@ void DtoResolveNestedContext(const Loc &loc, AggregateDeclaration *decl,
unsigned idx = getVthisIdx(decl);
llvm::StructType *st = getIrAggr(decl)->getLLStructType();
LLValue *gep = DtoGEP(st, value, 0, idx, ".vthis");
DtoStore(DtoBitCast(nest, st->getElementType(idx)), gep);
DtoStore(nest, gep);
}
}
@ -343,7 +342,6 @@ LLValue *DtoNestedContext(const Loc &loc, Dsymbol *sym) {
"Calling sibling function or directly nested function");
} else {
llvm::StructType *type = getIrFunc(ctxfd)->frameType;
val = DtoBitCast(val, LLPointerType::getUnqual(type));
val = DtoGEP(type, val, 0, neededDepth);
val = DtoAlignedLoad(type->getElementType(neededDepth),
val, (std::string(".frame.") + frameToPass->toChars()).c_str());
@ -503,7 +501,7 @@ void DtoCreateNestedContext(FuncGenState &funcGen) {
LLValue *mem =
gIR->CreateCallOrInvoke(fn, DtoConstSize_t(size), ".gc_frame");
if (frameAlignment <= 16) {
frame = DtoBitCast(mem, frameType->getPointerTo(), ".frame");
frame = mem;
} else {
const uint64_t mask = frameAlignment - 1;
mem = gIR->ir->CreatePtrToInt(mem, DtoSize_t());
@ -529,14 +527,11 @@ void DtoCreateNestedContext(FuncGenState &funcGen) {
src = indexVThis(ad, thisptr);
}
if (depth > 1) {
src = DtoBitCast(src, getVoidPtrType());
LLValue *dst = DtoBitCast(frame, getVoidPtrType());
DtoMemCpy(dst, src, DtoConstSize_t((depth - 1) * target.ptrsize),
DtoMemCpy(frame, src, DtoConstSize_t((depth - 1) * target.ptrsize),
getABITypeAlign(getVoidPtrType()));
}
// Copy nestArg into framelist; the outer frame is not in the list of
// pointers
src = DtoBitCast(src, frameType->getContainedType(depth - 1));
LLValue *gep = DtoGEP(frameType, frame, 0, depth - 1);
DtoAlignedStore(src, gep);
}

View file

@ -92,7 +92,7 @@ LLGlobalVariable *ObjCState::getMethVarRef(const ObjcSelector &sel) {
}
void ObjCState::retain(LLConstant *sym) {
retainedSymbols.push_back(DtoBitCast(sym, getVoidPtrType()));
retainedSymbols.push_back(sym);
}
void ObjCState::finalize() {

View file

@ -71,7 +71,7 @@ void RTTIBuilder::push_null_void_array() {
}
void RTTIBuilder::push_void_array(uint64_t dim, llvm::Constant *ptr) {
push(DtoConstSlice(DtoConstSize_t(dim), DtoBitCast(ptr, getVoidPtrType())));
push(DtoConstSlice(DtoConstSize_t(dim), ptr));
}
void RTTIBuilder::push_void_array(llvm::Constant *CI, Type *valtype,
@ -113,7 +113,7 @@ void RTTIBuilder::push_array(llvm::Constant *CI, uint64_t dim, Type *valtype,
setLinkage(lwc, G);
G->setAlignment(llvm::MaybeAlign(DtoAlignment(valtype)));
push_array(dim, DtoBitCast(G, DtoType(pointerTo(valtype))));
push_array(dim, G);
}
void RTTIBuilder::push_array(uint64_t dim, llvm::Constant *ptr) {
@ -128,15 +128,10 @@ void RTTIBuilder::push_size_as_vp(uint64_t s) {
push(llvm::ConstantExpr::getIntToPtr(DtoConstSize_t(s), getVoidPtrType()));
}
void RTTIBuilder::push_funcptr(FuncDeclaration *fd, Type *castto) {
void RTTIBuilder::push_funcptr(FuncDeclaration *fd) {
if (fd) {
LLConstant *F = DtoCallee(fd);
if (castto) {
F = DtoBitCast(F, DtoType(castto));
}
push(F);
} else if (castto) {
push_null(castto);
} else {
push_null_vp();
}

View file

@ -48,7 +48,7 @@ public:
void push_typeinfo(Type *t);
/// pushes the function pointer or a null void* if it cannot.
void push_funcptr(FuncDeclaration *fd, Type *castto = nullptr);
void push_funcptr(FuncDeclaration *fd);
/// pushes the array slice given.
void push_array(uint64_t dim, llvm::Constant *ptr);

View file

@ -886,7 +886,7 @@ static void emitInstrumentationFn(const char *name) {
// Grab the address of the calling function
auto *caller =
gIR->ir->CreateCall(GET_INTRINSIC_DECL(returnaddress), DtoConstInt(0));
auto callee = DtoBitCast(gIR->topfunc(), getVoidPtrType());
auto callee = gIR->topfunc();
gIR->ir->CreateCall(fn, {callee, caller});
}

View file

@ -152,7 +152,6 @@ LLValue *DtoUnpaddedStruct(Type *dty, LLValue *v) {
fieldval = DtoUnpaddedStruct(fields[i]->type, fieldptr);
} else {
assert(!fields[i]->isBitFieldDeclaration());
fieldptr = DtoBitCast(fieldptr, DtoPtrToType(fields[i]->type));
fieldval = DtoLoad(DtoType(fields[i]->type), fieldptr);
}
newval = DtoInsertValue(newval, fieldval, i);
@ -174,7 +173,6 @@ void DtoPaddedStruct(Type *dty, LLValue *v, LLValue *lval) {
DtoPaddedStruct(fields[i]->type, fieldval, fieldptr);
} else {
assert(!fields[i]->isBitFieldDeclaration());
fieldptr = DtoBitCast(fieldptr, DtoPtrToType(fields[i]->type));
DtoStoreZextI8(fieldval, fieldptr);
}
}

View file

@ -411,9 +411,8 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e,
val = DtoRVal(dval);
} else if (auto intPtrType = getPtrToAtomicType(pointeeType)) {
LLType *atype = getAtomicType(pointeeType);
ptr = DtoBitCast(ptr, intPtrType);
auto lval = makeLValue(exp1->loc, dval);
val = DtoLoad(atype, DtoBitCast(lval, intPtrType));
val = DtoLoad(atype, lval);
} else {
error(e->loc,
"atomic store only supports types of size 1/2/4/8/16 bytes, not `%s`",
@ -446,7 +445,6 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e,
if (!pointeeType->isIntegerTy()) {
if (auto intPtrType = getPtrToAtomicType(pointeeType)) {
ptr = DtoBitCast(ptr, intPtrType);
loadedType = getAtomicType(pointeeType);
} else {
error(e->loc,
@ -503,11 +501,10 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e,
val = DtoRVal(dval);
} else if (auto intPtrType = getPtrToAtomicType(pointeeType)) {
LLType *atype = getAtomicType(pointeeType);
ptr = DtoBitCast(ptr, intPtrType);
auto cmpLVal = makeLValue(exp2->loc, dcmp);
cmp = DtoLoad(atype, DtoBitCast(cmpLVal, intPtrType));
cmp = DtoLoad(atype, cmpLVal);
auto lval = makeLValue(exp3->loc, dval);
val = DtoLoad(atype, DtoBitCast(lval, intPtrType));
val = DtoLoad(atype, lval);
} else {
error(e->loc,
"`cmpxchg` only supports types of size 1/2/4/8/16 bytes, not `%s`",
@ -526,8 +523,7 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e,
// because of i1)
auto mem = DtoAlloca(e->type);
llvm::Type* memty = DtoType(e->type);
DtoStore(p->ir->CreateExtractValue(ret, 0),
DtoBitCast(DtoGEP(memty, mem, 0u, 0), ptr->getType()));
DtoStore(p->ir->CreateExtractValue(ret, 0), DtoGEP(memty, mem, 0u, 0));
DtoStoreZextI8(p->ir->CreateExtractValue(ret, 1), DtoGEP(memty, mem, 0, 1));
result = new DLValue(e->type, mem);
@ -591,8 +587,9 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e,
unsigned bitmask = DtoSize_t()->getBitWidth() - 1;
assert(bitmask == 31 || bitmask == 63);
// auto q = cast(size_t*)ptr + (bitnum >> (64bit ? 6 : 5));
LLValue *q = DtoBitCast(ptr, DtoSize_t()->getPointerTo());
q = DtoGEP1(DtoSize_t(), q, p->ir->CreateLShr(bitnum, bitmask == 63 ? 6 : 5), "bitop.q");
LLValue *q =
DtoGEP1(DtoSize_t(), ptr,
p->ir->CreateLShr(bitnum, bitmask == 63 ? 6 : 5), "bitop.q");
// auto mask = 1 << (bitnum & bitmask);
LLValue *mask =
@ -764,12 +761,10 @@ private:
}
}
}
LLValue *contextptr = DtoBitCast(thisptrLval, getVoidPtrType());
args.push_back(contextptr);
args.push_back(thisptrLval);
} else if (thiscall && dfnval && dfnval->vthis) {
// ... or a normal 'this' argument
LLValue *thisarg = DtoBitCast(dfnval->vthis, llArgType);
args.push_back(thisarg);
args.push_back(dfnval->vthis);
} else if (isDelegateCall) {
// ... or a delegate context arg
LLValue *ctxarg;
@ -778,13 +773,11 @@ private:
} else {
ctxarg = gIR->ir->CreateExtractValue(DtoRVal(fnval), 0, ".ptr");
}
ctxarg = DtoBitCast(ctxarg, llArgType);
args.push_back(ctxarg);
} else if (nestedcall) {
// ... or a nested function context arg
if (dfnval) {
LLValue *contextptr = DtoNestedContext(loc, dfnval->func);
contextptr = DtoBitCast(contextptr, getVoidPtrType());
args.push_back(contextptr);
} else {
args.push_back(llvm::UndefValue::get(getVoidPtrType()));
@ -806,8 +799,7 @@ private:
const auto selector = dfnval->func->objc.selector;
assert(selector);
LLGlobalVariable *selptr = gIR->objc.getMethVarRef(*selector);
args.push_back(DtoBitCast(DtoLoad(selptr->getValueType(), selptr),
getVoidPtrType()));
args.push_back(DtoLoad(selptr->getValueType(), selptr));
}
}
@ -919,9 +911,7 @@ DValue *DtoCallFunction(const Loc &loc, Type *resulttype, DValue *fnval,
if (irFty.arg_objcSelector) {
// Use runtime msgSend function bitcasted as original call
const char *msgSend = gABI->objcMsgSendFunc(resulttype, irFty);
LLType *t = callable->getType();
callable = getRuntimeFunction(loc, gIR->module, msgSend);
callable = DtoBitCast(callable, t);
}
// call the function
@ -971,9 +961,7 @@ DValue *DtoCallFunction(const Loc &loc, Type *resulttype, DValue *fnval,
case TY::Tsarray:
if (nextbase->ty == TY::Tvector && !tf->isref()) {
if (retValIsLVal) {
retllval = DtoBitCast(retllval, DtoType(pointerTo(rbase)));
} else {
if (!retValIsLVal) {
// static arrays need to be dumped to memory; use vector alignment
retllval =
DtoAllocaDump(retllval, DtoType(rbase), DtoAlignment(nextbase),

View file

@ -80,7 +80,6 @@ public:
if (TypeInfoDeclaration *ti = e->var->isTypeInfoDeclaration()) {
result = DtoTypeInfoOf(e->loc, ti->tinfo, /*base=*/false);
result = DtoBitCast(result, DtoType(e->type));
return;
}
@ -179,7 +178,7 @@ public:
LLConstant *arrptr = DtoGEP(gvar->getValueType(), gvar, 0u, 0u);
if (t->ty == TY::Tpointer) {
result = DtoBitCast(arrptr, DtoType(t));
result = arrptr;
} else if (t->ty == TY::Tarray) {
LLConstant *clen = LLConstantInt::get(DtoSize_t(), e->len, false);
result = DtoConstSlice(clen, arrptr, e->type);
@ -210,7 +209,6 @@ public:
llResult = llvm::ConstantExpr::getGetElementPtr(DtoMemType(pointeeType),
llBase, llOffset);
} else { // need to cast base to i8*
llBase = DtoBitCast(llBase, getVoidPtrType());
LLConstant *llOffset = DtoConstSize_t(byteOffset);
if (negateOffset)
llOffset = llvm::ConstantExpr::getNeg(llOffset);
@ -218,7 +216,7 @@ public:
llvm::ConstantExpr::getGetElementPtr(getI8Type(), llBase, llOffset);
}
return DtoBitCast(llResult, DtoType(e->type));
return llResult;
}
void visit(AddExp *e) override {
@ -323,7 +321,7 @@ public:
if (type->ty == TY::Tarray || type->ty == TY::Tdelegate) {
value = DtoGEP(irg->getType(), value, 0u, 1u);
}
result = DtoBitCast(value, DtoType(tb));
result = value;
} else if (tb->ty == TY::Tclass && e->e1->type->ty == TY::Tclass &&
e->e1->op == EXP::classReference) {
auto cd = static_cast<ClassReferenceExp *>(e->e1)->originalClass();
@ -341,7 +339,7 @@ public:
// offset pointer
instance = DtoGEP(DtoType(e->e1->type), instance, 0, i_index);
}
result = DtoBitCast(instance, DtoType(tb));
result = instance;
} else {
goto Lerr;
}
@ -384,14 +382,10 @@ public:
} else {
// Offset isn't a multiple of base type size, just cast to i8* and
// apply the byte offset.
auto i8 = LLType::getInt8Ty(gIR->context());
result = llvm::ConstantExpr::getGetElementPtr(
i8, DtoBitCast(base, i8->getPointerTo()),
DtoConstSize_t(e->offset));
getI8Type(), base, DtoConstSize_t(e->offset));
}
}
result = DtoBitCast(result, DtoType(e->type));
}
//////////////////////////////////////////////////////////////////////////////
@ -405,8 +399,7 @@ public:
// address of global variable
if (auto vexp = e->e1->isVarExp()) {
LLConstant *c = DtoConstSymbolAddress(e->loc, vexp->var);
result = c ? DtoBitCast(c, DtoType(e->type)) : nullptr;
result = DtoConstSymbolAddress(e->loc, vexp->var);
return;
}
@ -428,13 +421,11 @@ public:
// gep
LLConstant *idxs[2] = {DtoConstSize_t(0), index};
LLConstant *val = isaConstant(getIrGlobal(vd)->value);
val = DtoBitCast(val, DtoType(pointerTo(vd->type)));
LLConstant *gep = llvm::ConstantExpr::getGetElementPtr(
DtoType(vd->type), val, idxs, true);
// bitcast to requested type
assert(e->type->toBasetype()->ty == TY::Tpointer);
result = DtoBitCast(gep, DtoType(e->type));
result = gep;
return;
}
@ -541,18 +532,16 @@ public:
llvm::GlobalValue::InternalLinkage, initval, ".dynarrayStorage");
gvar->setUnnamedAddr(canBeConst ? llvm::GlobalValue::UnnamedAddr::Global
: llvm::GlobalValue::UnnamedAddr::None);
llvm::Constant *store = DtoBitCast(gvar, getPtrToType(arrtype));
if (bt->ty == TY::Tpointer) {
// we need to return pointer to the static array.
result = store;
result = gvar;
return;
}
// build a constant dynamic array reference with the .ptr field pointing
// into store
LLConstant *globalstorePtr = DtoGEP(arrtype, store, 0u, 0u);
result = DtoConstSlice(DtoConstSize_t(e->elements->length), globalstorePtr);
result = DtoConstSlice(DtoConstSize_t(e->elements->length), gvar);
}
//////////////////////////////////////////////////////////////////////////////
@ -673,7 +662,6 @@ public:
}
assert(e->type->ty == TY::Tclass || e->type->ty == TY::Tenum);
result = DtoBitCast(result, DtoType(e->type));
}
//////////////////////////////////////////////////////////////////////////////
@ -729,7 +717,6 @@ public:
}
result = DtoTypeInfoOf(e->loc, t, /*base=*/false);
result = DtoBitCast(result, DtoType(e->type));
}
//////////////////////////////////////////////////////////////////////////////

View file

@ -67,7 +67,6 @@ bool walkPostorder(Expression *e, StoppableVisitor *v);
////////////////////////////////////////////////////////////////////////////////
static LLValue *write_zeroes(LLValue *mem, unsigned start, unsigned end) {
mem = DtoBitCast(mem, getVoidPtrType());
LLType *i8 = LLType::getInt8Ty(gIR->context());
LLValue *gep = DtoGEP1(i8, mem, start, ".padding");
DtoMemSetZero(i8, gep, DtoConstSize_t(end - start));
@ -166,8 +165,7 @@ static void write_struct_literal(Loc loc, LLValue *mem, StructDeclaration *sd,
}
IF_LOG Logger::cout() << "merged IR value: " << *val << '\n';
gIR->ir->CreateAlignedStore(val, DtoBitCast(ptr, getPtrToType(intType)),
llvm::MaybeAlign(1));
gIR->ir->CreateAlignedStore(val, ptr, llvm::MaybeAlign(1));
offset += group.sizeInBytes;
i += group.bitFields.size() - 1; // skip the other bit fields of the group
@ -191,8 +189,7 @@ static void write_struct_literal(Loc loc, LLValue *mem, StructDeclaration *sd,
assert(vd == sd->vthis);
IF_LOG Logger::println("initializing vthis");
LOG_SCOPE
DImValue val(vd->type,
DtoBitCast(DtoNestedContext(loc, sd), DtoType(vd->type)));
DImValue val(vd->type, DtoNestedContext(loc, sd));
DtoAssign(loc, field, &val, EXP::blit);
}
@ -449,9 +446,9 @@ public:
result = new DSliceValue(e->type, DtoConstSlice(clen, arrptr, dtype));
} else if (dtype->ty == TY::Tsarray) {
// array length matches string length with or without null terminator
result = new DLValue(e->type, DtoBitCast(gvar, DtoPtrToType(dtype)));
result = new DLValue(e->type, gvar);
} else if (dtype->ty == TY::Tpointer) {
result = new DImValue(e->type, DtoBitCast(arrptr, DtoType(dtype)));
result = new DImValue(e->type, arrptr);
} else {
llvm_unreachable("Unknown type for StringExp.");
}
@ -799,9 +796,7 @@ public:
if (canEmitVTableUnchangedAssumption && !dfnval->vtable &&
dfnval->vthis && dfnval->func->isVirtual()) {
dfnval->vtable =
DtoLoad(getVoidPtrType(),
DtoBitCast(dfnval->vthis, getVoidPtrType()->getPointerTo()),
"saved_vtable");
DtoLoad(getVoidPtrType(), dfnval->vthis, "saved_vtable");
}
}
@ -812,9 +807,7 @@ public:
// Reload vtable ptr. It's the first element so instead of GEP+load we can
// do a void* load+bitcast (at this point in the code we don't have easy
// access to the type of the class to do a GEP).
auto vtable = DtoLoad(
dfnval->vtable->getType(),
DtoBitCast(dfnval->vthis, dfnval->vtable->getType()->getPointerTo()));
auto vtable = DtoLoad(dfnval->vtable->getType(), dfnval->vthis);
auto cmp = p->ir->CreateICmpEQ(vtable, dfnval->vtable);
p->ir->CreateCall(GET_INTRINSIC_DECL(assume), {cmp});
}
@ -910,12 +903,11 @@ public:
if (!offsetValue) {
// Offset isn't a multiple of base type size, just cast to i8* and
// apply the byte offset.
auto castBase = DtoBitCast(baseValue, getVoidPtrType());
if (target.ptrsize == 8) {
offsetValue = DtoGEP1i64(getI8Type(), castBase, e->offset);
offsetValue = DtoGEP1i64(getI8Type(), baseValue, e->offset);
} else {
offsetValue =
DtoGEP1(getI8Type(), castBase, static_cast<unsigned>(e->offset));
DtoGEP1(getI8Type(), baseValue, static_cast<unsigned>(e->offset));
}
}
}
@ -945,7 +937,7 @@ public:
LLConstant *addr = toConstElem(e, p);
IF_LOG Logger::cout()
<< "returning address of struct literal global: " << addr << '\n';
result = new DImValue(e->type, DtoBitCast(addr, DtoType(e->type)));
result = new DImValue(e->type, addr);
return;
}
@ -976,7 +968,7 @@ public:
}
IF_LOG Logger::cout() << "lval: " << *lval << '\n';
result = new DImValue(e->type, DtoBitCast(lval, DtoType(e->type)));
result = new DImValue(e->type, lval);
}
//////////////////////////////////////////////////////////////////////////////
@ -1004,7 +996,7 @@ public:
// get the rvalue and return it as an lvalue
LLValue *V = DtoRVal(e->e1);
result = new DLValue(e->type, DtoBitCast(V, DtoPtrToType(e->type)));
result = new DLValue(e->type, V);
}
static llvm::PointerType * getWithSamePointeeType(llvm::PointerType *p, unsigned addressSpace) {
@ -1065,11 +1057,9 @@ public:
}
else
ptrty = DtoType(e->type);
result = new DDcomputeLValue(e->type, i1ToI8(ptrty),
DtoBitCast(DtoLVal(d), DtoPtrToType(e->type)));
result = new DDcomputeLValue(e->type, i1ToI8(ptrty), DtoLVal(d));
} else {
LLValue *p = DtoBitCast(DtoLVal(ptr), DtoPtrToType(e->type));
result = new DLValue(e->type, p);
result = new DLValue(e->type, DtoLVal(ptr));
}
} else if (FuncDeclaration *fdecl = e->var->isFuncDeclaration()) {
// This is a bit more convoluted than it would need to be, because it
@ -1138,7 +1128,7 @@ public:
if (ident == Id::ensure || ident == Id::require) {
Logger::println("contract this exp");
LLValue *v = p->func()->nestArg; // thisptr lvalue
result = new DLValue(e->type, DtoBitCast(v, DtoPtrToType(e->type)));
result = new DLValue(e->type, v);
} else if (vd->toParent2() != p->func()->decl) {
Logger::println("nested this exp");
result =
@ -1146,7 +1136,7 @@ public:
} else {
Logger::println("normal this exp");
LLValue *v = p->func()->thisArg;
result = new DLValue(e->type, DtoBitCast(v, DtoPtrToType(e->type)));
result = new DLValue(e->type, v);
}
}
@ -1190,7 +1180,7 @@ public:
IF_LOG Logger::println("e1type: %s", e1type->toChars());
llvm_unreachable("Unknown IndexExp target.");
}
result = new DLValue(e->type, DtoBitCast(arrptr, DtoPtrToType(e->type)));
result = new DLValue(e->type, arrptr);
}
//////////////////////////////////////////////////////////////////////////////
@ -1287,10 +1277,6 @@ public:
if (etype->ty == TY::Tsarray) {
TypeSArray *tsa = static_cast<TypeSArray *>(etype);
elen = DtoConstSize_t(tsa->dim->toUInteger());
// in this case, we also need to make sure the pointer is cast to the
// innermost element type
eptr = DtoBitCast(eptr, DtoType(pointerTo(tsa->nextOf())));
}
}
@ -1298,14 +1284,13 @@ public:
// fixed-width slice to a static array.
Type *const ety = e->type->toBasetype();
if (ety->ty == TY::Tsarray) {
result = new DLValue(e->type, DtoBitCast(eptr, DtoPtrToType(e->type)));
result = new DLValue(e->type, eptr);
return;
}
assert(ety->ty == TY::Tarray);
if (!elen)
elen = DtoArrayLen(v);
eptr = DtoBitCast(eptr, DtoPtrToType(ety->nextOf()));
result = new DSliceValue(e->type, elen, eptr);
}
@ -1623,8 +1608,7 @@ public:
else if (auto taa = ntype->isTypeAArray()) {
LLFunction *func = getRuntimeFunction(e->loc, gIR->module, "_aaNew");
LLValue *aaTypeInfo =
DtoBitCast(DtoTypeInfoOf(e->loc, stripModifiers(taa), /*base=*/false),
DtoType(getAssociativeArrayTypeInfoType()));
DtoTypeInfoOf(e->loc, stripModifiers(taa), /*base=*/false);
LLValue *aa = gIR->CreateCallOrInvoke(func, aaTypeInfo, "aa");
result = new DImValue(e->type, aa);
}
@ -1821,8 +1805,7 @@ public:
getIRMangledFuncName("_D9invariant12_d_invariantFC6ObjectZv", LINK::d);
const auto fn = getRuntimeFunction(e->loc, gIR->module, fnMangle.c_str());
const auto arg =
DtoBitCast(DtoRVal(cond), fn->getFunctionType()->getParamType(0));
const auto arg = DtoRVal(cond);
gIR->CreateCallOrInvoke(fn, arg);
} else if (condty->ty == TY::Tpointer &&
@ -1965,32 +1948,27 @@ public:
e->func->toChars());
}
LLPointerType *int8ptrty = getPtrToType(LLType::getInt8Ty(gIR->context()));
assert(e->type->toBasetype()->ty == TY::Tdelegate);
LLType *dgty = DtoType(e->type);
DValue *u = toElem(e->e1);
LLValue *uval;
LLValue *contextptr;
if (DFuncValue *f = u->isFunc()) {
assert(f->func);
LLValue *contextptr = DtoNestedContext(e->loc, f->func);
uval = DtoBitCast(contextptr, getVoidPtrType());
contextptr = DtoNestedContext(e->loc, f->func);
} else {
uval = (DtoIsInMemoryOnly(u->type) ? DtoLVal(u) : DtoRVal(u));
contextptr = (DtoIsInMemoryOnly(u->type) ? DtoLVal(u) : DtoRVal(u));
}
IF_LOG Logger::cout() << "context = " << *uval << '\n';
LLValue *castcontext = DtoBitCast(uval, int8ptrty);
IF_LOG Logger::cout() << "context = " << *contextptr << '\n';
IF_LOG Logger::println("func: '%s'", e->func->toPrettyChars());
LLValue *castfptr;
LLValue *fptr;
if (e->e1->op != EXP::super_ && e->e1->op != EXP::dotType &&
e->func->isVirtual() && !e->func->isFinalFunc()) {
castfptr = DtoVirtualFunctionPointer(u, e->func).first;
fptr = DtoVirtualFunctionPointer(u, e->func).first;
} else if (e->func->isAbstract()) {
llvm_unreachable("Delegate to abstract method not implemented.");
} else if (e->func->toParent()->isInterfaceDeclaration()) {
@ -2010,13 +1988,11 @@ public:
}
}
castfptr = DtoCallee(e->func);
fptr = DtoCallee(e->func);
}
castfptr = DtoBitCast(castfptr, dgty->getContainedType(1));
result = new DImValue(
e->type, DtoAggrPair(DtoType(e->type), castcontext, castfptr, ".dg"));
e->type, DtoAggrPair(DtoType(e->type), contextptr, fptr, ".dg"));
}
//////////////////////////////////////////////////////////////////////////////
@ -2135,7 +2111,7 @@ public:
DValue *u = toElem(e->e1);
if (retPtr && u->type->toBasetype()->ty != TY::Tnoreturn) {
LLValue *lval = makeLValue(e->loc, u);
DtoStore(lval, DtoBitCast(retPtr, lval->getType()->getPointerTo()));
DtoStore(lval, retPtr);
}
llvm::BranchInst::Create(condend, p->scopebb());
@ -2143,7 +2119,7 @@ public:
DValue *v = toElem(e->e2);
if (retPtr && v->type->toBasetype()->ty != TY::Tnoreturn) {
LLValue *lval = makeLValue(e->loc, v);
DtoStore(lval, DtoBitCast(retPtr, lval->getType()->getPointerTo()));
DtoStore(lval, retPtr);
}
llvm::BranchInst::Create(condend, p->scopebb());
@ -2308,14 +2284,8 @@ public:
LLFunction *callee = DtoCallee(fd, false);
if (fd->isNested()) {
LLType *dgty = DtoType(e->type);
LLValue *cval = DtoNestedContext(e->loc, fd);
cval = DtoBitCast(cval, dgty->getContainedType(0));
LLValue *castfptr = DtoBitCast(callee, dgty->getContainedType(1));
result = new DImValue(e->type, DtoAggrPair(cval, castfptr, ".func"));
result = new DImValue(e->type, DtoAggrPair(cval, callee, ".func"));
} else {
result = new DFuncValue(e->type, fd, callee);
}
@ -2368,7 +2338,6 @@ public:
return;
}
storage = DtoBitCast(storage, llElemType->getPointerTo());
if (arrayType->ty == TY::Tarray) {
result = new DSliceValue(e->type, DtoConstSize_t(len), storage);
} else if (arrayType->ty == TY::Tpointer) {
@ -2385,15 +2354,12 @@ public:
auto global = new llvm::GlobalVariable(gIR->module, init->getType(), true,
llvm::GlobalValue::InternalLinkage,
init, ".immutablearray");
result = new DSliceValue(arrayType, DtoConstSize_t(len),
DtoBitCast(global, getPtrToType(llElemType)));
result = new DSliceValue(arrayType, DtoConstSize_t(len), global);
} else {
DSliceValue *dynSlice = DtoNewDynArray(
e->loc, arrayType,
new DConstValue(Type::tsize_t, DtoConstSize_t(len)), false);
initializeArrayLiteral(
p, e, DtoBitCast(dynSlice->getPtr(), getPtrToType(llStoType)),
llStoType);
initializeArrayLiteral(p, e, dynSlice->getPtr(), llStoType);
result = dynSlice;
}
}
@ -2417,7 +2383,6 @@ public:
DtoMemSetZero(DtoType(e->type), dstMem);
} else {
LLValue *initsym = getIrAggr(sd)->getInitSymbol();
initsym = DtoBitCast(initsym, DtoType(pointerTo(e->type)));
assert(dstMem->getType() == initsym->getType());
DtoMemCpy(DtoType(e->type), dstMem, initsym);
}
@ -2559,9 +2524,8 @@ public:
llvm::Function *func =
getRuntimeFunction(e->loc, gIR->module, "_d_assocarrayliteralTX");
LLFunctionType *funcTy = func->getFunctionType();
LLValue *aaTypeInfo = DtoBitCast(
DtoTypeInfoOf(e->loc, stripModifiers(aatype), /*base=*/false),
DtoType(getAssociativeArrayTypeInfoType()));
LLValue *aaTypeInfo =
DtoTypeInfoOf(e->loc, stripModifiers(aatype), /*base=*/false);
LLConstant *initval = arrayConst(keysInits, indexType);
LLConstant *globalstore = new LLGlobalVariable(
@ -2625,7 +2589,7 @@ public:
DValue * dv = toElem(exp->e1);
LLValue *val = makeLValue(exp->loc, dv);
LLValue *v = DtoGEP(DtoType(dv->type), val, 0, index);
return new DLValue(exp->type, DtoBitCast(v, DtoPtrToType(exp->type)));
return new DLValue(exp->type, v);
}
void visit(DelegatePtrExp *e) override {
@ -2849,10 +2813,9 @@ public:
// member, so we have to add an extra layer of indirection.
resultType = getInterfaceTypeInfoType();
LLType *pres = DtoType(pointerTo(resultType));
typinf = DtoLoad(pres, DtoBitCast(typinf, pres->getPointerTo()));
typinf = DtoLoad(pres, typinf);
} else {
resultType = getClassInfoType();
typinf = DtoBitCast(typinf, DtoType(pointerTo(resultType)));
}
result = new DLValue(resultType, typinf);

View file

@ -407,10 +407,6 @@ LLValue *DtoGEP1i64(LLType *pointeeTy, LLValue *ptr, uint64_t i0, const char *na
////////////////////////////////////////////////////////////////////////////////
void DtoMemSet(LLValue *dst, LLValue *val, LLValue *nbytes, unsigned align) {
LLType *VoidPtrTy = getVoidPtrType();
dst = DtoBitCast(dst, VoidPtrTy);
gIR->ir->CreateMemSet(dst, val, nbytes, llvm::MaybeAlign(align),
false /*isVolatile*/);
}
@ -429,11 +425,6 @@ void DtoMemSetZero(LLType *type, LLValue *dst, unsigned align) {
////////////////////////////////////////////////////////////////////////////////
void DtoMemCpy(LLValue *dst, LLValue *src, LLValue *nbytes, unsigned align) {
LLType *VoidPtrTy = getVoidPtrType();
dst = DtoBitCast(dst, VoidPtrTy);
src = DtoBitCast(src, VoidPtrTy);
auto A = llvm::MaybeAlign(align);
gIR->ir->CreateMemCpy(dst, A, src, A, nbytes, false /*isVolatile*/);
}
@ -459,9 +450,6 @@ LLValue *DtoMemCmp(LLValue *lhs, LLValue *rhs, LLValue *nbytes) {
&gIR->module);
}
lhs = DtoBitCast(lhs, VoidPtrTy);
rhs = DtoBitCast(rhs, VoidPtrTy);
return gIR->ir->CreateCall(fn, {lhs, rhs, nbytes});
}

View file

@ -270,8 +270,7 @@ void emitBeginCatchMSVC(IRState &irs, Catch *ctch,
if (!isCPPclass) {
auto enterCatchFn =
getRuntimeFunction(ctch->loc, irs.module, "_d_eh_enter_catch");
irs.CreateCallOrInvoke(enterCatchFn, DtoBitCast(exnObj, getVoidPtrType()),
clssInfo);
irs.CreateCallOrInvoke(enterCatchFn, exnObj, clssInfo);
}
}
}
@ -730,9 +729,8 @@ llvm::BasicBlock *TryCatchFinallyScopes::emitLandingPad() {
// "Call" llvm.eh.typeid.for, which gives us the eh selector value to
// compare the landing pad selector value with.
llvm::Value *ehTypeId =
irs.ir->CreateCall(GET_INTRINSIC_DECL(eh_typeid_for),
DtoBitCast(cb.classInfoPtr, getVoidPtrType()));
llvm::Value *ehTypeId = irs.ir->CreateCall(
GET_INTRINSIC_DECL(eh_typeid_for), cb.classInfoPtr);
// Compare the selector value from the unwinder against the expected
// one and branch accordingly.

View file

@ -196,7 +196,6 @@ LLConstant *IrClass::getVtblInit() {
if (!cd->isCPPclass()) {
if (!suppressTypeInfo()) {
c = getClassInfoSymbol();
c = DtoBitCast(c, voidPtrType);
} else {
// use null if there are no TypeInfos
c = llvm::Constant::getNullValue(voidPtrType);
@ -235,7 +234,7 @@ LLConstant *IrClass::getVtblInit() {
}
}
c = DtoBitCast(DtoCallee(fd), voidPtrType);
c = DtoCallee(fd);
if (cd->isFuncHidden(fd) && !fd->isFuture()) {
// fd is hidden from the view of this class. If fd overlaps with any
@ -381,7 +380,7 @@ LLConstant *IrClass::getClassInfoInit() {
if (isInterface) {
b.push_array(0, getNullValue(voidPtrPtr));
} else {
b.push_array(cd->vtbl.length, DtoBitCast(getVtblSymbol(), voidPtrPtr));
b.push_array(cd->vtbl.length, getVtblSymbol());
}
// Interface[] interfaces
@ -397,12 +396,12 @@ LLConstant *IrClass::getClassInfoInit() {
// void* destructor
assert(!isInterface || !cd->tidtor);
b.push_funcptr(cd->tidtor, Type::tvoidptr);
b.push_funcptr(cd->tidtor);
// void function(Object) classInvariant
assert(!isInterface || !cd->inv);
VarDeclaration *invVar = cinfo->fields[6];
b.push_funcptr(cd->inv, invVar->type);
b.push_funcptr(cd->inv);
// ClassFlags m_flags
const auto flags = buildClassinfoFlags(cd);
@ -430,7 +429,7 @@ LLConstant *IrClass::getClassInfoInit() {
defConstructor = nullptr;
}
assert(!isInterface || !defConstructor);
b.push_funcptr(defConstructor, defConstructorVar->type);
b.push_funcptr(defConstructor);
// immutable(void)* m_RTInfo
if (cd->getRTInfo) {
@ -546,7 +545,7 @@ LLConstant *IrClass::getInterfaceVtblInit(BaseClass *b,
llvm::Constant *c = llvm::ConstantExpr::getGetElementPtr(
interfaceInfosZ->getValueType(), interfaceInfosZ, idxs, true);
constants.push_back(DtoBitCast(c, voidPtrTy));
constants.push_back(c);
} else {
// use null if there are no TypeInfos
constants.push_back(llvm::Constant::getNullValue(voidPtrTy));
@ -579,7 +578,7 @@ LLConstant *IrClass::getInterfaceVtblInit(BaseClass *b,
if (fd->interfaceVirtual)
thunkOffset -= fd->interfaceVirtual->offset;
if (thunkOffset == 0) {
constants.push_back(DtoBitCast(irFunc->getLLVMCallee(), voidPtrTy));
constants.push_back(irFunc->getLLVMCallee());
continue;
}
@ -656,10 +655,7 @@ LLConstant *IrClass::getInterfaceVtblInit(BaseClass *b,
? 0
: 1;
LLValue *&thisArg = args[thisArgIndex];
LLType *targetThisType = thisArg->getType();
thisArg = DtoBitCast(thisArg, getVoidPtrType());
thisArg = DtoGEP1(LLType::getInt8Ty(gIR->context()), thisArg, DtoConstInt(-thunkOffset));
thisArg = DtoBitCast(thisArg, targetThisType);
thisArg = DtoGEP1(getI8Type(), thisArg, DtoConstInt(-thunkOffset));
// all calls that might be subject to inlining into a caller with debug
// info should have debug info, too
@ -682,7 +678,7 @@ LLConstant *IrClass::getInterfaceVtblInit(BaseClass *b,
gIR->funcGenStates.pop_back();
}
constants.push_back(DtoBitCast(thunk, voidPtrTy));
constants.push_back(thunk);
}
// build the vtbl constant
@ -734,8 +730,6 @@ LLConstant *IrClass::getClassInfoInterfaces() {
LLSmallVector<LLConstant *, 6> constants;
constants.reserve(cd->vtblInterfaces->length);
LLType *classinfo_type = DtoType(getClassInfoType());
LLType *voidptrptr_type = DtoType(pointerTo(pointerTo(Type::tvoid)));
LLStructType *interface_type =
isaStruct(DtoType(interfacesArrayType->nextOf()));
assert(interface_type);
@ -752,16 +746,14 @@ LLConstant *IrClass::getClassInfoInterfaces() {
// classinfo
LLConstant *ci = irinter->getClassInfoSymbol();
ci = DtoBitCast(ci, classinfo_type);
// vtbl
LLConstant *vtb;
// interface get a null
if (cd->isInterfaceDeclaration()) {
vtb = DtoConstSlice(DtoConstSize_t(0), getNullValue(voidptrptr_type));
vtb = DtoConstSlice(DtoConstSize_t(0), getNullValue(getVoidPtrType()));
} else {
vtb = getInterfaceVtblSymbol(it, i);
vtb = DtoBitCast(vtb, voidptrptr_type);
auto vtblSize = itc->getVtblType()->getNumContainedTypes();
vtb = DtoConstSlice(DtoConstSize_t(vtblSize), vtb);
}