mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00
Revise DtoGEP() helpers and mark most GEPs inbounds
This commit is contained in:
parent
5efb6bd1eb
commit
956061c3c7
8 changed files with 53 additions and 81 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
38
gen/toir.cpp
38
gen/toir.cpp
|
@ -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)),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue