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

View file

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

View file

@ -1218,7 +1218,7 @@ public:
// get value for this iteration // get value for this iteration
LLValue *loadedKey = irs->ir->CreateLoad(keyvar); LLValue *loadedKey = irs->ir->CreateLoad(keyvar);
LLValue *gep = DtoGEP1(val, loadedKey); LLValue *gep = DtoGEP1(val, loadedKey, true);
if (!stmt->value->isRef() && !stmt->value->isOut()) { if (!stmt->value->isRef() && !stmt->value->isOut()) {
// Copy value to local variable, and use it as the value variable. // 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); assert(bitmask == 31 || bitmask == 63);
// auto q = cast(size_t*)ptr + (bitnum >> (64bit ? 6 : 5)); // auto q = cast(size_t*)ptr + (bitnum >> (64bit ? 6 : 5));
LLValue *q = DtoBitCast(ptr, DtoSize_t()->getPointerTo()); 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); // auto mask = 1 << (bitnum & bitmask);
LLValue *mask = LLValue *mask =

View file

@ -739,8 +739,8 @@ public:
if (negateOffset) { if (negateOffset) {
noStrideInc = p->ir->CreateNeg(noStrideInc); noStrideInc = p->ir->CreateNeg(noStrideInc);
} }
return new DImValue( return new DImValue(base->type,
base->type, DtoGEP1(base->getRVal(), noStrideInc, "", p->scopebb())); DtoGEP1(base->getRVal(), noStrideInc, false));
} }
// This might not actually be generated by the frontend, just to be // This might not actually be generated by the frontend, just to be
@ -750,7 +750,7 @@ public:
inc = p->ir->CreateNeg(inc); inc = p->ir->CreateNeg(inc);
} }
llvm::Value *bytePtr = DtoBitCast(base->getRVal(), getVoidPtrType()); 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); return DtoCast(loc, result, resultType);
} }
@ -1280,22 +1280,20 @@ public:
DValue *r = toElem(e->e2); DValue *r = toElem(e->e2);
p->arrays.pop_back(); p->arrays.pop_back();
LLValue *zero = DtoConstUint(0);
LLValue *arrptr = nullptr; LLValue *arrptr = nullptr;
if (e1type->ty == Tpointer) { if (e1type->ty == Tpointer) {
arrptr = DtoGEP1(l->getRVal(), r->getRVal()); arrptr = DtoGEP1(l->getRVal(), r->getRVal(), false);
} else if (e1type->ty == Tsarray) { } else if (e1type->ty == Tsarray) {
if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) { if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) {
DtoIndexBoundsCheck(e->loc, l, r); 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) { } else if (e1type->ty == Tarray) {
if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) { if (p->emitArrayBoundsChecks() && !e->indexIsInBounds) {
DtoIndexBoundsCheck(e->loc, l, r); DtoIndexBoundsCheck(e->loc, l, r);
} }
arrptr = DtoArrayPtr(l); arrptr = DtoGEP1(DtoArrayPtr(l), r->getRVal(), e->indexIsInBounds);
arrptr = DtoGEP1(arrptr, r->getRVal());
} else if (e1type->ty == Taarray) { } else if (e1type->ty == Taarray) {
result = DtoAAIndex(e->loc, e->type, l, r, e->modifiable); result = DtoAAIndex(e->loc, e->type, l, r, e->modifiable);
return; return;
@ -1382,7 +1380,7 @@ public:
} }
// offset by lower // offset by lower
eptr = DtoGEP1(eptr, vlo, "lowerbound"); eptr = DtoGEP1(eptr, vlo, !needCheckLower, "lowerbound");
// adjust length // adjust length
elen = p->ir->CreateSub(vup, vlo); elen = p->ir->CreateSub(vup, vlo);
@ -1637,19 +1635,9 @@ public:
} }
} else if (e1type->ty == Tpointer) { } else if (e1type->ty == Tpointer) {
assert(e->e2->op == TOKint64); assert(e->e2->op == TOKint64);
LLConstant *offset; LLConstant *offset =
if (e->op == TOKplusplus) { e->op == TOKplusplus ? DtoConstUint(1) : DtoConstInt(-1);
offset = post = DtoGEP1(val, offset, false, "", p->scopebb());
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());
} else if (e1type->isfloating()) { } else if (e1type->isfloating()) {
assert(e2type->isfloating()); assert(e2type->isfloating());
LLValue *one = DtoConstFP(e1type, ldouble(1.0)); LLValue *one = DtoConstFP(e1type, ldouble(1.0));
@ -2668,8 +2656,8 @@ public:
Type *indexType = static_cast<TypeAArray *>(aatype)->index; Type *indexType = static_cast<TypeAArray *>(aatype)->index;
assert(indexType && vtype); assert(indexType && vtype);
llvm::Function *func = getRuntimeFunction( llvm::Function *func =
e->loc, gIR->module, "_d_assocarrayliteralTX"); getRuntimeFunction(e->loc, gIR->module, "_d_assocarrayliteralTX");
LLFunctionType *funcTy = func->getFunctionType(); LLFunctionType *funcTy = func->getFunctionType();
LLValue *aaTypeInfo = LLValue *aaTypeInfo =
DtoBitCast(DtoTypeInfoOf(stripModifiers(aatype)), 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");
auto gep = llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
p->getElementType(),
#endif
ptr, indices, name, bb ? bb : gIR->scopebb());
gep->setIsInBounds(inBounds);
return gep;
}
}
LLValue *DtoGEP1(LLValue *ptr, LLValue *i0, bool inBounds, const char *name,
llvm::BasicBlock *bb) { llvm::BasicBlock *bb) {
LLPointerType *p = isaPointer(ptr); return DtoGEP(ptr, i0, inBounds, name, bb);
assert(p && "GEP expects a pointer type");
return llvm::GetElementPtrInst::Create(
#if LDC_LLVM_VER >= 307
p->getElementType(),
#endif
ptr, i0, var, bb ? bb : gIR->scopebb());
} }
//////////////////////////////////////////////////////////////////////////////// LLValue *DtoGEP(LLValue *ptr, LLValue *i0, LLValue *i1, bool inBounds,
const char *name, llvm::BasicBlock *bb) {
LLValue *DtoGEP(LLValue *ptr, LLValue *i0, LLValue *i1, const char *var, LLValue *indices[] = {i0, i1};
llvm::BasicBlock *bb) { return DtoGEP(ptr, indices, inBounds, name, 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());
} }
//////////////////////////////////////////////////////////////////////////////// LLValue *DtoGEPi1(LLValue *ptr, unsigned i0, const char *name,
LLValue *DtoGEPi1(LLValue *ptr, unsigned i, const char *var,
llvm::BasicBlock *bb) { llvm::BasicBlock *bb) {
LLPointerType *p = isaPointer(ptr); return DtoGEP(ptr, DtoConstUint(i0), /* inBounds = */ true, name, bb);
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());
} }
//////////////////////////////////////////////////////////////////////////////// LLValue *DtoGEPi(LLValue *ptr, unsigned i0, unsigned i1, const char *name,
LLValue *DtoGEPi(LLValue *ptr, unsigned i0, unsigned i1, const char *var,
llvm::BasicBlock *bb) { llvm::BasicBlock *bb) {
LLPointerType *p = isaPointer(ptr); LLValue *indices[] = {DtoConstUint(i0), DtoConstUint(i1)};
assert(p && "GEP expects a pointer type"); return DtoGEP(ptr, indices, /* inBounds = */ true, name, bb);
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());
} }
////////////////////////////////////////////////////////////////////////////////
LLConstant *DtoGEPi(LLConstant *ptr, unsigned i0, unsigned i1) { LLConstant *DtoGEPi(LLConstant *ptr, unsigned i0, unsigned i1) {
LLPointerType *p = isaPointer(ptr); LLPointerType *p = isaPointer(ptr);
assert(p && "GEP expects a pointer type"); assert(p && "GEP expects a pointer type");
LLValue *v[] = {DtoConstUint(i0), DtoConstUint(i1)}; LLValue *indices[] = {DtoConstUint(i0), DtoConstUint(i1)};
return llvm::ConstantExpr::getGetElementPtr( return llvm::ConstantExpr::getGetElementPtr(
#if LDC_LLVM_VER >= 307 #if LDC_LLVM_VER >= 307
p->getElementType(), p->getElementType(),
#endif #endif
ptr, v, true); ptr, indices, /* InBounds = */ true);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

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

View file

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