Skip to content

Commit 2211b2c

Browse files
Merge pull request #67497 from nate-chandler/cherrypick/release/5.9/rdar112792831
5.9: [IRGen] Add metadata pack markers for more instructions.
2 parents 901d3f8 + 1b74405 commit 2211b2c

11 files changed

+169
-32
lines changed

include/swift/AST/Types.h

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,13 @@ class RecursiveTypeProperties {
180180
/// they have a type variable originator.
181181
SolverAllocated = 0x8000,
182182

183-
/// This type contains a concrete pack.
184-
HasConcretePack = 0x10000,
183+
/// Contains a PackType.
184+
HasPack = 0x10000,
185185

186-
Last_Property = HasConcretePack
186+
/// Contains a PackArchetypeType.
187+
HasPackArchetype = 0x20000,
188+
189+
Last_Property = HasPackArchetype
187190
};
188191
enum { BitWidth = countBitsUsed(Property::Last_Property) };
189192

@@ -259,7 +262,9 @@ class RecursiveTypeProperties {
259262

260263
bool hasParameterPack() const { return Bits & HasParameterPack; }
261264

262-
bool hasConcretePack() const { return Bits & HasConcretePack; }
265+
bool hasPack() const { return Bits & HasPack; }
266+
267+
bool hasPackArchetype() const { return Bits & HasPackArchetype; }
263268

264269
/// Does a type with these properties structurally contain a
265270
/// parameterized existential type?
@@ -419,12 +424,12 @@ class alignas(1 << TypeAlignInBits) TypeBase
419424
NumProtocols : 16
420425
);
421426

