Skip to content

Commit 126022f

Browse files
Merge pull request #70054 from nate-chandler/rdar118059326
[SIL] Key consume checking off var_decl attr.
2 parents 0eb71d1 + 9861422 commit 126022f

File tree

120 files changed

+792
-546
lines changed

Some content is hidden

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

120 files changed

+792
-546
lines changed

docs/SIL.rst

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

45164516
The optional ``lexical`` attribute specifies that the operand corresponds to a
4517-
local variable in the Swift source, so special care must be taken when moving
4518-
the end_borrow.
4517+
local variable with a lexical lifetime in the Swift source, so special care
4518+
must be taken when moving the end_borrow. Compare to the ``var_decl``
4519+
attribute.
4520+
4521+
The optional ``pointer_escape`` attribute specifies that a pointer to the
4522+
operand escapes within the borrow scope introduced by this begin_borrow.
4523+
4524+
The optional ``var_decl`` attribute specifies that the operand corresponds to a
4525+
local variable in the Swift source.
45194526

45204527
This instruction is only valid in functions in Ownership SSA form.
45214528

@@ -6373,7 +6380,14 @@ values'. A move_value instruction is an instruction that introduces (or injects)
63736380
a type `T` into the move only value space.
63746381

63756382
The ``lexical`` attribute specifies that the value corresponds to a local
6376-
variable in the Swift source.
6383+
variable with a lexical lifetime in the Swift source. Compare to the
6384+
``var_decl`` attribute.
6385+
6386+
The optional ``pointer_escape`` attribute specifies that a pointer to the
6387+
operand escapes within the scope introduced by this move_value.
6388+
6389+
The optional ``var_decl`` attribute specifies that the operand corresponds to a
6390+
local variable in the Swift source.
63776391

63786392

63796393
drop_deinit

include/swift/SIL/SILBuilder.h

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

805805
BeginBorrowInst *createBeginBorrow(SILLocation Loc, SILValue LV,
806806
bool isLexical = false,
807-
bool hasPointerEscape = false) {
807+
bool hasPointerEscape = false,
808+
bool fromVarDecl = false) {
808809
assert(getFunction().hasOwnership());
809810
assert(!LV->getType().isAddress());
810-
return insert(new (getModule()) BeginBorrowInst(getSILDebugLocation(Loc),
811-
LV, isLexical, hasPointerEscape));
811+
return insert(new (getModule())
812+
BeginBorrowInst(getSILDebugLocation(Loc), LV, isLexical,
813+
hasPointerEscape, fromVarDecl));
812814
}
813815

814816
/// Convenience function for creating a load_borrow on non-trivial values and
@@ -1402,13 +1404,15 @@ class SILBuilder {
14021404

14031405
MoveValueInst *createMoveValue(SILLocation loc, SILValue operand,
14041406
bool isLexical = false,
1405-
bool hasPointerEscape = false) {
1407+
bool hasPointerEscape = false,
1408+
bool fromVarDecl = false) {
14061409
assert(getFunction().hasOwnership());
14071410
assert(!operand->getType().isTrivial(getFunction()) &&
14081411
"Should not be passing trivial values to this api. Use instead "
14091412
"emitMoveValueOperation");
1410-
return insert(new (getModule()) MoveValueInst(
1411-
getSILDebugLocation(loc), operand, isLexical, hasPointerEscape));
1413+
return insert(new (getModule())
1414+
MoveValueInst(getSILDebugLocation(loc), operand,
1415+
isLexical, hasPointerEscape, fromVarDecl));
14121416
}
14131417

14141418
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
@@ -4398,11 +4398,12 @@ class BeginBorrowInst
43984398
USE_SHARED_UINT8;
43994399

44004400
BeginBorrowInst(SILDebugLocation DebugLoc, SILValue LValue, bool isLexical,
4401-
bool hasPointerEscape)
4401+
bool hasPointerEscape, bool fromVarDecl)
44024402
: UnaryInstructionBase(DebugLoc, LValue,
44034403
LValue->getType().getObjectType()) {
44044404
sharedUInt8().BeginBorrowInst.lexical = isLexical;
44054405
sharedUInt8().BeginBorrowInst.pointerEscape = hasPointerEscape;
4406+
sharedUInt8().BeginBorrowInst.fromVarDecl = fromVarDecl;
44064407
}
44074408

44084409
public:
@@ -4428,6 +4429,10 @@ class BeginBorrowInst
44284429
sharedUInt8().BeginBorrowInst.pointerEscape = pointerEscape;
44294430
}
44304431

4432+
bool isFromVarDecl() const {
4433+
return sharedUInt8().BeginBorrowInst.fromVarDecl;
4434+
}
4435+
44314436
/// Return a range over all EndBorrow instructions for this BeginBorrow.
44324437
EndBorrowRange getEndBorrows() const;
44334438

@@ -8374,10 +8379,11 @@ class MoveValueInst
83748379
USE_SHARED_UINT8;
83758380

83768381
MoveValueInst(SILDebugLocation DebugLoc, SILValue operand, bool isLexical,
8377-
bool hasPointerEscape)
8382+
bool hasPointerEscape, bool fromVarDecl)
83788383
: UnaryInstructionBase(DebugLoc, operand, operand->getType()) {
83798384
sharedUInt8().MoveValueInst.lexical = isLexical;
83808385
sharedUInt8().MoveValueInst.pointerEscape = hasPointerEscape;
8386+
sharedUInt8().MoveValueInst.fromVarDecl = fromVarDecl;
83818387
}
83828388

