Skip to content

Commit 29faebf

Browse files
committed
[SILGen] Gave arguments lexical lifetimes.
When the frontend flag -enable-experimental-lexical-lifetimes is passed, arguments of non-trivial, non-address types get lexical borrow scopes. The borrow scope begins in the function prolog. Usages of the arguments are actually usages of the borrowed value. The borrow scope is ended when the function's scope ends.
1 parent b63cc13 commit 29faebf

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

lib/SILGen/SILGenProlog.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,17 +251,23 @@ struct ArgumentInitHelper {
251251
// Leave the cleanup on the argument, if any, in place to consume the
252252
// argument if we're responsible for it.
253253
}
254-
SGF.VarLocs[pd] = SILGenFunction::VarLoc::get(argrv.getValue());
255254
SILValue value = argrv.getValue();
256255
SILDebugVariable varinfo(pd->isImmutable(), ArgNo);
257256
if (!argrv.getType().isAddress()) {
257+
if (SGF.getASTContext().LangOpts.EnableExperimentalLexicalLifetimes &&
258+
value->getOwnershipKind() != OwnershipKind::None) {
259+
value =
260+
SILValue(SGF.B.createBeginBorrow(loc, value, /*isLexical*/ true));
261+
SGF.Cleanups.pushCleanup<EndBorrowCleanup>(value);
262+
}
258263
SGF.B.createDebugValue(loc, value, varinfo);
259264
} else {
260265
if (auto AllocStack = dyn_cast<AllocStackInst>(value))
261266
AllocStack->setArgNo(ArgNo);
262267
else
263268
SGF.B.createDebugValueAddr(loc, value, varinfo);
264269
}
270+
SGF.VarLocs[pd] = SILGenFunction::VarLoc::get(value);
265271
}
266272

267273
void emitParam(ParamDecl *PD) {

test/SILGen/lexical_lifetime.swift

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ struct S {
1515
let c: C
1616
}
1717

18+
struct Trivial {
19+
let i: Int
20+
}
21+
1822
enum E {
1923
case e(C)
2024
}
2125

22-
func use<T>(_ t: T) {}
26+
@_silgen_name("use_generic")
27+
func use_generic<T>(_ t: T) {}
2328

2429
////////////////////////////////////////////////////////////////////////////////
2530
// Declarations }}
@@ -54,7 +59,7 @@ func lexical_borrow_let_class() {
5459
@_silgen_name("lexical_borrow_if_let_class")
5560
func lexical_borrow_if_let_class() {
5661
if let c = C(failably: ()) {
57-
use(())
62+
use_generic(())
5863
}
5964
}
6065

@@ -79,6 +84,42 @@ func lexical_borrow_let_class_in_enum() {
7984
let s = E.e(C())
8085
}
8186

87+
// arguments:
88+
89+
// CHECK-LABEL: sil hidden [ossa] @lexical_borrow_arg_guaranteed_class : $@convention(thin) (@guaranteed C) -> () {
90+
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @guaranteed $C):
91+
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
92+
// CHECK: debug_value [[LIFETIME]]
93+
// CHECK: [[ADDR:%[^,]+]] = alloc_stack $C
94+
// CHECK: store_borrow [[LIFETIME]] to [[ADDR]]
95+
// CHECK: [[USE_GENERIC:%[^,]+]] = function_ref @use_generic
96+
// CHECK: [[REGISTER_6:%[^,]+]] = apply [[USE_GENERIC]]<C>([[ADDR]])
97+
// CHECK: dealloc_stack [[ADDR]]
98+
// CHECK: end_borrow [[LIFETIME]]
99+
// CHECK: [[RETVAL:%[^,]+]] = tuple ()
100+
// CHECK: return [[RETVAL]]
101+
// CHECK-LABEL: } // end sil function 'lexical_borrow_arg_guaranteed_class'
102+
@_silgen_name("lexical_borrow_arg_guaranteed_class")
103+
func lexical_borrow_arg_guaranteed_class(_ c: C) {
104+
use_generic(c)
105+
}
106+
107+
// CHECK-LABEL: sil hidden [ossa] @lexical_borrow_arg_class_addr : $@convention(thin) (@inout C) -> () {
108+
// CHECK-NOT: begin_borrow [lexical]
109+
// CHECK-LABEL: } // end sil function 'lexical_borrow_arg_class_addr'
110+
@_silgen_name("lexical_borrow_arg_class_addr")
111+
func lexical_borrow_arg_class_addr(_ c: inout C) {
112+
use_generic(c)
113+
}
114+
115+
// CHECK-LABEL: sil hidden [ossa] @lexical_borrow_arg_trivial : $@convention(thin) (Trivial) -> () {
116+
// CHECK-NOT: begin_borrow [lexical]
117+
// CHECK-LABEL: } // end sil function 'lexical_borrow_arg_trivial'
118+
@_silgen_name("lexical_borrow_arg_trivial")
119+
func lexical_borrow_arg_trivial(_ trivial: Trivial) {
120+
use_generic(trivial)
121+
}
122+
82123
////////////////////////////////////////////////////////////////////////////////
83124
// Test }}
84125
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)