Skip to content

Commit cfc28e2

Browse files
committed
[SIL] Added on-stack pack metadata marker insts.
The new alloc_pack_metadata and dealloc_pack_metadata are inserted as part of IRGen lowering. The former indicates that the next instruction might result in on-stack pack metadata being emitted. The latter indicates that this is the position at which metadata emitted on behalf of its operand should be cleaned up.
1 parent e4a1521 commit cfc28e2

21 files changed

+238
-3
lines changed

docs/SIL.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3799,6 +3799,20 @@ address of the allocated memory.
37993799
on stack discipline. The corresponding stack deallocation instruction is
38003800
``dealloc_pack``.
38013801

3802+
alloc_pack_metadata
3803+
```````````````````
3804+
3805+
::
3806+
3807+
sil-instruction ::= 'alloc_pack_metadata' $()
3808+
3809+
Inserted as the last SIL lowering pass of IRGen, indicates that the next instruction
3810+
may have on-stack pack metadata allocated on its behalf.
3811+
3812+
Notionally, ``alloc_pack_metadata`` is a stack allocation instruction. See the
3813+
section above on stack discipline. The corresponding stack deallocation
3814+
instruction is ``dealloc_pack_metadata``.
3815+
38023816
alloc_ref
38033817
`````````
38043818
::
@@ -4056,6 +4070,23 @@ prior to being deallocated.
40564070
on Stack Discipline above. The operand must be an ``alloc_pack``
40574071
instruction.
40584072

4073+
dealloc_pack_metadata
4074+
`````````````````````
4075+
4076+
::
4077+
4078+
sil-instruction ::= 'dealloc_pack_metadata' sil-operand
4079+
4080+
dealloc_pack_metadata $0 : $*()
4081+
4082+
Inserted as the last SIL lowering pass of IRGen, indicates that the on-stack
4083+
pack metadata emitted on behalf of its operand (actually on behalf of the
4084+
instruction after its operand) must be cleaned up here.
4085+
4086+
``dealloc_pack_metadata`` is a stack deallocation instruction. See the section
4087+
on Stack Discipline above. The operand must be an ``alloc_pack_metadata``
4088+
instruction.
4089+
40594090
dealloc_box
40604091
```````````
40614092
::

include/swift/SIL/SILBuilder.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,15 @@ class SILBuilder {
443443
return insert(AllocPackInst::create(getSILDebugLocation(loc), packType,
444444
getFunction()));
445445
}
446+
AllocPackMetadataInst *
447+
createAllocPackMetadata(SILLocation loc,
448+
Optional<SILType> elementType = llvm::None) {
449+
return insert(new (getModule()) AllocPackMetadataInst(
450+
getSILDebugLocation(loc),
451+
elementType.value_or(
452+
SILType::getEmptyTupleType(getModule().getASTContext())
453+
.getAddressType())));
454+
}
446455

