Skip to content

Commit 10e487b

Browse files
authored
Merge pull request swiftlang#63589 from rjmccall/pack_length
Add a pack_length SIL instruction for measuring the length of a pack
2 parents e15ea7a + a384787 commit 10e487b

File tree

17 files changed

+153
-13
lines changed

17 files changed

+153
-13
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,6 +1946,13 @@ class SILBuilder {
19461946
getSILDebugLocation(Loc), Existential));
19471947
}
19481948

1949+
PackLengthInst *
1950+
createPackLength(SILLocation loc, CanPackType packType) {
1951+
return insert(PackLengthInst::create(getFunction(),
1952+
getSILDebugLocation(loc),
1953+
packType));
1954+
}
1955+
19491956
DynamicPackIndexInst *
19501957
createDynamicPackIndex(SILLocation loc, SILValue indexValue,
19511958
CanPackType indexedPackType) {

include/swift/SIL/SILCloner.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,6 +2495,17 @@ void SILCloner<ImplClass>::visitDeinitExistentialValueInst(
24952495
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand())));
24962496
}
24972497

2498+
template <typename ImplClass>
2499+
void SILCloner<ImplClass>::visitPackLengthInst(PackLengthInst *Inst) {
2500+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2501+
2502+
auto loc = getOpLocation(Inst->getLoc());
2503+
auto newPackType = cast<PackType>(getOpASTType(Inst->getPackType()));
2504+
2505+
recordClonedInstruction(
2506+
Inst, getBuilder().createPackLength(loc, newPackType));
2507+
}
2508+
24982509
template <typename ImplClass>
24992510
void SILCloner<ImplClass>::visitDynamicPackIndexInst(
25002511
DynamicPackIndexInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7451,6 +7451,36 @@ class DeinitExistentialValueInst
74517451
: UnaryInstructionBase(DebugLoc, Existential) {}
74527452
};
74537453

7454+
/// Compute the length of a pack (as a Builtin.Word).
7455+
class PackLengthInst final
7456+
: public NullaryInstructionWithTypeDependentOperandsBase<
7457+
SILInstructionKind::PackLengthInst,
7458+
PackLengthInst,
7459+
SingleValueInstruction> {
7460+
friend TrailingObjects;
7461+
friend SILBuilder;
7462+
7463+
CanPackType ThePackType;
7464+
7465+
PackLengthInst(SILDebugLocation loc,
7466+
ArrayRef<SILValue> typeDependentOperands,
7467+
SILType resultType,
7468+
CanPackType packType)
7469+
: NullaryInstructionWithTypeDependentOperandsBase(loc,
7470+
typeDependentOperands,
7471+
resultType),
7472+
ThePackType(packType) {}
7473+
7474+
static PackLengthInst *create(SILFunction &parent,
7475+
SILDebugLocation loc,
7476+
CanPackType packType);
7477+
public:
7478+
/// Return the measured pack type.
7479+
CanPackType getPackType() const {
7480+
return ThePackType;
7481+
}
7482+
};
7483+
74547484
/// An abstract class for instructions which producing variadic
74557485
/// pack indices.
74567486
///

include/swift/SIL/SILNodes.def

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,18 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
606606
// Variadic generics
607607
SINGLE_VALUE_INST(OpenPackElementInst, open_pack_element,
608608
SingleValueInstruction, None, DoesNotRelease)
609+
SINGLE_VALUE_INST(PackLengthInst, pack_length,
610+
SingleValueInstruction, None, DoesNotRelease)
611+
612+
// Variadic pack indexing
613+
ABSTRACT_SINGLE_VALUE_INST(AnyPackIndexInst, SingleValueInstruction)
614+
SINGLE_VALUE_INST(DynamicPackIndexInst, dynamic_pack_index,
615+
AnyPackIndexInst, None, DoesNotRelease)
616+
SINGLE_VALUE_INST(PackPackIndexInst, pack_pack_index,
617+
AnyPackIndexInst, None, DoesNotRelease)
618+
SINGLE_VALUE_INST(ScalarPackIndexInst, scalar_pack_index,
619+
AnyPackIndexInst, None, DoesNotRelease)
620+
SINGLE_VALUE_INST_RANGE(AnyPackIndexInst, DynamicPackIndexInst, ScalarPackIndexInst)
609621

