Skip to content

Commit b4f783e

Browse files
committed
[SIL] Added var_decl flag to borrows/moves.
1 parent 1518229 commit b4f783e

File tree

16 files changed

+89
-34
lines changed

16 files changed

+89
-34
lines changed

docs/SIL.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4514,12 +4514,16 @@ 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.
45194520

45204521
The optional ``pointer_escape`` attribute specifies that a pointer to the
45214522
operand escapes within the borrow scope introduced by this begin_borrow.
45224523

4524+
The optional ``var_decl`` attribute specifies that the operand corresponds to a
4525+
local variable in the Swift source.
4526+
45234527
This instruction is only valid in functions in Ownership SSA form.
45244528

45254529
end_borrow
@@ -6376,11 +6380,15 @@ values'. A move_value instruction is an instruction that introduces (or injects)
63766380
a type `T` into the move only value space.
63776381

63786382
The ``lexical`` attribute specifies that the value corresponds to a local
6379-
variable in the Swift source.
6383+
variable with a lexical lifetime in the Swift source. Compare to the
6384+
``var_decl`` attribute.
63806385

63816386
The optional ``pointer_escape`` attribute specifies that a pointer to the
63826387
operand escapes within the scope introduced by this move_value.
63836388

6389+
The optional ``var_decl`` attribute specifies that the operand corresponds to a
6390+
local variable in the Swift source.
6391+
63846392

