Skip to content

Commit 929b569

Browse files
Merge pull request #70068 from nate-chandler/cherrypick/release/5.10/rdar118059326
5.10: [SIL] Key consume checking off var_decl attr.
2 parents 5186b44 + cb1149d commit 929b569

File tree

121 files changed

+810
-555
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

121 files changed

+810
-555
lines changed

docs/SIL.rst

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4500,8 +4500,15 @@ live. This makes sense semantically since ``%1`` is modeling a new value with a
45004500
dependent lifetime on ``%0``.
45014501

45024502
The optional ``lexical`` attribute specifies that the operand corresponds to a
4503-
local variable in the Swift source, so special care must be taken when moving
4504-
the end_borrow.
4503+
local variable with a lexical lifetime in the Swift source, so special care
4504+
must be taken when moving the end_borrow. Compare to the ``var_decl``
4505+
attribute.
4506+
4507+
The optional ``pointer_escape`` attribute specifies that a pointer to the
4508+
operand escapes within the borrow scope introduced by this begin_borrow.
4509+
4510+
The optional ``var_decl`` attribute specifies that the operand corresponds to a
4511+
local variable in the Swift source.
45054512

45064513
This instruction is only valid in functions in Ownership SSA form.
45074514

@@ -6256,7 +6263,14 @@ values'. A move_value instruction is an instruction that introduces (or injects)
62566263
a type `T` into the move only value space.
62576264

62586265
The ``lexical`` attribute specifies that the value corresponds to a local
6259-
variable in the Swift source.
6266+
variable with a lexical lifetime in the Swift source. Compare to the
6267+
``var_decl`` attribute.
6268+
6269+
The optional ``pointer_escape`` attribute specifies that a pointer to the
6270+
operand escapes within the scope introduced by this move_value.
6271+
6272+
The optional ``var_decl`` attribute specifies that the operand corresponds to a
6273+
local variable in the Swift source.
62606274

62616275

62626276
drop_deinit

include/swift/SIL/SILBuilder.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -817,11 +817,13 @@ class SILBuilder {
817817

818818
BeginBorrowInst *createBeginBorrow(SILLocation Loc, SILValue LV,
819819
bool isLexical = false,
820-
bool hasPointerEscape = false) {
820+
bool hasPointerEscape = false,
821+
bool fromVarDecl = false) {
821822
assert(getFunction().hasOwnership());
822823
assert(!LV->getType().isAddress());
823-
return insert(new (getModule()) BeginBorrowInst(getSILDebugLocation(Loc),
824-
LV, isLexical, hasPointerEscape));
824+
return insert(new (getModule())
825+
BeginBorrowInst(getSILDebugLocation(Loc), LV, isLexical,
826+
hasPointerEscape, fromVarDecl));
825827
}
826828

827829
/// Convenience function for creating a load_borrow on non-trivial values and
@@ -1415,13 +1417,15 @@ class SILBuilder {
14151417

14161418
MoveValueInst *createMoveValue(SILLocation loc, SILValue operand,
14171419
bool isLexical = false,
1418-
bool hasPointerEscape = false) {
1420+
bool hasPointerEscape = false,
1421+
bool fromVarDecl = false) {
14191422
assert(getFunction().hasOwnership());
14201423
assert(!operand->getType().isTrivial(getFunction()) &&
14211424
"Should not be passing trivial values to this api. Use instead "
14221425
"emitMoveValueOperation");
1423-
return insert(new (getModule()) MoveValueInst(
1424-
getSILDebugLocation(loc), operand, isLexical, hasPointerEscape));
1426+
return insert(new (getModule())
1427+
MoveValueInst(getSILDebugLocation(loc), operand,
1428+
isLexical, hasPointerEscape, fromVarDecl));
14251429
}
14261430

14271431
DropDeinitInst *createDropDeinit(SILLocation loc, SILValue operand) {

include/swift/SIL/SILCloner.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,10 +1217,11 @@ void SILCloner<ImplClass>::visitBeginBorrowInst(BeginBorrowInst *Inst) {
12171217
return recordFoldedValue(Inst, getOpValue(Inst->getOperand()));
12181218
}
12191219

1220-
recordClonedInstruction(
1221-
Inst, getBuilder().createBeginBorrow(getOpLocation(Inst->getLoc()),
1222-
getOpValue(Inst->getOperand()),
1223-
Inst->isLexical()));
1220+
recordClonedInstruction(Inst,
1221+
getBuilder().createBeginBorrow(
1222+
getOpLocation(Inst->getLoc()),
1223+
getOpValue(Inst->getOperand()), Inst->isLexical(),
1224+
Inst->hasPointerEscape(), Inst->isFromVarDecl()));
12241225
}
12251226

12261227
template <typename ImplClass>
@@ -1930,9 +1931,9 @@ void SILCloner<ImplClass>::visitMoveValueInst(MoveValueInst *Inst) {
19301931
if (!getBuilder().hasOwnership()) {
19311932
return recordFoldedValue(Inst, getOpValue(Inst->getOperand()));
19321933
}
1933-
auto *MVI = getBuilder().createMoveValue(getOpLocation(Inst->getLoc()),
1934-
getOpValue(Inst->getOperand()),
1935-
Inst->isLexical());
1934+
auto *MVI = getBuilder().createMoveValue(
1935+
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1936+
Inst->isLexical(), Inst->hasPointerEscape(), Inst->isFromVarDecl());
19361937
MVI->setAllowsDiagnostics(Inst->getAllowDiagnostics());
19371938
recordClonedInstruction(Inst, MVI);
19381939
}

include/swift/SIL/SILInstruction.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4357,11 +4357,12 @@ class BeginBorrowInst
43574357
USE_SHARED_UINT8;
43584358

43594359
BeginBorrowInst(SILDebugLocation DebugLoc, SILValue LValue, bool isLexical,
4360-
bool hasPointerEscape)
4360+
bool hasPointerEscape, bool fromVarDecl)
43614361
: UnaryInstructionBase(DebugLoc, LValue,
43624362
LValue->getType().getObjectType()) {
43634363
sharedUInt8().BeginBorrowInst.lexical = isLexical;
43644364
sharedUInt8().BeginBorrowInst.pointerEscape = hasPointerEscape;
4365+
sharedUInt8().BeginBorrowInst.fromVarDecl = fromVarDecl;
43654366
}
43664367

43674368
public:
@@ -4387,6 +4388,10 @@ class BeginBorrowInst
43874388
sharedUInt8().BeginBorrowInst.pointerEscape = pointerEscape;
43884389
}
43894390