83838389
public:
@@ -8400,6 +8406,8 @@ class MoveValueInst
84008406
void setHasPointerEscape(bool pointerEscape) {
84018407
sharedUInt8().MoveValueInst.pointerEscape = pointerEscape;
84028408
}
8409+
8410+
bool isFromVarDecl() const { return sharedUInt8().MoveValueInst.fromVarDecl; }
84038411
};
84048412

84058413
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,
@@ -272,7 +273,8 @@ class alignas(8) SILNode :
272273
SHARED_FIELD(MoveValueInst, uint8_t
273274
allowDiagnostics : 1,
274275
lexical : 1,
275-
pointerEscape : 1);
276+
pointerEscape : 1,
277+
fromVarDecl : 1);
276278

277279
// Do not use `_sharedUInt8_private` outside of SILNode.
278280
} _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
@@ -3846,6 +3846,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38463846
bool allowsDiagnostics = false;
38473847
bool isLexical = false;
38483848
bool hasPointerEscape = false;
3849+
bool fromVarDecl = false;
38493850

38503851
StringRef AttrName;
38513852
SourceLoc AttrLoc;
@@ -3856,6 +3857,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38563857
isLexical = true;
38573858
else if (AttrName == "pointer_escape")
38583859
hasPointerEscape = true;
3860+
else if (AttrName == "var_decl")
3861+
fromVarDecl = true;
38593862
else {
38603863
P.diagnose(InstLoc.getSourceLoc(),
38613864
diag::sil_invalid_attribute_for_instruction, AttrName,
@@ -3868,7 +3871,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38683871
return true;
38693872
if (parseSILDebugLocation(InstLoc, B))
38703873
return true;
3871-
auto *MVI = B.createMoveValue(InstLoc, Val, isLexical, hasPointerEscape);
3874+
auto *MVI = B.createMoveValue(InstLoc, Val, isLexical, hasPointerEscape,
3875+
fromVarDecl);
38723876
MVI->setAllowsDiagnostics(allowsDiagnostics);
38733877
ResultVal = MVI;
38743878
break;
@@ -4077,6 +4081,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
40774081

40784082
bool isLexical = false;
40794083
bool hasPointerEscape = false;
4084+
bool fromVarDecl = false;
40804085

40814086
StringRef AttrName;
40824087
SourceLoc AttrLoc;
@@ -4085,6 +4090,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
40854090
isLexical = true;
40864091
else if (AttrName == "pointer_escape")
40874092
hasPointerEscape = true;
4093+
else if (AttrName == "var_decl")
4094+
fromVarDecl = true;
40884095
else {
40894096
P.diagnose(InstLoc.getSourceLoc(),
40904097
diag::sil_invalid_attribute_for_instruction, AttrName,
@@ -4097,7 +4104,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
40974104
parseSILDebugLocation(InstLoc, B))
40984105
return true;
40994106

4100-
ResultVal = B.createBeginBorrow(InstLoc, Val, isLexical, hasPointerEscape);
4107+
ResultVal = B.createBeginBorrow(InstLoc, Val, isLexical, hasPointerEscape,
4108+
fromVarDecl);
41014109
break;
41024110
}
41034111

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
@@ -3028,7 +3028,7 @@ SILValue LifetimeChecker::handleConditionalInitAssign() {
30283028
///
30293029
/// %box = alloc_box
30303030
/// %mark_uninit = mark_uninitialized %box
3031-
/// %lifetime = begin_borrow [lexical] %mark_uninit
3031+
/// %lifetime = begin_borrow [var_decl] %mark_uninit
30323032
/// %proj_box = project_box %lifetime
30333033
///
30343034
/// We are replacing a
@@ -3048,7 +3048,7 @@ SILValue LifetimeChecker::handleConditionalInitAssign() {
30483048
/// Consequently, it's not sufficient to just replace the destroy_value
30493049
/// %mark_uninit with a destroy_addr %proj_box (or to replace it with a diamond
30503050
/// where one branch has that destroy_addr) because the destroy_addr is a use
3051-
/// of %proj_box which must be within the lexical lifetime of the box.
3051+
/// of %proj_box which must be within the var_decl lifetime of the box.
30523052
///
30533053
/// On the other side, we are hemmed in by the fact that the end_borrow must
30543054
/// precede the dealloc_box which will be created in the diamond. So we
@@ -3084,12 +3084,12 @@ static bool adjustAllocBoxEndBorrow(SILInstruction *previous,
30843084
if (!pbi)
30853085
return false;
30863086

3087-
// This fixup only applies if we're destroying a project_box of the lexical
3087+
// This fixup only applies if we're destroying a project_box of the var_decl
30883088
// lifetime of an alloc_box.
30893089
auto *lifetime = dyn_cast<BeginBorrowInst>(pbi->getOperand());
30903090
if (!lifetime)
30913091
return false;
3092-
assert(lifetime->isLexical());
3092+
assert(lifetime->isFromVarDecl());
30933093
assert(isa<AllocBoxInst>(
30943094
cast<MarkUninitializedInst>(lifetime->getOperand())->getOperand()));
30953095

0 commit comments

Comments
 (0)