mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-04-28 22:21:31 +03:00
Skip superfluous IR pointer bitcasts, now that they are always opaque
This commit is contained in:
parent
ee9f3a142c
commit
d140f2a283
28 changed files with 182 additions and 399 deletions
45
gen/aa.cpp
45
gen/aa.cpp
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
109
gen/toir.cpp
109
gen/toir.cpp
|
@ -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);
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue