Skip to content

Commit c889026

Browse files
authored
Merge pull request #7938 from swiftix/wip-partial-specialization-v77
Support partial generic specialization of closures
2 parents 0ef867a + d85013e commit c889026

File tree

1 file changed

+60
-37
lines changed

1 file changed

+60
-37
lines changed

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,10 @@ bool ReabstractionInfo::prepareAndCheck(ApplySite Apply, SILFunction *Callee,
130130
bool HasConcreteGenericParams = false;
131131
bool HasNonArchetypeGenericParams = false;
132132
HasUnboundGenericParams = false;
133-
for (auto DT : CalleeGenericSig->getGenericParams()) {
133+
for (auto GP : CalleeGenericSig->getSubstitutableParams()) {
134134
// Check only the substitutions for the generic parameters.
135135
// Ignore any dependent types, etc.
136-
auto Replacement = Type(DT).subst(InterfaceSubs);
136+
auto Replacement = Type(GP).subst(InterfaceSubs);
137137
if (!Replacement->is<ArchetypeType>())
138138
HasNonArchetypeGenericParams = true;
139139

@@ -146,7 +146,7 @@ bool ReabstractionInfo::prepareAndCheck(ApplySite Apply, SILFunction *Callee,
146146
if (CalleeGenericEnv) {
147147
if (auto Archetype = Replacement->getAs<ArchetypeType>()) {
148148
auto OrigArchetype =
149-
CalleeGenericEnv->mapTypeIntoContext(DT)->castTo<ArchetypeType>();
149+
CalleeGenericEnv->mapTypeIntoContext(GP)->castTo<ArchetypeType>();
150150
if (Archetype->requiresClass() && !OrigArchetype->requiresClass())
151151
HasNonArchetypeGenericParams = true;
152152
if (Archetype->getLayoutConstraint() &&
@@ -261,6 +261,7 @@ ReabstractionInfo::ReabstractionInfo(ApplySite Apply, SILFunction *Callee,
261261
SpecializedType = CanSILFunctionType();
262262
SubstitutedType = CanSILFunctionType();
263263
SpecializedGenericSig = nullptr;
264+
SpecializedGenericEnv = nullptr;
264265
return;
265266
}
266267

@@ -382,6 +383,12 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF,
382383
Lowering::GenericContextScope GenericScope(M.Types,
383384
CanSpecializedGenericSig);
384385
FnTy = OrigF->getLoweredFunctionType()->substGenericArgs(M, SubstMap);
386+
// FIXME: Some of the added new requirements may not have been taken into
387+
// account by the substGenericArgs. So, canonicalize in the context of the
388+
// specialized signature.
389+
FnTy = cast<SILFunctionType>(
390+
CanSpecializedGenericSig->getCanonicalTypeInContext(
391+
FnTy, *M.getSwiftModule()));
385392
}
386393
assert(FnTy);
387394

@@ -454,7 +461,8 @@ getGenericEnvironmentAndSignature(GenericSignatureBuilder &Builder,
454461
GenericSignatureBuilder TmpBuilder(
455462
M.getASTContext(), LookUpConformanceInModule(M.getSwiftModule()));
456463
TmpBuilder.addGenericSignature(GenericSig);
457-
TmpBuilder.finalize(SourceLoc(), GenericSig->getGenericParams());
464+
TmpBuilder.finalize(SourceLoc(), GenericSig->getGenericParams(),
465+
/*allowConcreteGenericParams=*/true);
458466
GenericSig =
459467
TmpBuilder.getGenericSignature()->getCanonicalSignature().getPointer();
460468
GenericEnv = GenericSig->createGenericEnvironment(*M.getSwiftModule());
@@ -482,7 +490,8 @@ getSignatureWithRequirements(GenericSignature *OrigGenSig,
482490
Builder.addRequirement(Req, Source);
483491
}
484492

485-
Builder.finalize(SourceLoc(), OrigGenSig->getGenericParams());
493+
Builder.finalize(SourceLoc(), OrigGenSig->getGenericParams(),
494+
/*allowConcreteGenericParams=*/true);
486495
return getGenericEnvironmentAndSignature(Builder, M);
487496
}
488497

@@ -861,17 +870,14 @@ static void prepareCallArguments(ApplySite AI, SILBuilder &Builder,
861870

862871
/// Return a substituted callee function type.
863872
static CanSILFunctionType
864-
getCalleeSubstFunctionType(SILValue Callee, const ReabstractionInfo &ReInfo) {
873+
getCalleeSubstFunctionType(SILValue Callee, SubstitutionList Subs) {
865874
// Create a substituted callee type.
866875
auto CanFnTy =
867876
dyn_cast<SILFunctionType>(Callee->getType().getSwiftRValueType());
868877
auto CalleeSubstFnTy = CanFnTy;
869878

870-
if (ReInfo.getSpecializedType()->isPolymorphic() &&
871-
!ReInfo.getCallerParamSubstitutions().empty()) {
872-
CalleeSubstFnTy = CanFnTy->substGenericArgs(
873-
ReInfo.getNonSpecializedFunction()->getModule(),
874-
ReInfo.getCallerParamSubstitutions());
879+
if (CanFnTy->isPolymorphic() && !Subs.empty()) {
880+
CalleeSubstFnTy = CanFnTy->substGenericArgs(*Callee->getModule(), Subs);
875881
assert(!CalleeSubstFnTy->isPolymorphic() &&
876882
"Substituted callee type should not be polymorphic");
877883
assert(!CalleeSubstFnTy->hasTypeParameter() &&
@@ -899,7 +905,7 @@ static ApplySite replaceWithSpecializedCallee(ApplySite AI,
899905
Subs = ReInfo.getCallerParamSubstitutions();
900906
}
901907

902-
auto CalleeSubstFnTy = getCalleeSubstFunctionType(Callee, ReInfo);
908+
auto CalleeSubstFnTy = getCalleeSubstFunctionType(Callee, Subs);
903909
auto CalleeSILSubstFnTy = SILType::getPrimitiveObjectType(CalleeSubstFnTy);
904910
SILFunctionConventions substConv(CalleeSubstFnTy, Builder.getModule());
905911

@@ -988,19 +994,35 @@ class ReabstractionThunkGenerator {
988994
Fragile = IsFragile;
989995

990996
{
991-
Mangle::Mangler M;
992-
GenericSpecializationMangler OldMangler(
993-
M, OrigF, ReInfo.getOriginalParamSubstitutions(), Fragile,
994-
GenericSpecializationMangler::NotReabstracted);
995-
OldMangler.mangle();
996-
std::string Old = M.finalize();
997-
998-
NewMangling::GenericSpecializationMangler NewMangler(
999-
OrigF, ReInfo.getOriginalParamSubstitutions(), Fragile,
1000-
/*isReAbstracted*/ false);
1001-
1002-
std::string New = NewMangler.mangle();
1003-
ThunkName = NewMangling::selectMangling(Old, New);
997+
if (!ReInfo.isPartialSpecialization()) {
998+
Mangle::Mangler M;
999+
GenericSpecializationMangler OldMangler(
1000+
M, OrigF, ReInfo.getOriginalParamSubstitutions(), Fragile,
1001+
GenericSpecializationMangler::NotReabstracted);
1002+
OldMangler.mangle();
1003+
std::string Old = M.finalize();
1004+
1005+
NewMangling::GenericSpecializationMangler NewMangler(
1006+
OrigF, ReInfo.getOriginalParamSubstitutions(), Fragile,
1007+
/*isReAbstracted*/ false);
1008+
1009+
std::string New = NewMangler.mangle();
1010+
ThunkName = NewMangling::selectMangling(Old, New);
1011+
} else {
1012+
Mangle::Mangler M;
1013+
PartialSpecializationMangler OldMangler(
1014+
M, OrigF, ReInfo.getSpecializedType(), Fragile,
1015+
PartialSpecializationMangler::NotReabstracted);
1016+
OldMangler.mangle();
1017+
std::string Old = M.finalize();
1018+
1019+
NewMangling::PartialSpecializationMangler NewMangler(
1020+
OrigF, ReInfo.getSpecializedType(), Fragile,
1021+
/*isReAbstracted*/ false);
1022+
1023+
std::string New = NewMangler.mangle();
1024+
ThunkName = NewMangling::selectMangling(Old, New);
1025+
}
10041026
}
10051027
}
10061028

@@ -1020,6 +1042,8 @@ SILFunction *ReabstractionThunkGenerator::createThunk() {
10201042
if (!Thunk->empty())
10211043
return Thunk;
10221044

1045+
Thunk->setGenericEnvironment(ReInfo.getSpecializedGenericEnvironment());
1046+
10231047
SILBasicBlock *EntryBB = Thunk->createBasicBlock();
10241048
SILBuilder Builder(EntryBB);
10251049

@@ -1068,16 +1092,19 @@ SILValue ReabstractionThunkGenerator::createReabstractionThunkApply(
10681092
SILBuilder &Builder) {
10691093
SILFunction *Thunk = &Builder.getFunction();
10701094
auto *FRI = Builder.createFunctionRef(Loc, SpecializedFunc);
1095+
auto Subs = Thunk->getForwardingSubstitutions();
1096+
auto CalleeSubstFnTy = getCalleeSubstFunctionType(FRI, Subs);
1097+
auto CalleeSILSubstFnTy = SILType::getPrimitiveObjectType(CalleeSubstFnTy);
10711098
auto specConv = SpecializedFunc->getConventions();
10721099
if (!SpecializedFunc->getLoweredFunctionType()->hasErrorResult()) {
1073-
return Builder.createApply(Loc, FRI, SpecializedFunc->getLoweredType(),
1074-
specConv.getSILResultType(), {}, Arguments,
1100+
return Builder.createApply(Loc, FRI, CalleeSILSubstFnTy,
1101+
specConv.getSILResultType(), Subs, Arguments,
10751102
false);
10761103
}
10771104
// Create the logic for calling a throwing function.
10781105
SILBasicBlock *NormalBB = Thunk->createBasicBlock();
10791106
SILBasicBlock *ErrorBB = Thunk->createBasicBlock();
1080-
Builder.createTryApply(Loc, FRI, SpecializedFunc->getLoweredType(), {},
1107+
Builder.createTryApply(Loc, FRI, CalleeSILSubstFnTy, Subs,
10811108
Arguments, NormalBB, ErrorBB);
10821109
auto *ErrorVal = ErrorBB->createPHIArgument(specConv.getSILErrorType(),
10831110
ValueOwnershipKind::Owned);
@@ -1208,11 +1235,6 @@ void swift::trySpecializeApplyOfGeneric(
12081235
bool replacePartialApplyWithoutReabstraction = false;
12091236
auto *PAI = dyn_cast<PartialApplyInst>(Apply);
12101237

1211-
// TODO: Partial specializations of partial applies are
1212-
// not supported yet.
1213-
if (PAI && ReInfo.getSpecializedType()->isPolymorphic())
1214-
return;
1215-
12161238
if (PAI && ReInfo.hasConversions()) {
12171239
// If we have a partial_apply and we converted some results/parameters from
12181240
// indirect to direct there are 3 cases:
@@ -1289,11 +1311,12 @@ void swift::trySpecializeApplyOfGeneric(
12891311
for (auto &Op : PAI->getArgumentOperands()) {
12901312
Arguments.push_back(Op.get());
12911313
}
1314+
auto Subs = ReInfo.getCallerParamSubstitutions();
1315+
auto CalleeSubstFnTy = getCalleeSubstFunctionType(FRI, Subs);
1316+
auto CalleeSILSubstFnTy = SILType::getPrimitiveObjectType(CalleeSubstFnTy);
12921317
auto *NewPAI = Builder.createPartialApply(PAI->getLoc(), FRI,
1293-
PAI->getSubstCalleeSILType(),
1294-
{},
1295-
Arguments,
1296-
PAI->getType());
1318+
CalleeSILSubstFnTy, Subs,
1319+
Arguments, PAI->getType());
12971320
PAI->replaceAllUsesWith(NewPAI);
12981321
DeadApplies.insert(PAI);
12991322
return;

0 commit comments

Comments
 (0)