Skip to content

Commit 6f996ef

Browse files
committed
SIL: Consistently drop substitution map when forming apply instructions
Fixes rdar://129298104.
1 parent df0f784 commit 6f996ef

File tree

6 files changed

+72
-11
lines changed

6 files changed

+72
-11
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2678,6 +2678,8 @@ class ApplyInstBase<Impl, Base, false> : public Base {
26782678
SpecializationInfo(specializationInfo), NumCallArguments(args.size()),
26792679
NumTypeDependentOperands(typeDependentOperands.size()),
26802680
Substitutions(subs) {
2681+
assert(!!subs == !!callee->getType().castTo<SILFunctionType>()
2682+
->getInvocationGenericSignature());
26812683

26822684
// Initialize the operands.
26832685
auto allOperands = getAllOperands();

lib/SILGen/SILGenApply.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,6 +1950,11 @@ static void emitRawApply(SILGenFunction &SGF,
19501950
SILValue indirectErrorAddr,
19511951
SmallVectorImpl<SILValue> &rawResults,
19521952
ExecutorBreadcrumb prevExecutor) {
1953+
// We completely drop the generic signature if all generic parameters were
1954+
// concrete.
1955+
if (subs && subs.getGenericSignature()->areAllParamsConcrete())
1956+
subs = SubstitutionMap();
1957+
19531958
SILFunctionConventions substFnConv(substFnType, SGF.SGM.M);
19541959
// Get the callee value.
19551960
bool isConsumed = substFnType->isCalleeConsumed();
@@ -5920,6 +5925,11 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
59205925
SILType substFnType,
59215926
SubstitutionMap subs,
59225927
ArrayRef<SILValue> args) {
5928+
// We completely drop the generic signature if all generic parameters were
5929+
// concrete.
5930+
if (subs && subs.getGenericSignature()->areAllParamsConcrete())
5931+
subs = SubstitutionMap();
5932+
59235933
CanSILFunctionType silFnType = substFnType.castTo<SILFunctionType>();
59245934
SILFunctionConventions fnConv(silFnType, SGM.M);
59255935
SILType resultType = fnConv.getSILResultType(getTypeExpansionContext());

lib/SILGen/SILGenDestructor.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,16 @@ void SILGenFunction::emitDestroyingDestructor(DestructorDecl *dd) {
118118
SILValue baseSelf = B.createUpcast(cleanupLoc, selfValue, baseSILTy);
119119
ManagedValue dtorValue;
120120
SILType dtorTy;
121+
121122
auto subMap
122123
= superclassTy->getContextSubstitutionMap(SGM.M.getSwiftModule(),
123124
superclass);
125+
126+
// We completely drop the generic signature if all generic parameters were
127+
// concrete.
128+
if (subMap && subMap.getGenericSignature()->areAllParamsConcrete())
129+
subMap = SubstitutionMap();
130+
124131
std::tie(dtorValue, dtorTy)
125132
= emitSiblingMethodRef(cleanupLoc, baseSelf, dtorConstant, subMap);
126133

@@ -191,12 +198,11 @@ void SILGenFunction::emitDeallocatingClassDestructor(DestructorDecl *dd) {
191198
// Form a reference to the destroying destructor.
192199
SILDeclRef dtorConstant(dd, SILDeclRef::Kind::Destroyer);
193200
auto classTy = initialSelfValue->getType();
194-
auto classDecl = classTy.getASTType()->getAnyNominal();
201+
202+
auto subMap = F.getForwardingSubstitutionMap();
203+
195204
ManagedValue dtorValue;
196205
SILType dtorTy;
197-
auto subMap = classTy.getASTType()
198-
->getContextSubstitutionMap(SGM.M.getSwiftModule(),
199-
classDecl);
200206
std::tie(dtorValue, dtorTy)
201207
= emitSiblingMethodRef(loc, initialSelfValue, dtorConstant, subMap);
202208

lib/SILGen/SILGenFunction.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,13 @@ SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
987987
constant, loweredCaptureInfo, subs);
988988
}
989989

990-
if (subs) {
990+
// We completely drop the generic signature if all generic parameters were
991+
// concrete.
992+
if (!pft->isPolymorphic()) {
993+
subs = SubstitutionMap();
994+
} else {
995+
assert(!subs.getGenericSignature()->areAllParamsConcrete());
996+
991997
auto specialized =
992998
pft->substGenericArgs(F.getModule(), subs, getTypeExpansionContext());
993999
functionTy = SILType::getPrimitiveObjectType(specialized);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-swift-frontend -parse-as-library -disable-availability-checking -import-objc-header %S/Inputs/perf-annotations.h -emit-sil %s -o /dev/null -verify
2+
3+
// REQUIRES: swift_in_compiler
4+
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
5+
6+
@_noAllocation
7+
func createEmptyArray() {
8+
_ = [Int]() // expected-error {{ending the lifetime of a value of type}}
9+
}

test/SILOptimizer/performance-annotations.swift

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %target-swift-frontend -parse-as-library -disable-availability-checking -import-objc-header %S/Inputs/perf-annotations.h -emit-sil %s -o /dev/null -verify
2-
// REQUIRES: swift_stdlib_no_asserts,optimized_stdlib
2+
33
// REQUIRES: swift_in_compiler
4+
// REQUIRES: optimized_stdlib
45

56
protocol P {
67
func protoMethod(_ a: Int) -> Int
@@ -233,11 +234,6 @@ func closueWhichModifiesLocalVar() -> Int {
233234
return x
234235
}
235236

236-
@_noAllocation
237-
func createEmptyArray() {
238-
_ = [Int]() // expected-error {{ending the lifetime of a value of type}}
239-
}
240-
241237
struct Buffer {
242238
var p: UnsafeMutableRawBufferPointer
243239

@@ -514,3 +510,35 @@ func testNonCopyable() {
514510
let t = NonCopyableStruct()
515511
t.foo()
516512
}
513+
514+
func takesClosure(_: () -> ()) {}
515+
516+
@_noLocks
517+
func testClosureExpression<T>(_ t: T) {
518+
takesClosure {
519+
// expected-error@-1 {{generic closures or local functions can cause metadata allocation or locks}}
520+
_ = T.self
521+
}
522+
}
523+
524+
@_noLocks
525+
func testLocalFunction<T>(_ t: T) {
526+
func localFunc() {
527+
_ = T.self
528+
}
529+
530+
takesClosure(localFunc)
531+
// expected-error@-1 {{generic closures or local functions can cause metadata allocation or locks}}
532+
}
533+
534+
func takesGInt(_ x: G<Int>) {}
535+
536+
struct G<T> {}
537+
538+
extension G where T == Int {
539+
@_noAllocation func method() {
540+
takesClosure {
541+
takesGInt(self)
542+
}
543+
}
544+
}

0 commit comments

Comments
 (0)