Skip to content

Commit 3fe4646

Browse files
committed
Allow a SILFunctionArgument to be a parameter pack.
We might want to record the *sequence* of parameter decls associated with a parameter pack, but currently we're not doing that.
1 parent fb5f37f commit 3fe4646

File tree

6 files changed

+35
-7
lines changed

6 files changed

+35
-7
lines changed

include/swift/SIL/SILArgument.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,14 @@ class SILFunctionArgument : public SILArgument {
342342
ValueOwnershipKind ownershipKind, const ValueDecl *decl = nullptr,
343343
bool isNoImplicitCopy = false,
344344
LifetimeAnnotation lifetimeAnnotation = LifetimeAnnotation::None,
345-
bool isCapture = false)
345+
bool isCapture = false,
346+
bool isParameterPack = false)
346347
: SILArgument(ValueKind::SILFunctionArgument, parentBlock, type,
347348
ownershipKind, decl) {
348349
sharedUInt32().SILFunctionArgument.noImplicitCopy = isNoImplicitCopy;
349350
sharedUInt32().SILFunctionArgument.lifetimeAnnotation = lifetimeAnnotation;
350351
sharedUInt32().SILFunctionArgument.closureCapture = isCapture;
352+
sharedUInt32().SILFunctionArgument.parameterPack = isParameterPack;
351353
}
352354

353355
// A special constructor, only intended for use in
@@ -373,6 +375,23 @@ class SILFunctionArgument : public SILArgument {
373375
sharedUInt32().SILFunctionArgument.closureCapture = newValue;
374376
}
375377

378+
/// Is this parameter a pack that corresponds to multiple
379+
/// formal parameters? (This could mean multiple ParamDecl*s,
380+
/// or it could mean a ParamDecl* that's a pack expansion.) Note
381+
/// that not all lowered parameters of pack type are parameter packs:
382+
/// they can be part of a single formal parameter of tuple type.
383+
/// This flag indicates that the lowered parameter has a one-to-many
384+
/// relationship with formal parameters.
385+
///
386+
/// TODO: preserve the parameter pack references in SIL in a side table
387+
/// instead of using a single bit.
388+
bool isFormalParameterPack() const {
389+
return sharedUInt32().SILFunctionArgument.parameterPack;
390+
}
391+
void setFormalParameterPack(bool isPack) {
392+
sharedUInt32().SILFunctionArgument.parameterPack = isPack;
393+
}
394+
376395
LifetimeAnnotation getLifetimeAnnotation() const {
377396
return LifetimeAnnotation::Case(
378397
sharedUInt32().SILFunctionArgument.lifetimeAnnotation);
@@ -416,6 +435,7 @@ class SILFunctionArgument : public SILArgument {
416435
setNoImplicitCopy(arg->isNoImplicitCopy());
417436
setLifetimeAnnotation(arg->getLifetimeAnnotation());
418437
setClosureCapture(arg->isClosureCapture());
438+
setFormalParameterPack(arg->isFormalParameterPack());
419439
}
420440

421441
static bool classof(const SILInstruction *) = delete;

include/swift/SIL/SILNode.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,8 @@ class alignas(8) SILNode :
268268
SHARED_FIELD(StringLiteralInst, uint32_t length);
269269
SHARED_FIELD(PointerToAddressInst, uint32_t alignment);
270270
SHARED_FIELD(SILFunctionArgument, uint32_t noImplicitCopy : 1,
271-
lifetimeAnnotation : 2, closureCapture : 1);
271+
lifetimeAnnotation : 2, closureCapture : 1,
272+
parameterPack : 1);
272273

273274
// Do not use `_sharedUInt32_private` outside of SILNode.
274275
} _sharedUInt32_private;

