[IRGen] Pack metadata may be alloc'd for layouts.

Previously, mayRequirePackMetadata only considered whether a type
involved a pack.  That failed to account for the case of outlined value
functions that require pack metadata when the type involves a pack in
its layout.  Here, mayRequirePackMetadata now considers also whether the
layout corresponding to a type involves a pack.

rdar://119829826
This commit is contained in:
Nate Chandler
2024-01-02 10:43:57 -08:00
parent 75b270791b
commit 73d68a3f28
5 changed files with 122 additions and 13 deletions

View File

@@ -1301,7 +1301,11 @@ bool SILInstruction::isDeallocatingStack() const {
return false;
}
bool SILInstruction::mayRequirePackMetadata() const {
static bool typeOrLayoutInvolvesPack(SILType ty, SILFunction const &F) {
return ty.hasAnyPack() || ty.isOrContainsPack(F);
}
bool SILInstruction::mayRequirePackMetadata(SILFunction const &F) const {
switch (getKind()) {
case SILInstructionKind::AllocPackInst:
case SILInstructionKind::TuplePackElementAddrInst:
@@ -1313,11 +1317,11 @@ bool SILInstruction::mayRequirePackMetadata() const {
case SILInstructionKind::TryApplyInst: {
// Check the function type for packs.
auto apply = ApplySite::isa(const_cast<SILInstruction *>(this));
if (apply.getCallee()->getType().hasAnyPack())
if (typeOrLayoutInvolvesPack(apply.getCallee()->getType(), F))
return true;
// Check the substituted types for packs.
for (auto ty : apply.getSubstitutionMap().getReplacementTypes()) {
if (ty->hasAnyPack())
if (typeOrLayoutInvolvesPack(F.getTypeLowering(ty).getLoweredType(), F))
return true;
}
return false;
@@ -1328,20 +1332,20 @@ bool SILInstruction::mayRequirePackMetadata() const {
case SILInstructionKind::DestroyValueInst:
// Unary instructions.
{
return getOperand(0)->getType().hasAnyPack();
return typeOrLayoutInvolvesPack(getOperand(0)->getType(), F);
}
case SILInstructionKind::AllocStackInst: {
auto *asi = cast<AllocStackInst>(this);
return asi->getType().hasAnyPack();
return typeOrLayoutInvolvesPack(asi->getType(), F);
}
case SILInstructionKind::MetatypeInst: {
auto *mi = cast<MetatypeInst>(this);
return mi->getType().hasAnyPack();
return typeOrLayoutInvolvesPack(mi->getType(), F);
}
case SILInstructionKind::WitnessMethodInst: {
auto *wmi = cast<WitnessMethodInst>(this);
auto ty = wmi->getLookupType();
return ty->hasAnyPack();
return typeOrLayoutInvolvesPack(F.getTypeLowering(ty).getLoweredType(), F);
}
default:
// Instructions that deallocate stack must not result in pack metadata
@@ -1359,15 +1363,15 @@ bool SILInstruction::mayRequirePackMetadata() const {
// Check results and operands for packs. If a pack appears, lowering the
// instruction might result in pack metadata emission.
for (auto result : getResults()) {
if (result->getType().hasAnyPack())
if (typeOrLayoutInvolvesPack(result->getType(), F))
return true;
}
for (auto operandTy : getOperandTypes()) {
if (operandTy.hasAnyPack())
if (typeOrLayoutInvolvesPack(operandTy, F))
return true;
}
for (auto &tdo : getTypeDependentOperands()) {
if (tdo.get()->getType().hasAnyPack())
if (typeOrLayoutInvolvesPack(tdo.get()->getType(), F))
return true;
}