Skip to content

Commit 8595961

Browse files
committed
SILGen: Conditionally use @callee_guaranteed contexts
SR-5441
1 parent 2b1921b commit 8595961

File tree

5 files changed

+69
-25
lines changed

5 files changed

+69
-25
lines changed

lib/SIL/SILFunctionType.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ enum class ConventionsKind : uint8_t {
231231
getDirectParameter(unsigned index,
232232
const AbstractionPattern &type,
233233
const TypeLowering &substTL) const = 0;
234-
virtual ParameterConvention getCallee() const = 0;
234+
virtual ParameterConvention getCallee(bool useGuaranteedContext) const = 0;
235235
virtual ResultConvention getResult(const TypeLowering &resultTL) const = 0;
236236
virtual ParameterConvention
237237
getIndirectSelfParameter(const AbstractionPattern &type) const = 0;
@@ -946,7 +946,8 @@ static CanSILFunctionType getSILFunctionType(SILModule &M,
946946

947947
auto calleeConvention = ParameterConvention::Direct_Unowned;
948948
if (extInfo.hasContext())
949-
calleeConvention = conventions.getCallee();
949+
calleeConvention =
950+
conventions.getCallee(M.getOptions().EnableGuaranteedClosureContexts);
950951

951952
bool pseudogeneric = (constant ? isPseudogeneric(*constant) : false);
952953

@@ -985,7 +986,7 @@ struct DeallocatorConventions : Conventions {
985986
llvm_unreachable("Deallocators do not have non-self direct parameters");
986987
}
987988

988-
ParameterConvention getCallee() const override {
989+
ParameterConvention getCallee(bool) const override {
989990
llvm_unreachable("Deallocators do not have callees");
990991
}
991992

@@ -1035,7 +1036,9 @@ namespace {
10351036
return ParameterConvention::Direct_Owned;
10361037
}
10371038

1038-
ParameterConvention getCallee() const override {
1039+
ParameterConvention getCallee(bool useGuaranteedContext) const override {
1040+
if (useGuaranteedContext)
1041+
return ParameterConvention::Direct_Guaranteed;
10391042
return DefaultThickCalleeConvention;
10401043
}
10411044

@@ -1092,7 +1095,7 @@ namespace {
10921095
return ParameterConvention::Direct_Unowned;
10931096
}
10941097

1095-
ParameterConvention getCallee() const override {
1098+
ParameterConvention getCallee(bool) const override {
10961099
return ParameterConvention::Direct_Unowned;
10971100
}
10981101

@@ -1261,7 +1264,7 @@ namespace {
12611264
return getDirectCParameterConvention(Method->param_begin()[index]);
12621265
}
12631266

1264-
ParameterConvention getCallee() const override {
1267+
ParameterConvention getCallee(bool) const override {
12651268
// Always thin.
12661269
return ParameterConvention::Direct_Unowned;
12671270
}
@@ -1412,7 +1415,7 @@ namespace {
14121415
return getDirectCParameterConvention(getParamType(index));
14131416
}
14141417

1415-
ParameterConvention getCallee() const override {
1418+
ParameterConvention getCallee(bool) const override {
14161419
// FIXME: blocks should be Direct_Guaranteed.
14171420
return ParameterConvention::Direct_Unowned;
14181421
}
@@ -1702,7 +1705,7 @@ namespace {
17021705
return ParameterConvention::Direct_Unowned;
17031706
}
17041707

1705-
ParameterConvention getCallee() const override {
1708+
ParameterConvention getCallee(bool) const override {
17061709
// Always thin.
17071710
return ParameterConvention::Direct_Unowned;
17081711
}

lib/SILGen/SILGenApply.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,7 +1689,7 @@ static SILValue emitRawApply(SILGenFunction &SGF,
16891689
// Get the callee value.
16901690
SILValue fnValue = substFnType->isCalleeConsumed()
16911691
? fn.forward(SGF)
1692-
: fn.getValue();
1692+
: fn.borrow(SGF, loc).getValue();
16931693

16941694
SmallVector<SILValue, 4> argValues;
16951695

@@ -4372,9 +4372,11 @@ CallEmission::applyPartiallyAppliedSuperMethod(unsigned uncurryLevel,
43724372
functionTy);
43734373
}
43744374
}
4375+
auto calleeConvention = SGF.SGM.M.getOptions().EnableGuaranteedClosureContexts
4376+
? ParameterConvention::Direct_Guaranteed
4377+
: ParameterConvention::Direct_Owned;
43754378
auto closureTy = SILGenBuilder::getPartialApplyResultType(
4376-
constantInfo.getSILType(), 1, SGF.B.getModule(), subs,
4377-
ParameterConvention::Direct_Owned);
4379+
constantInfo.getSILType(), 1, SGF.B.getModule(), subs, calleeConvention);
43784380

43794381
auto &module = SGF.getFunction().getModule();
43804382

@@ -5572,11 +5574,14 @@ static ManagedValue emitDynamicPartialApply(SILGenFunction &SGF,
55725574
SILValue self,
55735575
CanAnyFunctionType foreignFormalType,
55745576
CanAnyFunctionType nativeFormalType) {
5575-
auto partialApplyTy = SILBuilder::getPartialApplyResultType(method->getType(),
5576-
/*argCount*/1,
5577-
SGF.SGM.M,
5578-
/*subs*/{},
5579-
ParameterConvention::Direct_Owned);
5577+
auto calleeConvention = SGF.SGM.M.getOptions().EnableGuaranteedClosureContexts
5578+
? ParameterConvention::Direct_Guaranteed
5579+
: ParameterConvention::Direct_Owned;
5580+
5581+
auto partialApplyTy =
5582+
SILBuilder::getPartialApplyResultType(method->getType(),
5583+
/*argCount*/ 1, SGF.SGM.M,
5584+
/*subs*/ {}, calleeConvention);
55805585

55815586
// Retain 'self' because the partial apply will take ownership.
55825587
// We can't simply forward 'self' because the partial apply is conditional.

lib/SILGen/SILGenFunction.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,14 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
357357
for (auto capture : capturedArgs)
358358
forwardedArgs.push_back(capture.forward(*this));
359359

360-
SILType closureTy =
361-
SILGenBuilder::getPartialApplyResultType(functionRef->getType(),
362-
capturedArgs.size(), SGM.M,
363-
subs,
364-
ParameterConvention::Direct_Owned);
360+
auto calleeConvention = SGM.M.getOptions().EnableGuaranteedClosureContexts
361+
? ParameterConvention::Direct_Guaranteed
362+
: ParameterConvention::Direct_Owned;
363+
364+
SILType closureTy = SILGenBuilder::getPartialApplyResultType(
365+
functionRef->getType(), capturedArgs.size(), SGM.M, subs,
366+
calleeConvention);
367+
365368
auto toClosure =
366369
B.createPartialApply(loc, functionRef, functionTy,
367370
subs, forwardedArgs, closureTy);

lib/SILGen/SILGenThunk.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,13 @@ void SILGenFunction::emitCurryThunk(SILDeclRef thunk) {
165165
resultTy = F.mapTypeIntoContext(resultTy);
166166
auto substTy = toFn->getType().substGenericArgs(SGM.M, subs);
167167

168+
auto calleeConvention = SGM.M.getOptions().EnableGuaranteedClosureContexts
169+
? ParameterConvention::Direct_Guaranteed
170+
: ParameterConvention::Direct_Owned;
171+
168172
// Partially apply the next uncurry level and return the result closure.
169-
auto closureTy =
170-
SILGenBuilder::getPartialApplyResultType(toFn->getType(), /*appliedParams=*/1,
171-
SGM.M, subs,
172-
ParameterConvention::Direct_Owned);
173+
auto closureTy = SILGenBuilder::getPartialApplyResultType(
174+
toFn->getType(), /*appliedParams=*/1, SGM.M, subs, calleeConvention);
173175
SILValue toClosure =
174176
B.createPartialApply(vd, toFn, substTy, subs, {selfArg}, closureTy);
175177
if (resultTy != closureTy)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-swift-frontend -enable-sil-ownership -parse-stdlib -parse-as-library -enable-guaranteed-closure-contexts -emit-silgen %s | %FileCheck %s
2+
import Swift
3+
4+
// CHECK-LABEL: sil @{{.*}}apply{{.*}} : $@convention(thin) (@owned @noescape @callee_guaranteed () -> Int)
5+
// bb0(%0 : @owned $@noescape @callee_guaranteed () -> Int):
6+
// [[B1:%.*]] = begin_borrow %0 : $@noescape @callee_guaranteed () -> Int
7+
// [[C1:%.*]] = copy_value %2 : $@noescape @callee_guaranteed () -> Int
8+
//
9+
// The important part is that the call borrow's the function value -- we are
10+
// @callee_guaranteed.
11+
// [[B2:%.*]] = begin_borrow [[C1]] : $@noescape @callee_guaranteed () -> Int
12+
// [[R:%.*]] = apply [[B2]]() : $@noescape @callee_guaranteed () -> Int
13+
// end_borrow [[B2]] from [[C1]] : $@noescape @callee_guaranteed () -> Int, $@noescape @callee_guaranteed () -> Int
14+
//
15+
// destroy_value [[C1]] : $@noescape @callee_guaranteed () -> Int
16+
// end_borrow [[B1]] from %0 : $@noescape @callee_guaranteed () -> Int, $@noescape @callee_guaranteed () -> Int
17+
// destroy_value %0 : $@noescape @callee_guaranteed () -> Int
18+
// return [[R]] : $Int
19+
public func apply(_ f : () -> Int) -> Int {
20+
return f()
21+
}
22+
23+
// CHECK-LABEL: sil @{{.*}}test{{.*}} : $@convention(thin) () -> ()
24+
// CHECK: [[A:%.*]] = function_ref @{{.*}}apply{{.*}} : $@convention(thin) (@owned @noescape @callee_guaranteed () -> Int) -> Int
25+
// CHECK: [[C1:%.*]] = function_ref @{{.*}}test{{.*}} : $@convention(thin) () -> Int
26+
// CHECK: [[C2:%.*]] = convert_function [[C2]] : $@convention(thin) () -> Int to $@convention(thin) @noescape () -> Int
27+
// CHECK: [[C3:%.*]] = thin_to_thick_function [[C2]] : $@convention(thin) @noescape () -> Int to $@noescape @callee_guaranteed () -> Int
28+
// CHECK: apply [[A]]([[C3]]) : $@convention(thin) (@owned @noescape @callee_guaranteed () -> Int) -> Int
29+
public func test() {
30+
let res = apply({ return 1 })
31+
}

0 commit comments

Comments
 (0)