4391+
bool isFromVarDecl() const {
4392+
return sharedUInt8().BeginBorrowInst.fromVarDecl;
4393+
}
4394+
43904395
/// Return a range over all EndBorrow instructions for this BeginBorrow.
43914396
EndBorrowRange getEndBorrows() const;
43924397

@@ -8232,10 +8237,11 @@ class MoveValueInst
82328237
USE_SHARED_UINT8;
82338238

82348239
MoveValueInst(SILDebugLocation DebugLoc, SILValue operand, bool isLexical,
8235-
bool hasPointerEscape)
8240+
bool hasPointerEscape, bool fromVarDecl)
82368241
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {
82378242
sharedUInt8().MoveValueInst.lexical = isLexical;
82388243
sharedUInt8().MoveValueInst.pointerEscape = hasPointerEscape;
8244+
sharedUInt8().MoveValueInst.fromVarDecl = fromVarDecl;
82398245
}
82408246

82418247
public:
@@ -8258,6 +8264,8 @@ class MoveValueInst
82588264
void setHasPointerEscape(bool pointerEscape) {
82598265
sharedUInt8().MoveValueInst.pointerEscape = pointerEscape;
82608266
}
8267+
8268+
bool isFromVarDecl() const { return sharedUInt8().MoveValueInst.fromVarDecl; }
82618269
};
82628270

82638271
class DropDeinitInst

include/swift/SIL/SILNode.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ class alignas(8) SILNode :
241241

242242
SHARED_FIELD(BeginBorrowInst, uint8_t
243243
lexical : 1,
244-
pointerEscape : 1);
244+
pointerEscape : 1,
245+
fromVarDecl : 1);
245246

246247
SHARED_FIELD(CopyAddrInst, uint8_t
247248
isTakeOfSrc : 1,
@@ -269,7 +270,8 @@ class alignas(8) SILNode :
269270
SHARED_FIELD(MoveValueInst, uint8_t
270271
allowDiagnostics : 1,
271272
lexical : 1,
272-
pointerEscape : 1);
273+
pointerEscape : 1,
274+
fromVarDecl : 1);
273275

