toconstelem.cpp (ldc-1.32.0) | : | toconstelem.cpp (ldc-1.32.1) | ||
---|---|---|---|---|
skipping to change at line 190 | skipping to change at line 190 | |||
LLConstant *clen = | LLConstant *clen = | |||
LLConstantInt::get(DtoSize_t(), e->numberOfCodeUnits(), false); | LLConstantInt::get(DtoSize_t(), e->numberOfCodeUnits(), false); | |||
result = DtoConstSlice(clen, arrptr, e->type); | result = DtoConstSlice(clen, arrptr, e->type); | |||
} else { | } else { | |||
llvm_unreachable("Unknown type for StringExp."); | llvm_unreachable("Unknown type for StringExp."); | |||
} | } | |||
} | } | |||
////////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////////// | |||
// very similar to emitPointerOffset() in binops.cpp | ||||
LLConstant *tryEmitPointerOffset(BinExp *e, bool negateOffset) { | ||||
Type *t1b = e->e1->type->toBasetype(); | ||||
if (t1b->ty != TY::Tpointer || !e->e2->type->isintegral()) | ||||
return nullptr; | ||||
Type *const pointeeType = t1b->nextOf(); | ||||
LLConstant *llBase = toConstElem(e->e1, p); | ||||
const dinteger_t byteOffset = e->e2->toInteger(); | ||||
LLConstant *llResult = nullptr; | ||||
const auto pointeeSize = pointeeType->size(e->loc); | ||||
if (pointeeSize && byteOffset % pointeeSize == 0) { // can do a nice GEP | ||||
LLConstant *llOffset = DtoConstSize_t(byteOffset / pointeeSize); | ||||
if (negateOffset) | ||||
llOffset = llvm::ConstantExpr::getNeg(llOffset); | ||||
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); | ||||
llResult = | ||||
llvm::ConstantExpr::getGetElementPtr(getI8Type(), llBase, llOffset); | ||||
} | ||||
return DtoBitCast(llResult, DtoType(e->type)); | ||||
} | ||||
void visit(AddExp *e) override { | void visit(AddExp *e) override { | |||
IF_LOG Logger::print("AddExp::toConstElem: %s @ %s\n", e->toChars(), | IF_LOG Logger::print("AddExp::toConstElem: %s @ %s\n", e->toChars(), | |||
e->type->toChars()); | e->type->toChars()); | |||
LOG_SCOPE; | LOG_SCOPE; | |||
// add to pointer | // add to pointer | |||
Type *t1b = e->e1->type->toBasetype(); | if (auto r = tryEmitPointerOffset(e, false)) { | |||
if (t1b->ty == TY::Tpointer && e->e2->type->isintegral()) { | result = r; | |||
llvm::Constant *ptr = toConstElem(e->e1, p); | ||||
dinteger_t idx = undoStrideMul(e->loc, t1b, e->e2->toInteger()); | ||||
result = llvm::ConstantExpr::getGetElementPtr(DtoType(e->e1->type), ptr, | ||||
DtoConstSize_t(idx)); | ||||
return; | return; | |||
} | } | |||
visit(static_cast<Expression *>(e)); | visit(static_cast<Expression *>(e)); | |||
} | } | |||
void visit(MinExp *e) override { | void visit(MinExp *e) override { | |||
IF_LOG Logger::print("MinExp::toConstElem: %s @ %s\n", e->toChars(), | IF_LOG Logger::print("MinExp::toConstElem: %s @ %s\n", e->toChars(), | |||
e->type->toChars()); | e->type->toChars()); | |||
LOG_SCOPE; | LOG_SCOPE; | |||
Type *t1b = e->e1->type->toBasetype(); | // subtract from pointer | |||
if (t1b->ty == TY::Tpointer && e->e2->type->isintegral()) { | if (auto r = tryEmitPointerOffset(e, true)) { | |||
llvm::Constant *ptr = toConstElem(e->e1, p); | result = r; | |||
dinteger_t idx = undoStrideMul(e->loc, t1b, e->e2->toInteger()); | ||||
llvm::Constant *negIdx = llvm::ConstantExpr::getNeg(DtoConstSize_t(idx)); | ||||
result = llvm::ConstantExpr::getGetElementPtr(DtoType(e->e1->type), ptr, | ||||
negIdx); | ||||
return; | return; | |||
} | } | |||
visit(static_cast<Expression *>(e)); | visit(static_cast<Expression *>(e)); | |||
} | } | |||
////////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////////// | |||
void visit(SliceExp *e) override { | void visit(SliceExp *e) override { | |||
IF_LOG Logger::print("SliceExp::toConstElem: %s @ %s\n", e->toChars(), | IF_LOG Logger::print("SliceExp::toConstElem: %s @ %s\n", e->toChars(), | |||
End of changes. 3 change blocks. | ||||
14 lines changed or deleted | 36 lines changed or added |