63856393
drop_deinit
63866394
```````````

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: 6 additions & 5 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(
1222-
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1223-
Inst->isLexical(), Inst->hasPointerEscape()));
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>
@@ -1932,7 +1933,7 @@ void SILCloner<ImplClass>::visitMoveValueInst(MoveValueInst *Inst) {
19321933
}
19331934
auto *MVI = getBuilder().createMoveValue(
19341935
getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()),
1935-
Inst->isLexical(), Inst->hasPointerEscape());
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/Serialization/DeserializeSIL.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2154,11 +2154,12 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
21542154
assert(RecordKind == SIL_ONE_OPERAND && "Layout should be OneOperand.");
21552155
bool isLexical = Attr & 0x1;
21562156
bool hasPointerEscape = (Attr >> 1) & 0x1;
2157+
bool fromVarDecl = (Attr >> 2) & 0x1;
21572158
ResultInst = Builder.createBeginBorrow(
21582159
Loc,
21592160
getLocalValue(ValID, getSILType(MF->getType(TyID),
21602161
(SILValueCategory)TyCategory, Fn)),
2161-
isLexical, hasPointerEscape);
2162+
isLexical, hasPointerEscape, fromVarDecl);
21622163
break;
21632164
}
21642165

@@ -2245,10 +2246,11 @@ bool SILDeserializer::readSILInstruction(SILFunction *Fn,
22452246
bool AllowsDiagnostics = Attr & 0x1;
22462247
bool IsLexical = (Attr >> 1) & 0x1;
22472248
bool IsEscaping = (Attr >> 2) & 0x1;
2249+
bool IsFromVarDecl = (Attr >> 3) & 0x1;
22482250
auto *MVI = Builder.createMoveValue(
22492251
Loc,
22502252
getLocalValue(ValID, getSILType(Ty, (SILValueCategory)TyCategory, Fn)),
2251-
IsLexical, IsEscaping);
2253+
IsLexical, IsEscaping, IsFromVarDecl);
22522254
MVI->setAllowsDiagnostics(AllowsDiagnostics);
22532255
ResultInst = MVI;
22542256
break;

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 = 819; // _resultDependsOnSelf
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 820; // begin_borrow/move_value [var_decl]
6262

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

lib/Serialization/SILFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ namespace sil_block {
435435
// SIL instructions with one typed valueref. (dealloc_stack, return)
436436
using SILOneOperandLayout =
437437
BCRecordLayout<SIL_ONE_OPERAND, SILInstOpCodeField,
438-
BCFixed<3>, // Optional attributes
438+
BCFixed<4>, // Optional attributes
439439
TypeIDField, SILTypeCategoryField, ValueIDField>;
440440

441441
using SILOneOperandExtraAttributeLayout = BCRecordLayout<

lib/Serialization/SerializeSIL.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,12 +1525,14 @@ void SILSerializer::writeSILInstruction(const SILInstruction &SI) {
15251525
} else if (auto *ECMI = dyn_cast<EndCOWMutationInst>(&SI)) {
15261526
Attr = ECMI->doKeepUnique();
15271527
} else if (auto *BBI = dyn_cast<BeginBorrowInst>(&SI)) {
1528-
Attr =
1529-
unsigned(BBI->isLexical()) | unsigned(BBI->hasPointerEscape() << 1);
1528+
Attr = unsigned(BBI->isLexical()) |
1529+
(unsigned(BBI->hasPointerEscape() << 1)) |
1530+
(unsigned(BBI->isFromVarDecl() << 2));
15301531
} else if (auto *MVI = dyn_cast<MoveValueInst>(&SI)) {
15311532
Attr = unsigned(MVI->getAllowDiagnostics()) |
15321533
(unsigned(MVI->isLexical() << 1)) |
1533-
(unsigned(MVI->hasPointerEscape() << 2));
1534+
(unsigned(MVI->hasPointerEscape() << 2)) |
1535+
(unsigned(MVI->isFromVarDecl() << 3));
15341536
} else if (auto *I = dyn_cast<MarkUnresolvedNonCopyableValueInst>(&SI)) {
15351537
Attr = unsigned(I->getCheckKind());
15361538
} else if (auto *I = dyn_cast<MarkUnresolvedReferenceBindingInst>(&SI)) {

test/SIL/Parser/basic2.sil

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ bb0(%0 : @owned $Builtin.NativeObject):
5252
// CHECK-NEXT: [[REGISTER_4:%[^,]+]] = move_value [allows_diagnostics] [lexical] [[REGISTER_3]]
5353
// CHECK-NEXT: [[REGISTER_5:%[^,]+]] = move_value [allows_diagnostics] [lexical] [[REGISTER_4]]
5454
// CHECK-NEXT: [[REGISTER_6:%[^,]+]] = move_value [allows_diagnostics] [lexical] [pointer_escape] [[REGISTER_5]]
55-
// CHECK-NEXT: return [[REGISTER_6]]
55+
// CHECK-NEXT: [[REGISTER_7:%[^,]+]] = move_value [var_decl] [[REGISTER_6]]
56+
// CHECK-NEXT: return [[REGISTER_7]]
5657
// CHECK-NEXT: } // end sil function 'test_movevalue_parsing'
5758
sil [ossa] @test_movevalue_parsing : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
5859
bb0(%0 : @owned $Builtin.NativeObject):
@@ -62,7 +63,8 @@ bb0(%0 : @owned $Builtin.NativeObject):
6263
%4 = move_value [allows_diagnostics] [lexical] %3 : $Builtin.NativeObject
6364
%5 = move_value [lexical] [allows_diagnostics] %4 : $Builtin.NativeObject
6465
%6 = move_value [pointer_escape] [lexical] [allows_diagnostics] %5 : $Builtin.NativeObject
65-
return %6 : $Builtin.NativeObject
66+
%7 = move_value [var_decl] %6 : $Builtin.NativeObject
67+
return %7 : $Builtin.NativeObject
6668
}
6769

6870
// CHECK-LABEL: sil [ossa] @test_debug_value_alloc_stack_moved : $@convention(thin) (@owned Builtin.NativeObject) -> () {
@@ -284,4 +286,4 @@ bb0(%0 : $*Builtin.NativeObject, %1 : @owned $Builtin.NativeObject):
284286
dealloc_stack %2 : $*((), (Builtin.NativeObject, Builtin.NativeObject))
285287
%9999 = tuple ()
286288
return %9999 : $()
287-
}
289+
}

test/SIL/Parser/borrow.sil

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,16 @@ class C {}
3333
// CHECK-LABEL: sil [ossa] @foo
3434
// CHECK: begin_borrow {{%[^,]+}}
3535
// CHECK: begin_borrow [lexical] {{%[^,]+}}
36+
// CHECK: begin_borrow [var_decl] {{%[^,]+}}
3637
// CHECK-LABEL: } // end sil function 'foo'
3738
sil [ossa] @foo : $@convention(thin) () -> () {
3839
%instance = alloc_ref $C
3940
%guaranteed_c2 = begin_borrow %instance : $C
4041
end_borrow %guaranteed_c2 : $C
4142
%guaranteed_c = begin_borrow [lexical] %instance : $C
4243
end_borrow %guaranteed_c : $C
44+
%guaranteed_c3 = begin_borrow [var_decl] %instance : $C
45+
end_borrow %guaranteed_c3 : $C
4346
destroy_value %instance : $C
4447
%res = tuple ()
4548
return %res : $()

test/SIL/Serialization/basic.sil

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ bb0:
9191
// CHECK-NEXT: [[REGISTER_3:%[^,]+]] = move_value [lexical] [[REGISTER_2]]
9292
// CHECK-NEXT: [[REGISTER_4:%[^,]+]] = move_value [allows_diagnostics] [lexical] [[REGISTER_3]]
9393
// CHECK-NEXT: [[REGISTER_5:%[^,]+]] = move_value [allows_diagnostics] [lexical] [[REGISTER_4]]
94-
// CHECK-NEXT: return [[REGISTER_5]]
94+
// CHECK-NEXT: [[REGISTER_6:%[^,]+]] = move_value [var_decl] [[REGISTER_5]]
95+
// CHECK-NEXT: return [[REGISTER_6]]
9596
// CHECK-NEXT: } // end sil function 'test_movevalue_parsing'
9697
sil [ossa] @test_movevalue_parsing : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
9798
bb0(%0 : @owned $Builtin.NativeObject):
@@ -100,7 +101,8 @@ bb0(%0 : @owned $Builtin.NativeObject):
100101
%3 = move_value [lexical] %2 : $Builtin.NativeObject
101102
%4 = move_value [allows_diagnostics] [lexical] %3 : $Builtin.NativeObject
102103
%5 = move_value [lexical] [allows_diagnostics] %4 : $Builtin.NativeObject
103-
return %5 : $Builtin.NativeObject
104+
%6 = move_value [var_decl] %5 : $Builtin.NativeObject
105+
return %6 : $Builtin.NativeObject
104106
}
105107

106108
// CHECK-LABEL: sil [no_allocation] [ossa] @test_no_allocation : $@convention(thin) () -> () {

test/SIL/Serialization/borrow.sil

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ import Builtin
1111
// CHECK-LABEL: sil [serialized] [ossa] @begin_borrow_test
1212
// CHECK: begin_borrow [lexical] {{%[^,]+}}
1313
// CHECK: begin_borrow {{%[^,]+}}
14+
// CHECK: begin_borrow [var_decl] {{%[^,]+}}
1415
// CHECK: } // end sil function 'begin_borrow_test'
1516
sil [serialized] [ossa] @begin_borrow_test : $@convention(thin) () -> () {
1617
%instance = alloc_ref $C
1718
%guaranteed_c = begin_borrow [lexical] %instance : $C
1819
end_borrow %guaranteed_c : $C
1920
%guaranteed_c2 = begin_borrow %instance : $C
2021
end_borrow %guaranteed_c2 : $C
22+
%guaranteed_c3 = begin_borrow [var_decl] %instance : $C
23+
end_borrow %guaranteed_c3 : $C
2124
destroy_value %instance : $C
2225
%res = tuple ()
2326
return %res : $()

0 commit comments

Comments
 (0)