Fix regression for LDC-specific elide-scope-class-finalization optimization

`NewExp.type` can apparently newly be a yet-unresolved `TypeIdentifier`.
Resolve it in that case to a `TypeClass` now.

Also defer the has-dtor check for the whole class hierarchy of the
*dynamic* type from that LDC-specific frontend addition to the glue
layer, as I'm not sure we can rely on `ClassDeclaration.dtor` having
been set at that time already.

I've chosen to keep storing a single extra LDC-specific *bit*
(`onstackWithMatchingDynType`) instead of storing the full dynamic
class type. While this slightly weakens the optimization (no
optimization for non-equivalent static/dynamic class types anymore),
it doesn't increase the AST node size. And I think almost all cases
use an equivalent type anyway (e.g., the DMD frontend itself only uses
`scope` class allocations with equivalent types).
This commit is contained in:
Martin Kinkelin 2023-01-21 17:31:49 +01:00
parent 3541eaa03b
commit 153f8ccdce
7 changed files with 82 additions and 28 deletions

View file

@ -187,9 +187,25 @@ void DtoFinalizeClass(const Loc &loc, LLValue *inst) {
////////////////////////////////////////////////////////////////////////////////
void DtoFinalizeScopeClass(const Loc &loc, DValue* dval, bool hasDtor) {
llvm::Value* inst = DtoRVal(dval);
if (!isOptimizationEnabled() || hasDtor) {
void DtoFinalizeScopeClass(const Loc &loc, DValue *dval,
bool dynTypeMatchesStaticType) {
llvm::Value *inst = DtoRVal(dval);
if (!isOptimizationEnabled() || !dynTypeMatchesStaticType) {
DtoFinalizeClass(loc, inst);
return;
}
bool hasDtor = false;
auto cd = dval->type->toBasetype()->isTypeClass()->sym;
for (; cd; cd = cd->baseClass) {
if (cd->dtor) {
hasDtor = true;
break;
}
}
if (hasDtor) {
DtoFinalizeClass(loc, inst);
return;
}
@ -199,9 +215,10 @@ void DtoFinalizeScopeClass(const Loc &loc, DValue* dval, bool hasDtor) {
llvm::BasicBlock *ifbb = gIR->insertBB("if");
llvm::BasicBlock *endbb = gIR->insertBBAfter(ifbb, "endif");
llvm::StructType *st = getIrAggr(static_cast<TypeClass *>(dval->type)->sym)
->getLLStructType();
const auto monitor = DtoLoad(st->getElementType(1), DtoGEP(st, inst, 0, 1), ".monitor");
llvm::StructType *st =
getIrAggr(static_cast<TypeClass *>(dval->type)->sym)->getLLStructType();
const auto monitor =
DtoLoad(st->getElementType(1), DtoGEP(st, inst, 0, 1), ".monitor");
const auto hasMonitor =
gIR->ir->CreateICmp(llvm::CmpInst::ICMP_NE, monitor,
getNullValue(monitor->getType()), ".hasMonitor");