Skip to content

Commit 4434ee9

Browse files
authored
Merge pull request swiftlang#38658 from jckarter/avoid-reabstracting-applied-member-ref
SILGen: Don't reabstract a member ref we're about to directly apply.
2 parents 9a48cf9 + bc258d0 commit 4434ee9

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,27 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
11661166
}
11671167
}
11681168

1169+
void visitMemberRefExpr(MemberRefExpr *e) {
1170+
// If we're loading a closure-type property out of a generic aggregate,
1171+
// we might reabstract it under normal circumstances, but since we're
1172+
// going to apply it immediately here, there's no reason to. We can
1173+
// invoke the function value at whatever abstraction level we get.
1174+
assert(isa<VarDecl>(e->getMember().getDecl()));
1175+
1176+
// Any writebacks for this access are tightly scoped.
1177+
FormalEvaluationScope scope(SGF);
1178+
1179+
LValue lv = SGF.emitLValue(e, SGFAccessKind::OwnedObjectRead);
1180+
if (lv.isLastComponentTranslation())
1181+
lv.dropLastTranslationComponent();
1182+
1183+
ManagedValue fn = SGF.emitLoadOfLValue(e, std::move(lv), SGFContext())
1184+
.getAsSingleValue(SGF, e);
1185+
1186+
setCallee(Callee::forIndirect(fn, lv.getOrigFormalType(),
1187+
cast<FunctionType>(lv.getSubstFormalType()), e));
1188+
}
1189+
11691190
void visitAbstractClosureExpr(AbstractClosureExpr *e) {
11701191
// Emit the closure body.
11711192
SGF.SGM.emitClosure(e);

test/SILGen/reabstract.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,13 @@ func testInoutOpaque(_ c: C, i: Int) {
8585
// CHECK: function_ref @$s10reabstract1CCSiIegly_ACSiytIeglnr_TR
8686
// CHECK: partial_apply
8787
// CHECK: store
88-
// CHECK: load
89-
// CHECK: function_ref @$s10reabstract1CCSiytIeglnr_ACSiIegly_TR
90-
// CHECK: partial_apply
91-
// CHECK: apply
88+
// CHECK: [[CLOSURE:%.*]] = struct_extract {{.*}}, #Box.t
89+
// CHECK: [[CLOSURE1:%.*]] = copy_value [[CLOSURE]]
90+
// CHECK: [[CLOSURE2:%.*]] = begin_borrow [[CLOSURE1]]
91+
// CHECK: apply [[CLOSURE2]]
9292
// CHECK: } // end sil function '$s10reabstract15testInoutOpaque_1iyAA1CC_SitF'
9393

9494
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s10reabstract1CCSiIegly_ACSiytIeglnr_TR : $@convention(thin) (@inout C, @in_guaranteed Int, @guaranteed @callee_guaranteed (@inout C, Int) -> ()) -> @out () {
95-
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s10reabstract1CCSiytIeglnr_ACSiIegly_TR : $@convention(thin) (@inout C, Int, @guaranteed @callee_guaranteed (@inout C, @in_guaranteed Int) -> @out ()) -> () {
9695

9796
func closureTakingOptional(_ fn: (Int?) -> ()) {}
9897
closureTakingOptional({ (_: Any) -> () in })
@@ -107,7 +106,6 @@ closureTakingOptional({ (_: Any) -> () in })
107106
func evenLessFun(_ s: __shared C, _ o: __owned C) {}
108107

109108
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s10reabstract1CCACIeggx_A2CytIegnir_TR : $@convention(thin) (@in_guaranteed C, @in C, @guaranteed @callee_guaranteed (@guaranteed C, @owned C) -> ()) -> @out ()
110-
// CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] [ossa] @$s10reabstract1CCACytIegnir_A2CIeggx_TR : $@convention(thin) (@guaranteed C, @owned C, @guaranteed @callee_guaranteed (@in_guaranteed C, @in C) -> @out ()) -> ()
111109
func testSharedOwnedOpaque(_ s: C, o: C) {
112110
let box = Box(t: evenLessFun)
113111
box.t(s, o)

test/SILGen/same_type_abstraction.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ struct S1 {}
1212
struct S2 {}
1313

1414
// CHECK-LABEL: sil hidden [ossa] @$s21same_type_abstraction28callClosureWithConcreteTypes{{[_0-9a-zA-Z]*}}F
15-
// CHECK: function_ref @$s{{.*}}TR :
15+
// CHECK-NOT: function_ref @$s{{.*}}TR :
16+
// CHECK: apply {{.*}} : ${{.*}}(@in_guaranteed
1617
func callClosureWithConcreteTypes<T: Associated, U: Associated>(x: Abstracted<T, U>, arg: S1) -> S2 where T.Assoc == S1, U.Assoc == S2 {
1718
return x.closure(arg)
1819
}

0 commit comments

Comments
 (0)