422-
SWIFT_INLINE_BITFIELD_FULL(TypeVariableType, TypeBase, 7+30,
427+
SWIFT_INLINE_BITFIELD_FULL(TypeVariableType, TypeBase, 7+29,
423428
/// Type variable options.
424429
Options : 7,
425430
: NumPadBits,
426431
/// The unique number assigned to this type variable.
427-
ID : 30
432+
ID : 29
428433
);
429434

430435
SWIFT_INLINE_BITFIELD(SILFunctionType, TypeBase, NumSILExtInfoBits+1+4+1+2+1+1,
@@ -687,16 +692,26 @@ class alignas(1 << TypeAlignInBits) TypeBase
687692
return getRecursiveProperties().hasLocalArchetype();
688693
}
689694

695+
/// Whether the type contains a generic parameter declared as a parameter
696+
/// pack.
690697
bool hasParameterPack() const {
691698
return getRecursiveProperties().hasParameterPack();
692699
}
693700

694-
bool hasConcretePack() const {
695-
return getRecursiveProperties().hasConcretePack();
701+
/// Whether the type contains a PackType.
702+
bool hasPack() const {
703+
return getRecursiveProperties().hasPack();
696704
}
697705

698-
/// Whether the type has some flavor of pack.
699-
bool hasPack() const { return hasParameterPack() || hasConcretePack(); }
706+
/// Whether the type contains a PackArchetypeType.
707+
bool hasPackArchetype() const {
708+
return getRecursiveProperties().hasPackArchetype();
709+
}
710+
711+
/// Whether the type has any flavor of pack.
712+
bool hasAnyPack() const {
713+
return hasParameterPack() || hasPack() || hasPackArchetype();
714+
}
700715

701716
/// Determine whether the type involves a parameterized existential type.
702717
bool hasParameterizedExistential() const {

include/swift/SIL/SILType.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,12 +352,15 @@ class SILType {
352352
/// pack.
353353
bool hasParameterPack() const { return getASTType()->hasParameterPack(); }
354354

355-
/// Whether the type contains a concrete pack.
356-
bool hasConcretePack() const { return getASTType()->hasConcretePack(); }
357-
358-
/// Whether the type contains some flavor of pack.
355+
/// Whether the type contains a PackType.
359356
bool hasPack() const { return getASTType()->hasPack(); }
360357

358+
/// Whether the type contains a PackArchetypeType.
359+
bool hasPackArchetype() const { return getASTType()->hasPackArchetype(); }
360+
361+
/// Whether the type contains any flavor of pack.
362+
bool hasAnyPack() const { return getASTType()->hasAnyPack(); }
363+
361364
/// True if the type is an empty tuple or an empty struct or a tuple or
362365
/// struct containing only empty types.
363366
bool isEmpty(const SILFunction &F) const;

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,7 +3404,7 @@ CanPackType CanPackType::get(const ASTContext &C,
34043404
}
34053405

34063406
PackType *PackType::get(const ASTContext &C, ArrayRef<Type> elements) {
3407-
RecursiveTypeProperties properties = RecursiveTypeProperties::HasConcretePack;
3407+
RecursiveTypeProperties properties = RecursiveTypeProperties::HasPack;
34083408
bool isCanonical = true;
34093409
for (Type eltTy : elements) {
34103410
assert(!eltTy->is<PackType>() &&
@@ -3444,7 +3444,7 @@ void PackType::Profile(llvm::FoldingSetNodeID &ID, ArrayRef<Type> Elements) {
34443444

34453445
CanSILPackType SILPackType::get(const ASTContext &C, ExtInfo info,
34463446
ArrayRef<CanType> elements) {
3447-
RecursiveTypeProperties properties = RecursiveTypeProperties::HasConcretePack;
3447+
RecursiveTypeProperties properties;
34483448
for (CanType eltTy : elements) {
34493449
assert(!isa<SILPackType>(eltTy) &&
34503450
"Cannot have pack directly inside another pack");
@@ -4036,7 +4036,7 @@ isAnyFunctionTypeCanonical(ArrayRef<AnyFunctionType::Param> params,
40364036
static RecursiveTypeProperties
40374037
getGenericFunctionRecursiveProperties(ArrayRef<AnyFunctionType::Param> params,
40384038
Type result) {
4039-
static_assert(RecursiveTypeProperties::BitWidth == 17,
4039+
static_assert(RecursiveTypeProperties::BitWidth == 18,
40404040
"revisit this if you add new recursive type properties");
40414041
RecursiveTypeProperties properties;
40424042

@@ -4677,7 +4677,7 @@ CanSILFunctionType SILFunctionType::get(
46774677
void *mem = ctx.Allocate(bytes, alignof(SILFunctionType));
46784678

46794679
RecursiveTypeProperties properties;
4680-
static_assert(RecursiveTypeProperties::BitWidth == 17,
4680+
static_assert(RecursiveTypeProperties::BitWidth == 18,
46814681
"revisit this if you add new recursive type properties");
46824682
for (auto &param : params)
46834683
properties |= param.getInterfaceType()->getRecursiveProperties();

lib/AST/Type.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3703,8 +3703,9 @@ PackArchetypeType::PackArchetypeType(
37033703
ArrayRef<ProtocolDecl *> ConformsTo, Type Superclass,
37043704
LayoutConstraint Layout, PackShape Shape)
37053705
: ArchetypeType(TypeKind::PackArchetype, Ctx,
3706-
RecursiveTypeProperties::HasArchetype, InterfaceType,
3707-
ConformsTo, Superclass, Layout, GenericEnv) {
3706+
RecursiveTypeProperties::HasArchetype |
3707+
RecursiveTypeProperties::HasPackArchetype,
3708+
InterfaceType, ConformsTo, Superclass, Layout, GenericEnv) {
37083709
assert(InterfaceType->isParameterPack());
37093710
*getTrailingObjects<PackShape>() = Shape;
37103711
}

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,6 +2645,10 @@ void IRGenSILFunction::visitSILBasicBlock(SILBasicBlock *BB) {
26452645
llvm::report_fatal_error(
26462646
"Instruction resulted in on-stack pack metadata emission but no "
26472647
"cleanup instructions were added");
2648+
// The markers which indicate where on-stack pack metadata should be
2649+
// deallocated were not inserted for I. To fix this, add I's opcode to
2650+
// SILInstruction::mayRequirePackMetadata subject to the appropriate
2651+
// checks.
26482652
}
26492653
}
26502654
#endif

lib/IRGen/PackMetadataMarkerInserter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Inserter::shouldInsertMarkersForInstruction(SILInstruction *inst) {
9191
BuiltinValueKind::StartAsyncLetWithLocalBuffer ||
9292
bi->getBuiltinKind() == BuiltinValueKind::StartAsyncLet)
9393
return Inserter::FindResult::Unhandleable;
94-
return Inserter::FindResult::None;
94+
LLVM_FALLTHROUGH;
9595
}
9696
default:
9797
return inst->mayRequirePackMetadata() ? FindResult::Some : FindResult::None;

lib/SIL/IR/SILInstruction.cpp

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,33 +1305,64 @@ bool SILInstruction::mayRequirePackMetadata() const {
13051305
case SILInstructionKind::TryApplyInst: {
13061306
// Check the function type for packs.
13071307
auto apply = ApplySite::isa(const_cast<SILInstruction *>(this));
1308-
if (apply.getCallee()->getType().hasPack())
1308+
if (apply.getCallee()->getType().hasAnyPack())
13091309
return true;
13101310
// Check the substituted types for packs.
13111311
for (auto ty : apply.getSubstitutionMap().getReplacementTypes()) {
1312-
if (ty->hasPack())
1312+
if (ty->hasAnyPack())
13131313
return true;
13141314
}
13151315
return false;
13161316
}
1317-
case SILInstructionKind::DebugValueInst: {
1318-
auto *dvi = cast<DebugValueInst>(this);
1319-
return dvi->getOperand()->getType().hasPack();
1317+
case SILInstructionKind::ClassMethodInst:
1318+
case SILInstructionKind::DebugValueInst:
1319+
case SILInstructionKind::DestroyAddrInst:
1320+
case SILInstructionKind::DestroyValueInst:
1321+
// Unary instructions.
1322+
{
1323+
return getOperand(0)->getType().hasAnyPack();
1324+
}
1325+
case SILInstructionKind::AllocStackInst: {
1326+
auto *asi = cast<AllocStackInst>(this);
1327+
return asi->getType().hasAnyPack();
13201328
}
13211329
case SILInstructionKind::MetatypeInst: {
13221330
auto *mi = cast<MetatypeInst>(this);
1323-
return mi->getType().hasPack();
1324-
}
1325-
case SILInstructionKind::ClassMethodInst: {
1326-
auto *cmi = cast<ClassMethodInst>(this);
1327-
return cmi->getOperand()->getType().hasPack();
1331+
return mi->getType().hasAnyPack();
13281332
}
13291333
case SILInstructionKind::WitnessMethodInst: {
13301334
auto *wmi = cast<WitnessMethodInst>(this);
13311335
auto ty = wmi->getLookupType();
1332-
return ty->hasPack();
1336+
return ty->hasAnyPack();
13331337
}
13341338
default:
1339+
// Instructions that deallocate stack must not result in pack metadata
1340+
// materialization. If they did there would be no way to create the pack
1341+
// metadata on stack.
1342+
if (isDeallocatingStack())
1343+
return false;
1344+
1345+
// Terminators that exit the function must not result in pack metadata
1346+
// materialization.
1347+
auto *ti = dyn_cast<TermInst>(this);
1348+
if (ti && ti->isFunctionExiting())
1349+
return false;
1350+
1351+
// Check results and operands for packs. If a pack appears, lowering the
1352+
// instruction might result in pack metadata emission.
1353+
for (auto result : getResults()) {
1354+
if (result->getType().hasAnyPack())
1355+
return true;
1356+
}
1357+
for (auto operandTy : getOperandTypes()) {
1358+
if (operandTy.hasAnyPack())
1359+
return true;
1360+
}
1361+
for (auto &tdo : getTypeDependentOperands()) {
1362+
if (tdo.get()->getType().hasAnyPack())
1363+
return true;
1364+
}
1365+
13351366
return false;
13361367
}
13371368
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
// Verify that we don't hit the `Instruction missing on-stack pack metadata cleanups!` assertion.
4+
5+
// For alloc_stacks of tuples featuring a pack.
6+
public func tupleExpansionWithMemberType<each T: Sequence>(seqs: (repeat each T), elts: (repeat (each T).Element)) {}

test/IRGen/pack_metadata_marker_inserter.sil

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ struct S1 {}
2222
struct S2 {}
2323
struct S3 {}
2424

25+
struct GVT<each T> : Error {
26+
}
27+
2528
struct GV<each T> {
2629
var tu: (repeat each T)
2730
}
@@ -145,6 +148,16 @@ entry:
145148
return %retval : $()
146149
}
147150

151+
// CHECK-SIL-LABEL: sil @return_variadic : {{.*}} {
152+
// CHECK-SIL: [[RETVAL:%[^,]+]] = struct
153+
// CHECK-SIL: return [[RETVAL]]
154+
// CHECK-SIL-LABEL: } // end sil function 'return_variadic'
155+
sil @return_variadic : $<each T>() -> GVT<repeat each T> {
156+
entry:
157+
%retval = struct $GVT<repeat each T> ()
158+
return %retval : $GVT<repeat each T>
159+
}
160+
148161
// =============================================================================
149162
// FINISH: Instructions: Apply }}
150163
// =============================================================================
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -pack-metadata-marker-inserter -enable-pack-metadata-stack-promotion=true | %FileCheck %s --check-prefixes CHECK-SIL
2+
3+
// REQUIRES: asserts
4+
5+
sil_stage lowered
6+
7+
import Builtin
8+
9+
protocol Error {}
10+
11+
struct GVT<each T> {
12+
}
13+
14+
// CHECK-SIL-LABEL: sil @throw_variadic : {{.*}} {
15+
// CHECK-SIL: [[ERROR:%[^,]+]] = struct
16+
// CHECK-SIL: throw [[ERROR]]
17+
// CHECK-SIL-LABEL: } // end sil function 'throw_variadic'
18+
sil @throw_variadic : $<each T>() -> ((), @error GVT<repeat each T>) {
19+
entry:
20+
%retval = struct $GVT<repeat each T> ()
21+
throw %retval : $GVT<repeat each T>
22+
}
23+

0 commit comments

Comments
 (0)