Skip to content

Commit 322ce5a

Browse files
committed
SIL: Consistently drop substitution map when forming apply instructions
Fixes rdar://129298104.
1 parent 02e3b5a commit 322ce5a

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
@@ -1886,6 +1886,11 @@ static void emitRawApply(SILGenFunction &SGF,
18861886
SILValue indirectErrorAddr,
18871887
SmallVectorImpl<SILValue> &rawResults,
18881888
ExecutorBreadcrumb prevExecutor) {
1889+
// We completely drop the generic signature if all generic parameters were
1890+
// concrete.
1891+
if (subs && subs.getGenericSignature()->areAllParamsConcrete())
1892+
subs = SubstitutionMap();
1893+
18891894
SILFunctionConventions substFnConv(substFnType, SGF.SGM.M);
18901895
// Get the callee value.
18911896
bool isConsumed = substFnType->isCalleeConsumed();
@@ -5857,6 +5862,11 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
58575862
SILType substFnType,
58585863
SubstitutionMap subs,
58595864
ArrayRef<SILValue> args) {
5865+
// We completely drop the generic signature if all generic parameters were
5866+
// concrete.
5867+
if (subs && subs.getGenericSignature()->areAllParamsConcrete())
5868+
subs = SubstitutionMap();
5869+
58605870
CanSILFunctionType silFnType = substFnType.castTo<SILFunctionType>();
58615871
SILFunctionConventions fnConv(silFnType, SGM.M);
58625872
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 -enable-experimental-feature RawLayout -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

@@ -527,3 +523,35 @@ public struct RawLayoutWrapper: ~Copyable {
527523
public struct RawLayout<T>: ~Copyable {
528524
public func test() {}
529525
}
526+
527+
func takesClosure(_: () -> ()) {}
528+
529+
@_noLocks
530+
func testClosureExpression<T>(_ t: T) {
531+
takesClosure {
532+
// expected-error@-1 {{generic closures or local functions can cause metadata allocation or locks}}
533+
_ = T.self
534+
}
535+
}
536+
537+
@_noLocks
538+
func testLocalFunction<T>(_ t: T) {
539+
func localFunc() {
540+
_ = T.self
541+
}
542+
543+
takesClosure(localFunc)
544+
// expected-error@-1 {{generic closures or local functions can cause metadata allocation or locks}}
545+
}
546+
547+
func takesGInt(_ x: G<Int>) {}
548+
549+
struct G<T> {}
550+
551+
extension G where T == Int {
552+
@_noAllocation func method() {
553+
takesClosure {
554+
takesGInt(self) // OK
555+
}
556+
}
557+
}

0 commit comments

Comments
 (0)