Implement -femit-local-var-lifetime which adds local (stack) variable… (#4395)

Implement -femit-local-var-lifetime which adds local (stack) variable lifetime annotation to LLVM IR, which enables sharing stack space for variables whose lifetimes do not overlap.
Resolves issue #2227

This is not enabled by default yet, to prevent miscompilation due to bugs (should be enabled in future for optimization levels > 0, and when sanitizers are enabled).
This commit is contained in:
Johan Engelen 2023-06-02 00:45:56 +02:00 committed by GitHub
parent 89cbc4cceb
commit ef0719f36b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 357 additions and 6 deletions

View file

@ -919,19 +919,29 @@ void DtoVarDeclaration(VarDeclaration *vd) {
Type *type = isSpecialRefVar(vd) ? vd->type->pointerTo() : vd->type;
llvm::Value *allocainst;
bool isRealAlloca = false;
LLType *lltype = DtoType(type); // void for noreturn
if (lltype->isVoidTy() || gDataLayout->getTypeSizeInBits(lltype) == 0) {
allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
} else if (type != vd->type) {
allocainst = DtoAlloca(type, vd->toChars());
isRealAlloca = true;
} else {
allocainst = DtoAlloca(vd, vd->toChars());
isRealAlloca = true;
}
irLocal->value = allocainst;
if (!lltype->isVoidTy())
gIR->DBuilder.EmitLocalVariable(allocainst, vd);
// Lifetime annotation is only valid on alloca.
if (isRealAlloca) {
// The lifetime of a stack variable starts from the point it is declared
gIR->funcGen().localVariableLifetimeAnnotator.addLocalVariable(
allocainst, DtoConstUlong(type->size()));
}
}
IF_LOG Logger::cout() << "llvm value for decl: " << *getIrLocal(vd)->value