274276
// Do not use `_sharedUInt8_private` outside of SILNode.
275277
} _sharedUInt8_private;

lib/SIL/IR/SILPrinter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
17011701
if (BBI->hasPointerEscape()) {
17021702
*this << "[pointer_escape] ";
17031703
}
1704+
if (BBI->isFromVarDecl()) {
1705+
*this << "[var_decl] ";
1706+
}
17041707
*this << getIDAndType(BBI->getOperand());
17051708
}
17061709

@@ -2074,6 +2077,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
20742077
*this << "[lexical] ";
20752078
if (I->hasPointerEscape())
20762079
*this << "[pointer_escape] ";
2080+
if (I->isFromVarDecl())
2081+
*this << "[var_decl] ";
20772082
*this << getIDAndType(I->getOperand());
20782083
}
20792084

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3801,6 +3801,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38013801
bool allowsDiagnostics = false;
38023802
bool isLexical = false;
38033803
bool hasPointerEscape = false;
3804+
bool fromVarDecl = false;
38043805

38053806
StringRef AttrName;
38063807
SourceLoc AttrLoc;
@@ -3811,6 +3812,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38113812
isLexical = true;
38123813
else if (AttrName == "pointer_escape")
38133814
hasPointerEscape = true;
3815+
else if (AttrName == "var_decl")
3816+
fromVarDecl = true;
38143817
else {
38153818
P.diagnose(InstLoc.getSourceLoc(),
38163819
diag::sil_invalid_attribute_for_instruction, AttrName,
@@ -3823,7 +3826,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38233826
return true;
38243827
if (parseSILDebugLocation(InstLoc, B))
38253828
return true;
3826-
auto *MVI = B.createMoveValue(InstLoc, Val, isLexical, hasPointerEscape);
3829+
auto *MVI = B.createMoveValue(InstLoc, Val, isLexical, hasPointerEscape,
3830+
fromVarDecl);
38273831
MVI->setAllowsDiagnostics(allowsDiagnostics);
38283832
ResultVal = MVI;
38293833
break;
@@ -4032,6 +4036,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
40324036

40334037
bool isLexical = false;
40344038
bool hasPointerEscape = false;
4039+
bool fromVarDecl = false;
40354040

40364041
StringRef AttrName;
40374042
SourceLoc AttrLoc;
@@ -4040,6 +4045,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
40404045
isLexical = true;
40414046
else if (AttrName == "pointer_escape")
40424047
hasPointerEscape = true;
4048+
else if (AttrName == "var_decl")
4049+
fromVarDecl = true;
40434050
else {
40444051
P.diagnose(InstLoc.getSourceLoc(),
40454052
diag::sil_invalid_attribute_for_instruction, AttrName,
@@ -4052,7 +4059,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
40524059
parseSILDebugLocation(InstLoc, B))
40534060
return true;
40544061

4055-
ResultVal = B.createBeginBorrow(InstLoc, Val, isLexical, hasPointerEscape);
4062+
ResultVal = B.createBeginBorrow(InstLoc, Val, isLexical, hasPointerEscape,
4063+
fromVarDecl);
40564064
break;
40574065
}
40584066

lib/SILGen/SILGenDecl.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,9 @@ class LocalVariableInitialization : public SingleBufferInitialization {
566566
//
567567
// Only add a lexical lifetime to the box if the the variable it stores
568568
// requires one.
569-
if (lifetime.isLexical()) {
570-
Box = SGF.B.createBeginBorrow(decl, Box, /*isLexical=*/true);
571-
}
569+
Box = SGF.B.createBeginBorrow(
570+
decl, Box, /*isLexical=*/lifetime.isLexical(),
571+
/*hasPointerEscape=*/false, /*fromVarDecl=*/true);
572572
}
573573

574574
Addr = SGF.B.createProjectBox(decl, Box, 0);
@@ -835,16 +835,17 @@ class LetValueInitialization : public Initialization {
835835
// Otherwise, if we do not have a no implicit copy variable, just follow
836836
// the "normal path": perform a lexical borrow if the lifetime is lexical.
837837
if (!vd->isNoImplicitCopy()) {
838-
if (SGF.F.getLifetime(vd, value->getType()).isLexical())
839-
return SGF.B.createBeginBorrow(PrologueLoc, value, /*isLexical*/ true);
840-
else
841-
return value;
838+
return SGF.B.createBeginBorrow(
839+
PrologueLoc, value,
840+
/*isLexical=*/SGF.F.getLifetime(vd, value->getType()).isLexical(),
841+
/*hasPointerEscape=*/false, /*fromVarDecl=*/true);
842842
}
843843

844844
// If we have a no implicit copy lexical, emit the instruction stream so
845845
// that the move checker knows to check this variable.
846-
value = SGF.B.createBeginBorrow(PrologueLoc, value,
847-
/*isLexical*/ true);
846+
value = SGF.B.createBeginBorrow(
847+
PrologueLoc, value,
848+
/*isLexical*/ true, /*hasPointerEscape=*/false, /*fromVarDecl=*/true);
848849
value = SGF.B.createCopyValue(PrologueLoc, value);
849850
value = SGF.B.createOwnedCopyableToMoveOnlyWrapperValue(PrologueLoc, value);
850851
return SGF.B.createMarkUnresolvedNonCopyableValueInst(
@@ -2166,11 +2167,6 @@ void SILGenFunction::destroyLocalVariable(SILLocation silLoc, VarDecl *vd) {
21662167
return;
21672168
}
21682169

2169-
if (!F.getLifetime(vd, Val->getType()).isLexical()) {
2170-
B.emitDestroyValueOperation(silLoc, Val);
2171-
return;
2172-
}
2173-
21742170
// This handles any case where we copy + begin_borrow or copyable_to_moveonly
21752171
// + begin_borrow. In either case we just need to end the lifetime of the
21762172
// begin_borrow's operand.

lib/SILOptimizer/Mandatory/ConsumeOperatorCopyableValuesChecker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ bool ConsumeOperatorCopyableValuesChecker::check() {
410410
for (auto &block : *fn) {
411411
for (auto &ii : block) {
412412
if (auto *bbi = dyn_cast<BeginBorrowInst>(&ii)) {
413-
if (bbi->isLexical() && !bbi->getType().isMoveOnly()) {
413+
if (bbi->isFromVarDecl() && !bbi->getType().isMoveOnly()) {
414414
LLVM_DEBUG(llvm::dbgs()
415415
<< "Found lexical lifetime to check: " << *bbi);
416416
valuesToCheck.insert(bbi);

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3004,7 +3004,7 @@ SILValue LifetimeChecker::handleConditionalInitAssign() {
30043004
///
30053005
/// %box = alloc_box
30063006
/// %mark_uninit = mark_uninitialized %box
3007-
/// %lifetime = begin_borrow [lexical] %mark_uninit
3007+
/// %lifetime = begin_borrow [var_decl] %mark_uninit
30083008
/// %proj_box = project_box %lifetime
30093009
///
30103010
/// We are replacing a
@@ -3024,7 +3024,7 @@ SILValue LifetimeChecker::handleConditionalInitAssign() {
30243024
/// Consequently, it's not sufficient to just replace the destroy_value
30253025
/// %mark_uninit with a destroy_addr %proj_box (or to replace it with a diamond
30263026
/// where one branch has that destroy_addr) because the destroy_addr is a use
3027-
/// of %proj_box which must be within the lexical lifetime of the box.
3027+
/// of %proj_box which must be within the var_decl lifetime of the box.
30283028
///
30293029
/// On the other side, we are hemmed in by the fact that the end_borrow must
30303030
/// precede the dealloc_box which will be created in the diamond. So we
@@ -3060,12 +3060,12 @@ static bool adjustAllocBoxEndBorrow(SILInstruction *previous,
30603060
if (!pbi)
30613061
return false;
30623062

3063-
// This fixup only applies if we're destroying a project_box of the lexical
3063+
// This fixup only applies if we're destroying a project_box of the var_decl
30643064
// lifetime of an alloc_box.
30653065
auto *lifetime = dyn_cast<BeginBorrowInst>(pbi->getOperand());
30663066
if (!lifetime)
30673067
return false;
3068-
assert(lifetime->isLexical());
3068+
assert(lifetime->isFromVarDecl());
30693069
assert(isa<AllocBoxInst>(
30703070
cast<MarkUninitializedInst>(lifetime->getOperand())->getOperand()));
30713071

0 commit comments

Comments
 (0)