Revise DtoGEP() helpers and mark most GEPs inbounds

This commit is contained in:
Martin 2015-12-13 14:10:41 +01:00
parent 5efb6bd1eb
commit 956061c3c7
8 changed files with 53 additions and 81 deletions

View file

@ -167,7 +167,7 @@ static void DtoArrayInit(Loc &loc, LLValue *ptr, LLValue *length,
LLValue *itr_val = DtoLoad(itr);
// assign array element value
DValue *arrayelem = new DVarValue(
dvalue->type->toBasetype(), DtoGEP1(ptr, itr_val, "arrayinit.arrayelem"));
dvalue->type->toBasetype(), DtoGEP1(ptr, itr_val, true, "arrayinit.arrayelem"));
DtoAssign(loc, arrayelem, dvalue, op);
// increment iterator
@ -761,7 +761,7 @@ void DtoCatAssignElement(Loc &loc, Type *arrayType, DValue *array,
appendedArray = DtoAggrPaint(appendedArray, DtoType(arrayType));
LLValue *val = DtoArrayPtr(array);
val = DtoGEP1(val, oldLength, ".lastElem");
val = DtoGEP1(val, oldLength, true, ".lastElem");
DtoAssign(loc, new DVarValue(arrayType->nextOf(), val), expVal, TOKblit);
callPostblit(loc, exp, val);
}

View file