610622
// Blocks
611623
SINGLE_VALUE_INST(ProjectBlockStorageInst, project_block_storage,
@@ -649,16 +661,6 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
649661
SINGLE_VALUE_INST(KeyPathInst, keypath,
650662
SingleValueInstruction, MayHaveSideEffects, DoesNotRelease)
651663

652-
// Variadic pack indexing
653-
ABSTRACT_SINGLE_VALUE_INST(AnyPackIndexInst, SingleValueInstruction)
654-
SINGLE_VALUE_INST(DynamicPackIndexInst, dynamic_pack_index,
655-
AnyPackIndexInst, None, DoesNotRelease)
656-
SINGLE_VALUE_INST(PackPackIndexInst, pack_pack_index,
657-
AnyPackIndexInst, None, DoesNotRelease)
658-
SINGLE_VALUE_INST(ScalarPackIndexInst, scalar_pack_index,
659-
AnyPackIndexInst, None, DoesNotRelease)
660-
SINGLE_VALUE_INST_RANGE(AnyPackIndexInst, DynamicPackIndexInst, ScalarPackIndexInst)
661-
662664
// BindMemory and RebindMemory have no physical side effect. Semantically they
663665
// write to their affected memory region because any reads or writes accessing
664666
// that memory must be dependent on the bind operation.

lib/IRGen/IRGenSIL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,7 @@ class IRGenSILFunction :
12761276
void visitProjectExistentialBoxInst(ProjectExistentialBoxInst *i);
12771277
void visitDeallocExistentialBoxInst(DeallocExistentialBoxInst *i);
12781278

1279+
void visitPackLengthInst(PackLengthInst *i);
12791280
void visitOpenPackElementInst(OpenPackElementInst *i);
12801281
void visitDynamicPackIndexInst(DynamicPackIndexInst *i);
12811282
void visitPackPackIndexInst(PackPackIndexInst *i);
@@ -6869,6 +6870,11 @@ void IRGenSILFunction::visitOpenExistentialValueInst(
68696870
llvm_unreachable("unsupported instruction during IRGen");
68706871
}
68716872

6873+
void IRGenSILFunction::visitPackLengthInst(PackLengthInst *i) {
6874+
auto length = emitPackShapeExpression(i->getPackType());
6875+
setLoweredSingletonExplosion(i, length);
6876+
}
6877+
68726878
void IRGenSILFunction::visitDynamicPackIndexInst(DynamicPackIndexInst *i) {
68736879
// At the IRGen level, this is just a type change.
68746880
auto index = getLoweredSingletonExplosion(i->getOperand());

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ SHOULD_NEVER_VISIT_INST(AllocExistentialBox)
9999
SHOULD_NEVER_VISIT_INST(AllocGlobal)
100100
SHOULD_NEVER_VISIT_INST(AllocStack)
101101
SHOULD_NEVER_VISIT_INST(AllocPack)
102+
SHOULD_NEVER_VISIT_INST(PackLength)
102103
SHOULD_NEVER_VISIT_INST(DifferentiabilityWitnessFunction)
103104
SHOULD_NEVER_VISIT_INST(FloatLiteral)
104105
SHOULD_NEVER_VISIT_INST(FunctionRef)

lib/SIL/IR/SILInstructions.cpp

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,6 +2267,28 @@ OpenExistentialValueInst::OpenExistentialValueInst(
22672267
: UnaryInstructionBase(debugLoc, operand, selfTy, forwardingOwnershipKind) {
22682268
}
22692269

2270+
PackLengthInst *PackLengthInst::create(SILFunction &F,
2271+
SILDebugLocation loc,
2272+
CanPackType packType) {
2273+
auto resultType = SILType::getBuiltinWordType(F.getASTContext());
2274+
2275+
// Always reduce the pack shape.
2276+
packType = packType->getReducedShape();
2277+
2278+
// Under current limitations, that should reliably eliminate
2279+
// any local archetypes from the pack, but there's no real need to
2280+
// assume that in the SIL representation.
2281+
SmallVector<SILValue, 8> typeDependentOperands;
2282+
collectTypeDependentOperands(typeDependentOperands, F, packType);
2283+
2284+
size_t size =
2285+
totalSizeToAlloc<swift::Operand>(typeDependentOperands.size());
2286+
void *buffer =
2287+
F.getModule().allocateInst(size, alignof(PackLengthInst));
2288+
return ::new (buffer)
2289+
PackLengthInst(loc, typeDependentOperands, resultType, packType);
2290+
}
2291+
22702292
DynamicPackIndexInst *DynamicPackIndexInst::create(SILFunction &F,
22712293
SILDebugLocation loc,
22722294
SILValue indexOperand,
@@ -2276,7 +2298,7 @@ DynamicPackIndexInst *DynamicPackIndexInst::create(SILFunction &F,
22762298
SmallVector<SILValue, 8> typeDependentOperands;
22772299
collectTypeDependentOperands(typeDependentOperands, F, packType);
22782300

2279-
unsigned size =
2301+
size_t size =
22802302
totalSizeToAlloc<swift::Operand>(1 + typeDependentOperands.size());
22812303
void *buffer =
22822304
F.getModule().allocateInst(size, alignof(DynamicPackIndexInst));
@@ -2299,7 +2321,7 @@ PackPackIndexInst *PackPackIndexInst::create(SILFunction &F,
22992321
SmallVector<SILValue, 8> typeDependentOperands;
23002322
collectTypeDependentOperands(typeDependentOperands, F, packType);
23012323

2302-
unsigned size =
2324+
size_t size =
23032325
totalSizeToAlloc<swift::Operand>(1 + typeDependentOperands.size());
23042326
void *buffer =
23052327
F.getModule().allocateInst(size, alignof(PackPackIndexInst));
@@ -2322,7 +2344,7 @@ ScalarPackIndexInst *ScalarPackIndexInst::create(SILFunction &F,
23222344
SmallVector<SILValue, 8> typeDependentOperands;
23232345
collectTypeDependentOperands(typeDependentOperands, F, packType);
23242346

2325-
unsigned size =
2347+
size_t size =
23262348
totalSizeToAlloc<swift::Operand>(typeDependentOperands.size());
23272349
void *buffer =
23282350
F.getModule().allocateInst(size, alignof(ScalarPackIndexInst));

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2274,6 +2274,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
22742274
void visitDeallocExistentialBoxInst(DeallocExistentialBoxInst *DEI) {
22752275
*this << getIDAndType(DEI->getOperand()) << ", $" << DEI->getConcreteType();
22762276
}
2277+
void visitPackLengthInst(PackLengthInst *PLI) {
2278+
*this << "$" << PLI->getPackType();
2279+
}
22772280
void visitDynamicPackIndexInst(DynamicPackIndexInst *DPII) {
22782281
*this << Ctx.getID(DPII->getOperand()) << " of $"
22792282
<< DPII->getIndexedPackType();

lib/SIL/IR/ValueOwnership.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ CONSTANT_OWNERSHIP_INST(Owned, ObjCMetatypeToObject)
9494
CONSTANT_OWNERSHIP_INST(None, AddressToPointer)
9595
CONSTANT_OWNERSHIP_INST(None, AllocStack)
9696
CONSTANT_OWNERSHIP_INST(None, AllocPack)
97+
CONSTANT_OWNERSHIP_INST(None, PackLength)
9798
CONSTANT_OWNERSHIP_INST(None, BeginAccess)
9899
CONSTANT_OWNERSHIP_INST(None, BindMemory)
99100
CONSTANT_OWNERSHIP_INST(None, RebindMemory)

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3284,6 +3284,14 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
32843284
B.createOpenExistentialValue(InstLoc, Val, Ty, forwardingOwnership);
32853285
break;
32863286
}
3287+
case SILInstructionKind::PackLengthInst: {
3288+
CanPackType packType;
3289+
if (P.parseToken(tok::sil_dollar, diag::expected_tok_in_sil_instr, "$") ||
3290+
parseASTPackType(packType))
3291+
return true;
3292+
ResultVal = B.createPackLength(InstLoc, packType);
3293+
break;
3294+
}
32873295
case SILInstructionKind::DynamicPackIndexInst: {
32883296
CanPackType packType;
32893297
if (parseValueRef(Val, SILType::getBuiltinWordType(P.Context), InstLoc, B) ||

0 commit comments

Comments
 (0)