Skip to content

Commit b150a48

Browse files
committed
[SIL] Add dead_end flag to dealloc_box.
1 parent a8cc3bf commit b150a48

File tree

15 files changed

+133
-21
lines changed

15 files changed

+133
-21
lines changed

docs/SIL.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4179,7 +4179,7 @@ dealloc_box
41794179
```````````
41804180
::
41814181

4182-
sil-instruction ::= 'dealloc_box' sil-operand
4182+
sil-instruction ::= 'dealloc_box' '[dead_end]'? sil-operand
41834183

41844184
dealloc_box %0 : $@box T
41854185

@@ -4192,6 +4192,9 @@ This does not destroy the boxed value. The contents of the
41924192
value must have been fully uninitialized or destroyed before
41934193
``dealloc_box`` is applied.
41944194

4195+
The optional ``dead_end`` attribute specifies that this instruction was created
4196+
during lifetime completion and is eligible for deletion during OSSA lowering.
4197+
41954198
project_box
41964199
```````````
41974200
::

include/swift/SIL/SILBuilder.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,10 +2387,10 @@ class SILBuilder {
23872387
return insert(new (getModule()) DeallocPartialRefInst(
23882388
getSILDebugLocation(Loc), operand, metatype));
23892389
}
2390-
DeallocBoxInst *createDeallocBox(SILLocation Loc,
2391-
SILValue operand) {
2392-
return insert(new (getModule()) DeallocBoxInst(
2393-
getSILDebugLocation(Loc), operand));
2390+
DeallocBoxInst *createDeallocBox(SILLocation Loc, SILValue operand,
2391+
IsDeadEnd_t isDeadEnd = IsntDeadEnd) {
2392+
return insert(new (getModule()) DeallocBoxInst(getSILDebugLocation(Loc),
2393+
operand, isDeadEnd));
23942394
}
23952395
DeallocExistentialBoxInst *createDeallocExistentialBox(SILLocation Loc,
23962396
CanType concreteType,

include/swift/SIL/SILCloner.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3175,7 +3175,8 @@ SILCloner<ImplClass>::visitDeallocBoxInst(DeallocBoxInst *Inst) {
31753175
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
31763176
recordClonedInstruction(
31773177
Inst, getBuilder().createDeallocBox(getOpLocation(Inst->getLoc()),
3178-
getOpValue(Inst->getOperand())));
3178+
getOpValue(Inst->getOperand()),
3179+
Inst->isDeadEnd()));
31793180
}
31803181

31813182
template<typename ImplClass>

include/swift/SIL/SILInstruction.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9463,8 +9463,19 @@ class DeallocBoxInst
94639463
{
94649464
friend SILBuilder;
94659465

9466-
DeallocBoxInst(SILDebugLocation DebugLoc, SILValue operand)
9467-
: UnaryInstructionBase(DebugLoc, operand) {}
9466+
USE_SHARED_UINT8;
9467+
9468+
public:
9469+
IsDeadEnd_t isDeadEnd() const {
9470+
return IsDeadEnd_t(sharedUInt8().DeallocBoxInst.deadEnd);
9471+
}
9472+
9473+
private:
9474+
DeallocBoxInst(SILDebugLocation DebugLoc, SILValue operand,
9475+
IsDeadEnd_t isDeadEnd)
9476+
: UnaryInstructionBase(DebugLoc, operand) {
9477+
sharedUInt8().DeallocBoxInst.deadEnd = isDeadEnd;
9478+
}
94689479
};
94699480

94709481
/// Deallocate memory allocated for a boxed existential container created by

include/swift/SIL/SILNode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ class alignas(8) SILNode :
248248
fromVarDecl : 1,
249249
fixed : 1);
250250

251+
SHARED_FIELD(DeallocBoxInst, uint8_t
252+
deadEnd : 1);
253+
251254
SHARED_FIELD(CopyAddrInst, uint8_t
252255
isTakeOfSrc : 1,
253256
isInitializationOfDest : 1);

lib/SIL/IR/SILPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2649,6 +2649,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
26492649
*this << getIDAndType(DPI->getMetatype());
26502650
}
26512651
void visitDeallocBoxInst(DeallocBoxInst *DI) {
2652+
if (DI->isDeadEnd())
2653+
*this << "[dead_end] ";
26522654
*this << getIDAndType(DI->getOperand());
26532655
}
26542656
void visitDestroyAddrInst(DestroyAddrInst *DI) {

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4971,12 +4971,15 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
49714971
ResultVal = B.createDeallocPartialRef(InstLoc, Instance, Metatype);
49724972
break;
49734973
}
4974-
case SILInstructionKind::DeallocBoxInst:
4975-
if (parseTypedValueRef(Val, B) || parseSILDebugLocation(InstLoc, B))
4976-
return true;
4974+
case SILInstructionKind::DeallocBoxInst: {
4975+
bool isDeadEnd = false;
4976+
if (parseSILOptional(isDeadEnd, *this, "dead_end") ||
4977+
parseTypedValueRef(Val, B) || parseSILDebugLocation(InstLoc, B))
4978+
return true;
49774979

4978-
ResultVal = B.createDeallocBox(InstLoc, Val);
4979-
break;
4980+
ResultVal = B.createDeallocBox(InstLoc, Val, IsDeadEnd_t(isDeadEnd));
4981+
break;
4982+
}
49804983
case SILInstructionKind::ValueMetatypeInst:
49814984
case SILInstructionKind::ExistentialMetatypeInst: {
49824985
SILType Ty;

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3809,6 +3809,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
38093809
require(boxTy, "operand must be a @box type");
38103810
require(DI->getOperand()->getType().isObject(),
38113811
"operand must be an object");
3812+
if (DI->isDeadEnd()) {
3813+
require(getDeadEndBlocks().isDeadEnd(DI->getParentBlock()),
3814+
"a dead_end dealloc_box must be in a dead-end block");
3815+
}
38123816
}
38133817

38143818
void checkDestroyAddrInst(DestroyAddrInst *DI) {

lib/Serialization/DeserializeSIL.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,14 +1455,18 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
14551455
ONETYPE_ONEOPERAND_INST(ExistentialMetatype)
14561456
ONETYPE_ONEOPERAND_INST(ProjectExistentialBox)
14571457
#undef ONETYPE_ONEOPERAND_INST
1458-
case SILInstructionKind::DeallocBoxInst:
1458+
case SILInstructionKind::DeallocBoxInst: {
14591459
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
14601460
"Layout should be OneTypeOneOperand.");
1461+
IsDeadEnd_t isDeadEnd = IsDeadEnd_t(Attr & 0x1);
14611462
ResultInst = Builder.createDeallocBox(
1462-
Loc, getLocalValue(Builder.maybeGetFunction(), ValID,
1463-
getSILType(MF->getType(TyID2),
1464-
(SILValueCategory)TyCategory2, Fn)));
1463+
Loc,
1464+
getLocalValue(
1465+
Builder.maybeGetFunction(), ValID,
1466+
getSILType(MF->getType(TyID2), (SILValueCategory)TyCategory2, Fn)),
1467+
isDeadEnd);
14651468
break;
1469+
}
14661470
case SILInstructionKind::OpenExistentialAddrInst:
14671471
assert(RecordKind == SIL_ONE_TYPE_ONE_OPERAND &&
14681472
"Layout should be OneTypeOneOperand.");

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 879; // dead_end flag on destroy_value
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 880; // dead_end flag on dealloc_box
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///

0 commit comments

Comments
 (0)