@ -139,9 +139,9 @@ void DtoGetComplexParts(Loc &loc, Type *to, DValue *val, DValue *&re,
if (to->iscomplex()) {
if (v->isLVal()) {
LLValue *reVal =
DtoGEP(v->getLVal(), DtoConstInt(0), DtoConstInt(0), ".re_part");
DtoGEPi(v->getLVal(), 0, 0, ".re_part");
LLValue *imVal =
DtoGEP(v->getLVal(), DtoConstInt(0), DtoConstInt(1), ".im_part");
DtoGEPi(v->getLVal(), 0, 1, ".im_part");
re = new DVarValue(baserety, reVal);
im = new DVarValue(baseimty, imVal);
} else {

View file

@ -1218,7 +1218,7 @@ public:
// get value for this iteration
LLValue *loadedKey = irs->ir->CreateLoad(keyvar);
LLValue *gep = DtoGEP1(val, loadedKey);
LLValue *gep = DtoGEP1(val, loadedKey, true);
if (!stmt->value->isRef() && !stmt->value->isOut()) {
// Copy value to local variable, and use it as the value variable.

View file

@ -531,7 +531,7 @@ bool DtoLowerMagicIntrinsic(IRState *p, FuncDeclaration *fndecl, CallExp *e,
assert(bitmask == 31 || bitmask == 63);
// auto q = cast(size_t*)ptr + (bitnum >> (64bit ? 6 : 5));
LLValue *q = DtoBitCast(ptr, DtoSize_t()->getPointerTo());
q = DtoGEP1(q, p->ir->CreateLShr(bitnum, bitmask == 63 ? 6 : 5), "bitop.q");
q = DtoGEP1(q, p->ir->CreateLShr(bitnum, bitmask == 63 ? 6 : 5), true, "bitop.q");
// auto mask = 1 << (bitnum & bitmask);
LLValue *mask =

View file

@ -739,8 +739,8 @@ public:
if (negateOffset) {
noStrideInc = p->ir->CreateNeg(noStrideInc);
}
return new DImValue(
base->type, DtoGEP1(base->getRVal(), noStrideInc, "", p->scopebb()));
return new DImValue(base->type,
DtoGEP1(base->getRVal(), noStrideInc, false));
}
// This might not actually be generated by the frontend, just to be
@ -750,7 +750,7 @@ public:
inc = p->ir->CreateNeg(inc);
}
llvm::Value *bytePtr = DtoBitCast(base->getRVal(), getVoidPtrType());
DValue *result = new DImValue(Type::tvoidptr, DtoGEP1(bytePtr, inc));
DValue *result = new DImValue(Type::tvoidptr, DtoGEP1(bytePtr, inc, false));
return DtoCast(loc, result, resultType);
}
@ -1280,22 +1280,20 @@ public:
DValue *r = toElem(e->e2);
p->arrays.pop_back();
LLValue *zero = DtoConstUint(0);
LLValue *arrptr = nullptr;
if (e1type->ty == Tpointer) {
arrptr = DtoGEP1(l->getRVal(), r->getRVal());
arrptr = DtoGEP1(l->getRVal(), r->getRVal(), false);
} else if (e1type->ty == Tsarray) {
if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) {
DtoIndexBoundsCheck(e->loc, l, r);
}
arrptr = DtoGEP(l->getRVal(), zero, r->getRVal());
arrptr = DtoGEP(l->getRVal(), DtoConstUint(0), r->getRVal(),
e->indexIsInBounds);
} else if (e1type->ty == Tarray) {
if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) {
DtoIndexBoundsCheck(e->loc, l, r);
}
arrptr = DtoArrayPtr(l);
arrptr = DtoGEP1(arrptr, r->getRVal());
arrptr = DtoGEP1(DtoArrayPtr(l), r->getRVal(), e->indexIsInBounds);
} else if (e1type->ty == Taarray) {
result = DtoAAIndex(e->loc, e->type, l, r, e->modifiable);
return;
@ -1382,7 +1380,7 @@ public:
}
// offset by lower
eptr = DtoGEP1(eptr, vlo, "lowerbound");
eptr = DtoGEP1(eptr, vlo, !needCheckLower, "lowerbound");
// adjust length
elen = p->ir->CreateSub(vup, vlo);
@ -1637,19 +1635,9 @@ public:
}
} else if (e1type->ty == Tpointer) {
assert(e->e2->op == TOKint64);
LLConstant *offset;
if (e->op == TOKplusplus) {
offset =
LLConstantInt::get(DtoSize_t(), static_cast<uint64_t>(1), false);
} else {
offset =
LLConstantInt::get(DtoSize_t(), static_cast<uint64_t>(-1), true);
}
post = llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
isaPointer(val)->getElementType(),
#endif
val, offset, "", p->scopebb());
LLConstant *offset =
e->op == TOKplusplus ? DtoConstUint(1) : DtoConstInt(-1);
post = DtoGEP1(val, offset, false, "", p->scopebb());
} else if (e1type->isfloating()) {
assert(e2type->isfloating());
LLValue *one = DtoConstFP(e1type, ldouble(1.0));
@ -2668,8 +2656,8 @@ public:
Type *indexType = static_cast<TypeAArray *>(aatype)->index;
assert(indexType && vtype);
llvm::Function *func = getRuntimeFunction(
e->loc, gIR->module, "_d_assocarrayliteralTX");
llvm::Function *func =
getRuntimeFunction(e->loc, gIR->module, "_d_assocarrayliteralTX");
LLFunctionType *funcTy = func->getFunctionType();
LLValue *aaTypeInfo =
DtoBitCast(DtoTypeInfoOf(stripModifiers(aatype)),

View file

@ -257,69 +257,53 @@ LLIntegerType *DtoSize_t() {
////////////////////////////////////////////////////////////////////////////////
LLValue *DtoGEP1(LLValue *ptr, LLValue *i0, const char *var,
namespace {
llvm::GetElementPtrInst *DtoGEP(LLValue *ptr, llvm::ArrayRef<LLValue *> indices,
bool inBounds, const char *name,
llvm::BasicBlock *bb) {
LLPointerType *p = isaPointer(ptr);
assert(p && "GEP expects a pointer type");
return llvm::GetElementPtrInst::Create(
auto gep = llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
p->getElementType(),
#endif
ptr, i0, var, bb ? bb : gIR->scopebb());
ptr, indices, name, bb ? bb : gIR->scopebb());
gep->setIsInBounds(inBounds);
return gep;
}
}
////////////////////////////////////////////////////////////////////////////////
LLValue *DtoGEP(LLValue *ptr, LLValue *i0, LLValue *i1, const char *var,
LLValue *DtoGEP1(LLValue *ptr, LLValue *i0, bool inBounds, const char *name,
llvm::BasicBlock *bb) {
LLPointerType *p = isaPointer(ptr);
assert(p && "GEP expects a pointer type");
LLValue *v[] = {i0, i1};
return llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
p->getElementType(),
#endif
ptr, v, var, bb ? bb : gIR->scopebb());
return DtoGEP(ptr, i0, inBounds, name, bb);
}
////////////////////////////////////////////////////////////////////////////////
LLValue *DtoGEP(LLValue *ptr, LLValue *i0, LLValue *i1, bool inBounds,
const char *name, llvm::BasicBlock *bb) {
LLValue *indices[] = {i0, i1};
return DtoGEP(ptr, indices, inBounds, name, bb);
}
LLValue *DtoGEPi1(LLValue *ptr, unsigned i, const char *var,
LLValue *DtoGEPi1(LLValue *ptr, unsigned i0, const char *name,
llvm::BasicBlock *bb) {
LLPointerType *p = isaPointer(ptr);
assert(p && "GEP expects a pointer type");
return llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
p->getElementType(),
#endif
ptr, DtoConstUint(i), var, bb ? bb : gIR->scopebb());
return DtoGEP(ptr, DtoConstUint(i0), /* inBounds = */ true, name, bb);
}
////////////////////////////////////////////////////////////////////////////////
LLValue *DtoGEPi(LLValue *ptr, unsigned i0, unsigned i1, const char *var,
LLValue *DtoGEPi(LLValue *ptr, unsigned i0, unsigned i1, const char *name,
llvm::BasicBlock *bb) {
LLPointerType *p = isaPointer(ptr);
assert(p && "GEP expects a pointer type");
LLValue *v[] = {DtoConstUint(i0), DtoConstUint(i1)};
return llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
p->getElementType(),
#endif
ptr, v, var, bb ? bb : gIR->scopebb());
LLValue *indices[] = {DtoConstUint(i0), DtoConstUint(i1)};
return DtoGEP(ptr, indices, /* inBounds = */ true, name, bb);
}
////////////////////////////////////////////////////////////////////////////////
LLConstant *DtoGEPi(LLConstant *ptr, unsigned i0, unsigned i1) {
LLPointerType *p = isaPointer(ptr);
assert(p && "GEP expects a pointer type");
LLValue *v[] = {DtoConstUint(i0), DtoConstUint(i1)};
LLValue *indices[] = {DtoConstUint(i0), DtoConstUint(i1)};
return llvm::ConstantExpr::getGetElementPtr(
#if LDC_LLVM_VER >= 307
p->getElementType(),
#endif
ptr, v, true);
ptr, indices, /* InBounds = */ true);
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -71,10 +71,10 @@ LLStructType *DtoMutexType();
LLStructType *DtoModuleReferenceType();
// getelementptr helpers
LLValue *DtoGEP1(LLValue *ptr, LLValue *i0, const char *name = "",
llvm::BasicBlock *bb = nullptr);
LLValue *DtoGEP(LLValue *ptr, LLValue *i0, LLValue *i1, const char *name = "",
llvm::BasicBlock *bb = nullptr);
LLValue *DtoGEP1(LLValue *ptr, LLValue *i0, bool inBounds,
const char *name = "", llvm::BasicBlock *bb = nullptr);
LLValue *DtoGEP(LLValue *ptr, LLValue *i0, LLValue *i1, bool inBounds,
const char *name = "", llvm::BasicBlock *bb = nullptr);
LLValue *DtoGEPi1(LLValue *ptr, unsigned i0, const char *name = "",
llvm::BasicBlock *bb = nullptr);

View file

@ -373,7 +373,7 @@ llvm::GlobalVariable *IrAggr::getInterfaceVtbl(BaseClass *b, bool new_instance,
: 1];
LLType *targetThisType = thisArg->getType();
thisArg = DtoBitCast(thisArg, getVoidPtrType());
thisArg = DtoGEP1(thisArg, DtoConstInt(-b->offset));
thisArg = DtoGEP1(thisArg, DtoConstInt(-b->offset), true);
thisArg = DtoBitCast(thisArg, targetThisType);
// call the real vtbl function.