Skip to content

Commit 9f134ea

Browse files
committed
[SILGen] Look thru loads for reference storage.
When emitting a guaranteed argument, a search is made for storage which can be borrowed. Look through LoadExprs during this search.
1 parent a037974 commit 9f134ea

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,6 +3188,9 @@ static StorageRefResult findStorageReferenceExprForBorrow(Expr *e) {
31883188
} else if (auto ioe = dyn_cast<InOutExpr>(e)) {
31893189
if (auto result = findStorageReferenceExprForBorrow(ioe->getSubExpr()))
31903190
return result.withTransitiveRoot(ioe);
3191+
} else if (auto le = dyn_cast<LoadExpr>(e)) {
3192+
if (auto result = findStorageReferenceExprForBorrow(le->getSubExpr()))
3193+
return result.withTransitiveRoot(le);
31913194
}
31923195

31933196
return StorageRefResult();

lib/SILGen/SILGenLValue.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ class LLVM_LIBRARY_VISIBILITY SILGenLValue
342342

343343
// Expressions that wrap lvalues
344344

345+
LValue visitLoadExpr(LoadExpr *e, SGFAccessKind accessKind,
346+
LValueOptions options);
345347
LValue visitInOutExpr(InOutExpr *e, SGFAccessKind accessKind,
346348
LValueOptions options);
347349
LValue visitDotSyntaxBaseIgnoredExpr(DotSyntaxBaseIgnoredExpr *e,
@@ -4328,6 +4330,11 @@ LValue SILGenLValue::visitInOutExpr(InOutExpr *e, SGFAccessKind accessKind,
43284330
return visitRec(e->getSubExpr(), accessKind, options);
43294331
}
43304332

4333+
LValue SILGenLValue::visitLoadExpr(LoadExpr *e, SGFAccessKind accessKind,
4334+
LValueOptions options) {
4335+
return visit(e->getSubExpr(), accessKind, options);
4336+
}
4337+
43314338
LValue SILGenLValue::visitConsumeExpr(ConsumeExpr *e, SGFAccessKind accessKind,
43324339
LValueOptions options) {
43334340
// Do formal evaluation of the base l-value.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend \
4+
// RUN: %s \
5+
// RUN: -emit-silgen \
6+
// RUN: -debug-diagnostic-names \
7+
// RUN: -I %t \
8+
// RUN: | \
9+
// RUN: %FileCheck %s
10+
11+
public struct FA<T> {
12+
public subscript(_ int: Int) -> T {
13+
// CHECK-LABEL: sil [ossa] @read : {{.*}} {
14+
// function_ref UnsafeMutablePointer.subscript.unsafeAddressor
15+
// CHECK: [[ADDRESSOR:%[^,]+]] = function_ref @$sSpyxSicilu
16+
// CHECK: [[POINTER:%[^,]+]] = apply [[ADDRESSOR]]
17+
// CHECK: [[RAW_POINTER:%[^,]+]] = struct_extract [[POINTER]]
18+
// CHECK: [[ADDR:%[^,]+]] = pointer_to_address [[RAW_POINTER]]
19+
// CHECK: [[ACCESS:%[^,]+]] = begin_access [read] [unsafe] [[ADDR]]
20+
// Verify that no spurious temporary is emitted.
21+
// CHECK-NOT: alloc_stack
22+
// CHECK: yield [[ACCESS]] : $*T, resume [[SUCCESS:bb[0-9]+]], unwind [[FAILURE:bb[0-9]+]]
23+
// CHECK: [[SUCCESS]]:
24+
// CHECK: end_access [[ACCESS]]
25+
// CHECK: [[FAILURE]]:
26+
// CHECK: end_access [[ACCESS]]
27+
// CHECK: unwind
28+
// CHECK-LABEL: } // end sil function 'read'
29+
@_silgen_name("read")
30+
_read {
31+
yield ump[int]
32+
}
33+
}
34+
var ump: UnsafeMutablePointer<T>
35+
}
36+

0 commit comments

Comments
 (0)