lib/SILGen/SILGenBuilder.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,15 +451,17 @@ static ManagedValue createInputFunctionArgument(
451451
SILGenBuilder &B, SILType type, SILLocation loc, ValueDecl *decl = nullptr,
452452
bool isNoImplicitCopy = false,
453453
LifetimeAnnotation lifetimeAnnotation = LifetimeAnnotation::None,
454-
bool isClosureCapture = false) {
454+
bool isClosureCapture = false,
455+
bool isFormalParameterPack = false) {
455456
auto &SGF = B.getSILGenFunction();
456457
SILFunction &F = B.getFunction();
457-
assert((F.isBare() || decl) &&
458+
assert((F.isBare() || isFormalParameterPack || decl) &&
458459
"Function arguments of non-bare functions must have a decl");
459460
auto *arg = F.begin()->createFunctionArgument(type, decl);
460461
arg->setNoImplicitCopy(isNoImplicitCopy);
461462
arg->setClosureCapture(isClosureCapture);
462463
arg->setLifetimeAnnotation(lifetimeAnnotation);
464+
arg->setFormalParameterPack(isFormalParameterPack);
463465
switch (arg->getArgumentConvention()) {
464466
case SILArgumentConvention::Indirect_In_Guaranteed:
465467
case SILArgumentConvention::Direct_Guaranteed:
@@ -499,10 +501,12 @@ static ManagedValue createInputFunctionArgument(
499501

500502
ManagedValue SILGenBuilder::createInputFunctionArgument(
501503
SILType type, ValueDecl *decl, bool isNoImplicitCopy,
502-
LifetimeAnnotation lifetimeAnnotation, bool isClosureCapture) {
504+
LifetimeAnnotation lifetimeAnnotation, bool isClosureCapture,
505+
bool isFormalParameterPack) {
503506
return ::createInputFunctionArgument(*this, type, SILLocation(decl), decl,
504507
isNoImplicitCopy, lifetimeAnnotation,
505-
isClosureCapture);
508+
isClosureCapture,
509+
isFormalParameterPack);
506510
}
507511

508512
ManagedValue

lib/SILGen/SILGenBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class SILGenBuilder : public SILBuilder {
230230
ManagedValue createInputFunctionArgument(
231231
SILType type, ValueDecl *decl, bool isNoImplicitCopy = false,
232232
LifetimeAnnotation lifetimeAnnotation = LifetimeAnnotation::None,
233-
bool isClosureCapture = false);
233+
bool isClosureCapture = false, bool isFormalParameterPack = false);
234234

235235
/// Create a SILArgument for an input parameter. Uses \p loc to create any
236236
/// copies necessary. Asserts if used to create a function argument for an out

lib/Serialization/DeserializeSIL.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,8 @@ SILBasicBlock *SILDeserializer::readSILBasicBlock(SILFunction *Fn,
971971
fArg->setLifetimeAnnotation(lifetime);
972972
bool isClosureCapture = (Args[I + 1] >> 19) & 0x1;
973973
fArg->setClosureCapture(isClosureCapture);
974+
bool isFormalParameterPack = (Args[I + 1] >> 20) & 0x1;
975+
fArg->setFormalParameterPack(isFormalParameterPack);
974976
Arg = fArg;
975977
} else {
976978
auto OwnershipKind = ValueOwnershipKind((Args[I + 1] >> 8) & 0xF);

lib/Serialization/SerializeSIL.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,7 @@ void SILSerializer::writeSILBasicBlock(const SILBasicBlock &BB) {
647647
packedMetadata |= unsigned(SFA->isNoImplicitCopy()) << 16; // 1 bit
648648
packedMetadata |= unsigned(SFA->getLifetimeAnnotation()) << 17; // 2 bits
649649
packedMetadata |= unsigned(SFA->isClosureCapture()) << 19; // 1 bit
650+
packedMetadata |= unsigned(SFA->isFormalParameterPack()) << 20; // 1 bit
650651
}
651652
// Used: 19 bits. Free: 13.
652653
//

0 commit comments

Comments
 (0)