Skip to content

Commit edc3820

Browse files
committed
SIL: Don't drop generic signatures where all parameters are concrete
1 parent 547eea5 commit edc3820

15 files changed

+163
-81
lines changed

lib/AST/ASTContext.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3971,12 +3971,8 @@ SILFunctionType::SILFunctionType(GenericSignature *genericSig, ExtInfo ext,
39713971
assert(!WitnessMethodConformance &&
39723972
"non-witness_method SIL function with a conformance");
39733973

3974-
// Make sure the interface types are sane.
3974+
// Make sure the interface types do not contain archetypes or error types.
39753975
if (genericSig) {
3976-
assert(!genericSig->areAllParamsConcrete() &&
3977-
"If all generic parameters are concrete, SILFunctionType should "
3978-
"not have a generic signature at all");
3979-
39803976
for (auto gparam : genericSig->getGenericParams()) {
39813977
(void)gparam;
39823978
assert(gparam->isCanonical() && "generic signature is not canonicalized");

lib/IRGen/Callee.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,6 @@ namespace irgen {
157157
CanSILFunctionType getSubstFunctionType() const {
158158
return Info.SubstFnType;
159159
}
160-
161-
bool hasSubstitutions() const {
162-
return Info.Substitutions.hasAnySubstitutableParams();
163-
}
164160

165161
SubstitutionMap getSubstitutions() const { return Info.Substitutions; }
166162

lib/IRGen/GenFunc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -876,9 +876,9 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,
876876
Explosion polyArgs;
877877

878878
// Emit the polymorphic arguments.
879-
assert((subs.hasAnySubstitutableParams()
879+
assert((!subs.empty()
880880
== hasPolymorphicParameters(origType) ||
881-
(!subs.hasAnySubstitutableParams() && origType->getRepresentation() ==
881+
(subs.empty() && origType->getRepresentation() ==
882882
SILFunctionTypeRepresentation::WitnessMethod))
883883
&& "should have substitutions iff original function is generic");
884884
WitnessMetadata witnessMetadata;

lib/SIL/SILVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
10501050
auto fnTy = requireObjectType(SILFunctionType, calleeTy, "callee operand");
10511051

10521052
// If there are substitutions, verify them and apply them to the callee.
1053-
if (!subs.hasAnySubstitutableParams()) {
1053+
if (subs.empty()) {
10541054
require(!fnTy->isPolymorphic(),
10551055
"callee of apply without substitutions must not be polymorphic");
10561056
return fnTy;

lib/SIL/TypeLowering.cpp

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,8 +1727,7 @@ getTypeLoweringForExpansion(TypeKey key,
17271727
}
17281728

17291729
/// Get the type of a global variable accessor function, () -> RawPointer.
1730-
static CanAnyFunctionType getGlobalAccessorType(CanType varType) {
1731-
ASTContext &C = varType->getASTContext();
1730+
static CanAnyFunctionType getGlobalAccessorType(ASTContext &C) {
17321731
return CanFunctionType::get({}, C.TheRawPointerType);
17331732
}
17341733

@@ -1844,8 +1843,6 @@ TypeConverter::getEffectiveGenericEnvironment(AnyFunctionRef fn,
18441843
CanGenericSignature
18451844
TypeConverter::getEffectiveGenericSignature(DeclContext *dc) {
18461845
if (auto sig = dc->getGenericSignatureOfContext()) {
1847-
if (sig->areAllParamsConcrete())
1848-
return nullptr;
18491846
return sig->getCanonicalSignature();
18501847
}
18511848

@@ -1878,8 +1875,10 @@ TypeConverter::getFunctionInterfaceTypeWithCaptures(CanAnyFunctionType funcType,
18781875
auto innerExtInfo = AnyFunctionType::ExtInfo(FunctionType::Representation::Thin,
18791876
funcType->throws());
18801877

1881-
return CanAnyFunctionType::get(genericSig, funcType.getParams(),
1882-
funcType.getResult(), innerExtInfo);
1878+
return CanAnyFunctionType::get(genericSig,
1879+
funcType.getParams(),
1880+
funcType.getResult(),
1881+
innerExtInfo);
18831882
}
18841883

18851884
CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
@@ -1889,41 +1888,33 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
18891888
case SILDeclRef::Kind::Func: {
18901889
if (auto *ACE = c.loc.dyn_cast<AbstractClosureExpr *>()) {
18911890
// FIXME: Closures could have an interface type computed by Sema.
1892-
auto funcTy = cast<AnyFunctionType>(ACE->getType()->getCanonicalType());
1893-
funcTy = cast<AnyFunctionType>(
1894-
funcTy->mapTypeOutOfContext()
1891+
auto funcTy = cast<AnyFunctionType>(
1892+
ACE->getType()->mapTypeOutOfContext()
18951893
->getCanonicalType());
18961894
return getFunctionInterfaceTypeWithCaptures(funcTy, ACE);
18971895
}
18981896

18991897
FuncDecl *func = cast<FuncDecl>(vd);
19001898
auto funcTy = cast<AnyFunctionType>(
19011899
func->getInterfaceType()->getCanonicalType());
1900+
1901+
// Fast path.
1902+
if (!func->getDeclContext()->isLocalContext())
1903+
return funcTy;
1904+
19021905
return getFunctionInterfaceTypeWithCaptures(funcTy, func);
19031906
}
19041907

1905-
case SILDeclRef::Kind::EnumElement: {
1906-
auto funcTy = cast<AnyFunctionType>(
1907-
vd->getInterfaceType()->getCanonicalType());
1908-
auto sig = getEffectiveGenericSignature(vd->getDeclContext());
1909-
return CanAnyFunctionType::get(sig,
1910-
funcTy->getParams(),
1911-
funcTy.getResult(),
1912-
funcTy->getExtInfo());
1913-
}
1914-
1908+
case SILDeclRef::Kind::EnumElement:
19151909
case SILDeclRef::Kind::Allocator: {
1916-
auto *cd = cast<ConstructorDecl>(vd);
1917-
auto funcTy = cast<AnyFunctionType>(
1918-
cd->getInterfaceType()->getCanonicalType());
1919-
return getFunctionInterfaceTypeWithCaptures(funcTy, cd);
1910+
return cast<AnyFunctionType>(
1911+
vd->getInterfaceType()->getCanonicalType());
19201912
}
19211913

19221914
case SILDeclRef::Kind::Initializer: {
19231915
auto *cd = cast<ConstructorDecl>(vd);
1924-
auto funcTy = cast<AnyFunctionType>(
1925-
cd->getInitializerInterfaceType()->getCanonicalType());
1926-
return getFunctionInterfaceTypeWithCaptures(funcTy, cd);
1916+
return cast<AnyFunctionType>(
1917+
cd->getInitializerInterfaceType()->getCanonicalType());
19271918
}
19281919

19291920
case SILDeclRef::Kind::Destroyer:
@@ -1937,7 +1928,7 @@ CanAnyFunctionType TypeConverter::makeConstantInterfaceType(SILDeclRef c) {
19371928
VarDecl *var = cast<VarDecl>(vd);
19381929
assert(var->hasStorage() &&
19391930
"constant ref to computed global var");
1940-
return getGlobalAccessorType(var->getInterfaceType()->getCanonicalType());
1931+
return getGlobalAccessorType(Context);
19411932
}
19421933
case SILDeclRef::Kind::DefaultArgGenerator:
19431934
return getDefaultArgGeneratorInterfaceType(*this, vd, vd->getDeclContext(),

lib/SILGen/SILGenType.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -626,13 +626,6 @@ SILFunction *SILGenModule::emitProtocolWitness(
626626
reqtOrigTy->substGenericArgs(reqtSubMap)
627627
->getCanonicalType(genericSig));
628628

629-
// Generic signatures where all parameters are concrete are lowered away
630-
// at the SILFunctionType level.
631-
if (genericSig && genericSig->areAllParamsConcrete()) {
632-
genericSig = nullptr;
633-
genericEnv = nullptr;
634-
}
635-
636629
// Rewrite the conformance in terms of the requirement environment's Self
637630
// type, which might have a different generic signature than the type
638631
// itself.

lib/SILOptimizer/IPO/CapturePromotion.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,9 +1260,8 @@ processPartialApplyInst(SILOptFunctionBuilder &FuncBuilder,
12601260
// consideration any captures.
12611261
auto CalleeFunctionTy = PAI->getCallee()->getType().castTo<SILFunctionType>();
12621262
auto SubstCalleeFunctionTy = CalleeFunctionTy;
1263-
if (PAI->hasSubstitutions())
1264-
SubstCalleeFunctionTy =
1265-
CalleeFunctionTy->substGenericArgs(M, PAI->getSubstitutionMap());
1263+
SubstCalleeFunctionTy =
1264+
CalleeFunctionTy->substGenericArgs(M, PAI->getSubstitutionMap());
12661265
SILFunctionConventions calleeConv(SubstCalleeFunctionTy, M);
12671266
auto CalleePInfo = SubstCalleeFunctionTy->getParameters();
12681267
SILFunctionConventions paConv(PAI->getType().castTo<SILFunctionType>(), M);

lib/SILOptimizer/IPO/ClosureSpecializer.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,9 @@ class CallSiteDescriptor {
222222
createNewClosure(SILBuilder &B, SILValue V,
223223
llvm::SmallVectorImpl<SILValue> &Args) const {
224224
if (auto *PA = dyn_cast<PartialApplyInst>(getClosure()))
225-
return B.createPartialApply(getClosure()->getLoc(), V, {}, Args,
225+
return B.createPartialApply(getClosure()->getLoc(), V,
226+
PA->getSubstitutionMap(),
227+
Args,
226228
getClosure()
227229
->getType()
228230
.getAs<SILFunctionType>()
@@ -436,8 +438,8 @@ static void rewriteApplyInst(const CallSiteDescriptor &CSDesc,
436438
case FullApplySiteKind::TryApplyInst: {
437439
auto *TAI = cast<TryApplyInst>(AI);
438440
NewAI = Builder.createTryApply(AI.getLoc(), FRI,
439-
SubstitutionMap(), NewArgs,
440-
TAI->getNormalBB(), TAI->getErrorBB());
441+
TAI->getSubstitutionMap(),
442+
NewArgs, TAI->getNormalBB(), TAI->getErrorBB());
441443
// If we passed in the original closure as @owned, then insert a release
442444
// right after NewAI. This is to balance the +1 from being an @owned
443445
// argument to AI.
@@ -457,7 +459,7 @@ static void rewriteApplyInst(const CallSiteDescriptor &CSDesc,
457459
case FullApplySiteKind::ApplyInst: {
458460
auto oldApply = cast<ApplyInst>(AI);
459461
auto newApply = Builder.createApply(oldApply->getLoc(), FRI,
460-
SubstitutionMap(),
462+
oldApply->getSubstitutionMap(),
461463
NewArgs, oldApply->isNonThrowing());
462464
// If we passed in the original closure as @owned, then insert a release
463465
// right after NewAI. This is to balance the +1 from being an @owned
@@ -733,7 +735,9 @@ SILValue ClosureSpecCloner::cloneCalleeConversion(
733735
auto FunRef = Builder.createFunctionRef(CallSiteDesc.getLoc(),
734736
PAI->getReferencedFunction());
735737
auto NewPA = Builder.createPartialApply(
736-
CallSiteDesc.getLoc(), FunRef, {}, {calleeValue},
738+
CallSiteDesc.getLoc(), FunRef,
739+
PAI->getSubstitutionMap(),
740+
{calleeValue},
737741
PAI->getType().getAs<SILFunctionType>()->getCalleeConvention(),
738742
PAI->isOnStack());
739743
// If the partial_apply is on stack we will emit a dealloc_stack in the

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -731,9 +731,7 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF,
731731
SubstitutionMap SubstMap,
732732
bool HasUnboundGenericParams) {
733733
auto &M = OrigF->getModule();
734-
if ((SpecializedGenericSig &&
735-
SpecializedGenericSig->areAllParamsConcrete()) ||
736-
!HasUnboundGenericParams) {
734+
if (!HasUnboundGenericParams) {
737735
SpecializedGenericSig = nullptr;
738736
SpecializedGenericEnv = nullptr;
739737
}

test/SILGen/capture-canonicalization.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ struct Bar {}
55

66
extension Foo where T == Bar {
77
func foo(x: T) -> Bar {
8-
// CHECK-LABEL: sil private [ossa] @{{.*}}3foo{{.*}}4foo2{{.*}} : $@convention(thin) (Bar) -> Bar
8+
// CHECK-LABEL: sil private [ossa] @{{.*}}3foo{{.*}}4foo2{{.*}} : $@convention(thin) <T where T == Bar> (Bar) -> Bar
99
func foo2() -> Bar {
1010
return x
1111
}

test/SILGen/conditional_conformance.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ extension Conformance: P1 where A: P2 {
2020
// This is defined below but is emitted before any witness tables.
2121
// Just make sure it does not have a generic signature.
2222
//
23-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s23conditional_conformance16SameTypeConcreteVyxGAA2P1AASiRszlAaEP6normalyyFTW : $@convention(witness_method: P1) (@in_guaranteed SameTypeConcrete<Int>) -> ()
23+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s23conditional_conformance16SameTypeConcreteVyxGAA2P1AASiRszlAaEP6normalyyFTW : $@convention(witness_method: P1) <τ_0_0 where τ_0_0 == Int> (@in_guaranteed SameTypeConcrete<Int>) -> ()
2424

2525

2626
// CHECK-LABEL: sil_witness_table hidden <A where A : P2> Conformance<A>: P1 module conditional_conformance {

0 commit comments

Comments
 (0)