447456
AllocRefInst *createAllocRef(SILLocation Loc, SILType ObjectType,
448457
bool objc, bool canAllocOnStack,
@@ -2215,6 +2224,11 @@ class SILBuilder {
22152224
return insert(new (getModule())
22162225
DeallocPackInst(getSILDebugLocation(loc), operand));
22172226
}
2227+
DeallocPackMetadataInst *createDeallocPackMetadata(SILLocation loc,
2228+
SILValue alloc) {
2229+
return insert(new (getModule())
2230+
DeallocPackMetadataInst(getSILDebugLocation(loc), alloc));
2231+
}
22182232
DeallocStackRefInst *createDeallocStackRef(SILLocation Loc,
22192233
SILValue operand) {
22202234
return insert(new (getModule())

include/swift/SIL/SILCloner.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,14 @@ SILCloner<ImplClass>::visitAllocStackInst(AllocStackInst *Inst) {
891891
recordClonedInstruction(Inst, NewInst);
892892
}
893893

894+
template <typename ImplClass>
895+
void SILCloner<ImplClass>::visitAllocPackMetadataInst(
896+
AllocPackMetadataInst *Inst) {
897+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
898+
recordClonedInstruction(Inst, getBuilder().createAllocPackMetadata(
899+
getOpLocation(Inst->getLoc())));
900+
}
901+
894902
template<typename ImplClass>
895903
void
896904
SILCloner<ImplClass>::visitAllocPackInst(AllocPackInst *Inst) {
@@ -2844,6 +2852,15 @@ SILCloner<ImplClass>::visitDeallocPackInst(DeallocPackInst *Inst) {
28442852
getOpValue(Inst->getOperand())));
28452853
}
28462854

2855+
template <typename ImplClass>
2856+
void SILCloner<ImplClass>::visitDeallocPackMetadataInst(
2857+
DeallocPackMetadataInst *Inst) {
2858+
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
2859+
recordClonedInstruction(
2860+
Inst, getBuilder().createDeallocPackMetadata(
2861+
getOpLocation(Inst->getLoc()), Inst->getOperand()));
2862+
}
2863+
28472864
template<typename ImplClass>
28482865
void
28492866
SILCloner<ImplClass>::visitDeallocRefInst(DeallocRefInst *Inst) {

include/swift/SIL/SILInstruction.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,10 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
821821
/// The first operand must be the allocating instruction.
822822
bool isDeallocatingStack() const;
823823

824+
/// Whether IRGen lowering of this instruction may result in emitting packs of
825+
/// metadata or witness tables.
826+
bool mayRequirePackMetadata() const;
827+
824828
/// Create a new copy of this instruction, which retains all of the operands
825829
/// and other information of this one. If an insertion point is specified,
826830
/// then the new instruction is inserted before the specified point, otherwise
@@ -2275,6 +2279,27 @@ class AllocPackInst final
22752279
}
22762280
};
22772281

2282+
/// AllocPackMetadataInst - Marker instruction indicating that the next
2283+
/// instruction might allocate on-stack pack metadata
2284+
/// during IRGen.
2285+
///
2286+
/// Only valid in lowered SIL.
2287+
class AllocPackMetadataInst final
2288+
: public NullaryInstructionWithTypeDependentOperandsBase<
2289+
SILInstructionKind::AllocPackMetadataInst, AllocPackMetadataInst,
2290+
AllocationInst> {
2291+
friend SILBuilder;
2292+
2293+
AllocPackMetadataInst(SILDebugLocation loc, SILType elementType)
2294+
: NullaryInstructionWithTypeDependentOperandsBase(
2295+
loc, {}, elementType.getAddressType()) {}
2296+
2297+
public:
2298+
/// The instruction which may trigger on-stack pack metadata when IRGen
2299+
/// lowering.
2300+
SILInstruction *getIntroducer() { return getNextInstruction(); }
2301+
};
2302+
22782303
/// The base class for AllocRefInst and AllocRefDynamicInst.
22792304
///
22802305
/// The first NumTailTypes operands are counts for the tail allocated
@@ -8642,6 +8667,27 @@ class DeallocPackInst :
86428667
: UnaryInstructionBase(debugLoc, operand) {}
86438668
};
86448669

8670+
/// DeallocPackMetadataInst - Deallocate stack memory allocated on behalf of the
8671+
/// operand by IRGen.
8672+
///
8673+
/// Only valid in lowered SIL.
8674+
class DeallocPackMetadataInst final
8675+
: public UnaryInstructionBase<SILInstructionKind::DeallocPackMetadataInst,
8676+
DeallocationInst> {
8677+
friend SILBuilder;
8678+
8679+
DeallocPackMetadataInst(SILDebugLocation debugLoc, SILValue alloc)
8680+
: UnaryInstructionBase(debugLoc, alloc) {}
8681+
8682+
public:
8683+
AllocPackMetadataInst *getAllocation() {
8684+
return cast<AllocPackMetadataInst>(getOperand().getDefiningInstruction());
8685+
}
8686+
/// The instruction which may trigger on-stack pack metadata when IRGen
8687+
/// lowering.
8688+
SILInstruction *getIntroducer() { return getAllocation()->getIntroducer(); }
8689+
};
8690+
86458691
/// Like DeallocStackInst, but for `alloc_ref [stack]`.
86468692
class DeallocStackRefInst
86478693
: public UnaryInstructionBase<SILInstructionKind::DeallocStackRefInst,

include/swift/SIL/SILNodes.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
310310
AllocationInst, None, DoesNotRelease)
311311
SINGLE_VALUE_INST(AllocPackInst, alloc_pack,
312312
AllocationInst, None, DoesNotRelease)
313+
SINGLE_VALUE_INST(AllocPackMetadataInst, alloc_pack_metadata,
314+
AllocationInst, None, DoesNotRelease)
313315
SINGLE_VALUE_INST(AllocRefInst, alloc_ref,
314316
AllocationInst, None, DoesNotRelease)
315317
SINGLE_VALUE_INST(AllocRefDynamicInst, alloc_ref_dynamic,
@@ -718,6 +720,8 @@ ABSTRACT_INST(DeallocationInst, SILInstruction)
718720
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
719721
NON_VALUE_INST(DeallocPackInst, dealloc_pack,
720722
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
723+
NON_VALUE_INST(DeallocPackMetadataInst, dealloc_pack_metadata,
724+
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
721725
NON_VALUE_INST(DeallocStackRefInst, dealloc_stack_ref,
722726
DeallocationInst, MayHaveSideEffects, DoesNotRelease)
723727
NON_VALUE_INST(DeallocRefInst, dealloc_ref,

lib/IRGen/IRGenSIL.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,7 @@ class IRGenSILFunction :
11751175
llvm::Value *addr);
11761176
void visitAllocStackInst(AllocStackInst *i);
11771177
void visitAllocPackInst(AllocPackInst *i);
1178+
void visitAllocPackMetadataInst(AllocPackMetadataInst *i);
11781179
void visitAllocRefInst(AllocRefInst *i);
11791180
void visitAllocRefDynamicInst(AllocRefDynamicInst *i);
11801181
void visitAllocBoxInst(AllocBoxInst *i);
@@ -1360,6 +1361,7 @@ class IRGenSILFunction :
13601361
void visitDeallocStackInst(DeallocStackInst *i);
13611362
void visitDeallocStackRefInst(DeallocStackRefInst *i);
13621363
void visitDeallocPackInst(DeallocPackInst *i);
1364+
void visitDeallocPackMetadataInst(DeallocPackMetadataInst *i);
13631365
void visitDeallocBoxInst(DeallocBoxInst *i);
13641366
void visitDeallocRefInst(DeallocRefInst *i);
13651367
void visitDeallocPartialRefInst(DeallocPartialRefInst *i);
@@ -5577,6 +5579,8 @@ void IRGenSILFunction::visitAllocPackInst(swift::AllocPackInst *i) {
55775579
setLoweredStackAddress(i, addr);
55785580
}
55795581

5582+
void IRGenSILFunction::visitAllocPackMetadataInst(AllocPackMetadataInst *i) {}
5583+
55805584
static void
55815585
buildTailArrays(IRGenSILFunction &IGF,
55825586
SmallVectorImpl<std::pair<SILType, llvm::Value *>> &TailArrays,
@@ -5682,6 +5686,10 @@ void IRGenSILFunction::visitDeallocPackInst(swift::DeallocPackInst *i) {
56825686
deallocatePack(*this, stackAddr, allocatedType);
56835687
}
56845688

5689+
void IRGenSILFunction::visitDeallocPackMetadataInst(
5690+
DeallocPackMetadataInst *i) {
5691+
}
5692+
56855693
void IRGenSILFunction::visitDeallocRefInst(swift::DeallocRefInst *i) {
56865694
// Lower the operand.
56875695
Explosion self = getLoweredExplosion(i->getOperand());

lib/SIL/IR/OperandOwnership.cpp

Lines changed: 2 additions & 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(AllocPackMetadata)
102103
SHOULD_NEVER_VISIT_INST(PackLength)
103104
SHOULD_NEVER_VISIT_INST(DifferentiabilityWitnessFunction)
104105
SHOULD_NEVER_VISIT_INST(FloatLiteral)
@@ -158,6 +159,7 @@ OPERAND_OWNERSHIP(TrivialUse, ExplicitCopyAddr)
158159
OPERAND_OWNERSHIP(TrivialUse, MarkUnresolvedMoveAddr)
159160
OPERAND_OWNERSHIP(TrivialUse, DeallocStack)
160161
OPERAND_OWNERSHIP(TrivialUse, DeallocPack)
162+
OPERAND_OWNERSHIP(TrivialUse, DeallocPackMetadata)
161163
OPERAND_OWNERSHIP(TrivialUse, DeinitExistentialAddr)
162164
OPERAND_OWNERSHIP(TrivialUse, DestroyAddr)
163165
OPERAND_OWNERSHIP(TrivialUse, EndAccess)

lib/SIL/IR/SILInstruction.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,7 +1247,8 @@ namespace {
12471247

12481248
bool SILInstruction::isAllocatingStack() const {
12491249
if (isa<AllocStackInst>(this) ||
1250-
isa<AllocPackInst>(this))
1250+
isa<AllocPackInst>(this) ||
1251+
isa<AllocPackMetadataInst>(this))
12511252
return true;
12521253

12531254
if (auto *ARI = dyn_cast<AllocRefInstBase>(this)) {
@@ -1278,7 +1279,8 @@ bool SILInstruction::isAllocatingStack() const {
12781279
bool SILInstruction::isDeallocatingStack() const {
12791280
if (isa<DeallocStackInst>(this) ||
12801281
isa<DeallocStackRefInst>(this) ||
1281-
isa<DeallocPackInst>(this))
1282+
isa<DeallocPackInst>(this) ||
1283+
isa<DeallocPackMetadataInst>(this))
12821284
return true;
12831285

12841286
if (auto *BI = dyn_cast<BuiltinInst>(this)) {
@@ -1290,6 +1292,24 @@ bool SILInstruction::isDeallocatingStack() const {
12901292
return false;
12911293
}
12921294

1295+
bool SILInstruction::mayRequirePackMetadata() const {
1296+
switch (getKind()) {
1297+
case SILInstructionKind::AllocPackInst:
1298+
case SILInstructionKind::PartialApplyInst:
1299+
case SILInstructionKind::ApplyInst:
1300+
case SILInstructionKind::BeginApplyInst:
1301+
case SILInstructionKind::TryApplyInst:
1302+
case SILInstructionKind::DebugValueInst:
1303+
case SILInstructionKind::MetatypeInst:
1304+
case SILInstructionKind::TuplePackElementAddrInst:
1305+
case SILInstructionKind::OpenPackElementInst:
1306+
case SILInstructionKind::ClassMethodInst:
1307+
case SILInstructionKind::WitnessMethodInst:
1308+
return true;
1309+
default:
1310+
return false;
1311+
}
1312+
}
12931313

12941314
/// Create a new copy of this instruction, which retains all of the operands
12951315
/// and other information of this one. If an insertion point is specified,

lib/SIL/IR/SILPrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,6 +1402,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
14021402
void visitAllocPackInst(AllocPackInst *API) {
14031403
*this << API->getType().getObjectType();
14041404
}
1405+
void visitAllocPackMetadataInst(AllocPackMetadataInst *APMI) {
1406+
*this << APMI->getType().getObjectType();
1407+
}
14051408

14061409
void printAllocRefInstBase(AllocRefInstBase *ARI) {
14071410
if (ARI->isObjC())
@@ -2418,6 +2421,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
24182421
void visitDeallocPackInst(DeallocPackInst *DI) {
24192422
*this << getIDAndType(DI->getOperand());
24202423
}
2424+
void visitDeallocPackMetadataInst(DeallocPackMetadataInst *DPMI) {
2425+
*this << getIDAndType(DPMI->getOperand());
2426+
}
24212427
void visitDeallocStackRefInst(DeallocStackRefInst *ESRL) {
24222428
*this << getIDAndType(ESRL->getOperand());
24232429
}

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, AllocPackMetadata)
9798
CONSTANT_OWNERSHIP_INST(None, PackLength)
9899
CONSTANT_OWNERSHIP_INST(None, BeginAccess)
99100
CONSTANT_OWNERSHIP_INST(None, BindMemory)

0 commit comments

Comments
 (0)