Skip to content

Commit 8338795

Browse files
authored
Merge pull request #9109 from slavapestov/substitution-map-devirt-fix
Small devirtualizer cleanup and fix
2 parents 749e05b + 221df61 commit 8338795

File tree

9 files changed

+64
-89
lines changed

9 files changed

+64
-89
lines changed

include/swift/AST/GenericSignature.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,6 @@ class alignas(1 << TypeAlignInBits) GenericSignature final
201201
Optional<ProtocolConformanceRef>
202202
lookupConformance(CanType depTy, ProtocolDecl *proto) const;
203203

204-
using GenericFunction = auto(CanType canType, Type conformingReplacementType,
205-
ProtocolType *conformedProtocol)
206-
->Optional<ProtocolConformanceRef>;
207-
using LookupConformanceFn = llvm::function_ref<GenericFunction>;
208-
209-
/// Build an array of substitutions from an interface type substitution map,
210-
/// using the given function to look up conformances.
211-
void getSubstitutions(TypeSubstitutionFn substitution,
212-
LookupConformanceFn lookupConformance,
213-
SmallVectorImpl<Substitution> &result) const;
214-
215204
/// Build an array of substitutions from an interface type substitution map,
216205
/// using the given function to look up conformances.
217206
void getSubstitutions(const SubstitutionMap &subMap,

lib/AST/GenericEnvironment.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -342,17 +342,21 @@ Type GenericEnvironment::getSugaredType(Type type) const {
342342

343343
SubstitutionList
344344
GenericEnvironment::getForwardingSubstitutions() const {
345+
auto *genericSig = getGenericSignature();
346+
347+
SubstitutionMap subMap = genericSig->getSubstitutionMap(
348+
QueryInterfaceTypeSubstitutions(this),
349+
MakeAbstractConformanceForGenericType());
350+
345351
SmallVector<Substitution, 4> result;
346-
getGenericSignature()->getSubstitutions(QueryInterfaceTypeSubstitutions(this),
347-
MakeAbstractConformanceForGenericType(),
348-
result);
349-
return getGenericSignature()->getASTContext().AllocateCopy(result);
352+
genericSig->getSubstitutions(subMap, result);
353+
return genericSig->getASTContext().AllocateCopy(result);
350354
}
351355

352356
SubstitutionMap
353357
GenericEnvironment::
354358
getSubstitutionMap(TypeSubstitutionFn subs,
355-
GenericSignature::LookupConformanceFn lookupConformance) const {
359+
LookupConformanceFn lookupConformance) const {
356360
SubstitutionMap subMap(const_cast<GenericEnvironment *>(this));
357361

358362
getGenericSignature()->enumeratePairedRequirements(

lib/AST/GenericSignature.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ GenericSignature::getSubstitutionMap(SubstitutionList subs) const {
405405
SubstitutionMap
406406
GenericSignature::
407407
getSubstitutionMap(TypeSubstitutionFn subs,
408-
GenericSignature::LookupConformanceFn lookupConformance) const {
408+
LookupConformanceFn lookupConformance) const {
409409
SubstitutionMap subMap(const_cast<GenericSignature *>(this));
410410

411411
// Enumerate all of the requirements that require substitution.
@@ -437,33 +437,30 @@ getSubstitutionMap(TypeSubstitutionFn subs,
437437
}
438438

439439
void GenericSignature::
440-
getSubstitutions(TypeSubstitutionFn subs,
441-
GenericSignature::LookupConformanceFn lookupConformance,
440+
getSubstitutions(const SubstitutionMap &subMap,
442441
SmallVectorImpl<Substitution> &result) const {
443442

444443
// Enumerate all of the requirements that require substitution.
445444
enumeratePairedRequirements([&](Type depTy, ArrayRef<Requirement> reqs) {
446445
auto &ctx = getASTContext();
447446

448447
// Compute the replacement type.
449-
Type currentReplacement = depTy.subst(subs, lookupConformance);
448+
Type currentReplacement = depTy.subst(subMap);
450449
if (!currentReplacement)
451450
currentReplacement = ErrorType::get(depTy);
452451

453452
// Collect the conformances.
454453
SmallVector<ProtocolConformanceRef, 4> currentConformances;
455454
for (auto req: reqs) {
456455
assert(req.getKind() == RequirementKind::Conformance);
457-
auto protoType = req.getSecondType()->castTo<ProtocolType>();
458-
if (auto conformance = lookupConformance(depTy->getCanonicalType(),
459-
currentReplacement,
460-
protoType)) {
456+
auto protoDecl = req.getSecondType()->castTo<ProtocolType>()->getDecl();
457+
if (auto conformance = subMap.lookupConformance(depTy->getCanonicalType(),
458+
protoDecl)) {
461459
currentConformances.push_back(*conformance);
462460
} else {
463461
if (!currentReplacement->hasError())
464462
currentReplacement = ErrorType::get(currentReplacement);
465-
currentConformances.push_back(
466-
ProtocolConformanceRef(protoType->getDecl()));
463+
currentConformances.push_back(ProtocolConformanceRef(protoDecl));
467464
}
468465
}
469466

@@ -477,14 +474,6 @@ getSubstitutions(TypeSubstitutionFn subs,
477474
});
478475
}
479476

480-
void GenericSignature::
481-
getSubstitutions(const SubstitutionMap &subMap,
482-
SmallVectorImpl<Substitution> &result) const {
483-
getSubstitutions(QuerySubstitutionMap{subMap},
484-
LookUpConformanceInSubstitutionMap(subMap),
485-
result);
486-
}
487-
488477
bool GenericSignature::requiresClass(Type type, ModuleDecl &mod) {
489478
if (!type->isTypeParameter()) return false;
490479

lib/SIL/TypeLowering.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,17 +2518,17 @@ TypeConverter::getInterfaceBoxTypeForCapture(ValueDecl *captured,
25182518
SILField(loweredInterfaceType, isMutable));
25192519

25202520
// Instantiate the layout with identity substitutions.
2521-
SmallVector<Substitution, 4> genericArgs;
2522-
signature->getSubstitutions(
2523-
[&](SubstitutableType* type) -> Type {
2521+
auto subMap = signature->getSubstitutionMap(
2522+
[&](SubstitutableType *type) -> Type {
25242523
return signature->getCanonicalTypeInContext(type,
25252524
*M.getSwiftModule());
25262525
},
25272526
[](Type depTy, Type replacementTy, ProtocolType *conformedTy)
25282527
-> ProtocolConformanceRef {
25292528
return ProtocolConformanceRef(conformedTy->getDecl());
2530-
},
2531-
genericArgs);
2529+
});
2530+
SmallVector<Substitution, 4> genericArgs;
2531+
signature->getSubstitutions(subMap, genericArgs);
25322532

25332533
auto boxTy = SILBoxType::get(C, layout, genericArgs);
25342534
#ifndef NDEBUG

lib/SILGen/SILGenConstructor.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -926,8 +926,7 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
926926
// Generate a set of substitutions for the initialization function,
927927
// whose generic signature is that of the type context, and whose
928928
// replacement types are the archetypes of the initializer itself.
929-
SmallVector<Substitution, 4> subsVec;
930-
typeGenericSig->getSubstitutions(
929+
auto subMap = typeGenericSig->getSubstitutionMap(
931930
[&](SubstitutableType *type) {
932931
if (auto gp = type->getAs<GenericTypeParamType>()) {
933932
return genericEnv->mapTypeIntoContext(gp);
@@ -940,8 +939,9 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
940939
ProtocolType *conformedProtocol) {
941940
return ProtocolConformanceRef(
942941
conformedProtocol->getDecl());
943-
},
944-
subsVec);
942+
});
943+
SmallVector<Substitution, 4> subsVec;
944+
typeGenericSig->getSubstitutions(subMap, subsVec);
945945
subs = SGM.getASTContext().AllocateCopy(subsVec);
946946
}
947947

lib/SILOptimizer/Utils/Devirtualize.cpp

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -778,23 +778,21 @@ getSubstitutionsForProtocolConformance(ProtocolConformanceRef CRef) {
778778
/// \param requirementSig The generic signature of the requirement
779779
/// \param witnessThunkSig The generic signature of the witness method
780780
/// \param origSubs The substitutions from the call instruction
781-
/// \param newSubs New substitutions are stored here
782-
static void getWitnessMethodSubstitutions(
783-
SILModule &M,
781+
static SubstitutionMap
782+
getWitnessMethodSubstitutions(
784783
ProtocolConformanceRef conformanceRef,
785784
GenericSignature *requirementSig,
786785
GenericSignature *witnessThunkSig,
787786
SubstitutionList origSubs,
788-
bool isDefaultWitness,
789-
SmallVectorImpl<Substitution> &newSubs) {
787+
bool isDefaultWitness) {
790788

791789
if (witnessThunkSig == nullptr)
792-
return;
790+
return SubstitutionMap();
793791

794-
if (isDefaultWitness) {
795-
newSubs.append(origSubs.begin(), origSubs.end());
796-
return;
797-
}
792+
auto origSubMap = requirementSig->getSubstitutionMap(origSubs);
793+
794+
if (isDefaultWitness)
795+
return origSubMap;
798796

799797
assert(!conformanceRef.isAbstract());
800798
auto conformance = conformanceRef.getConcrete();
@@ -809,24 +807,19 @@ static void getWitnessMethodSubstitutions(
809807
baseDepth = witnessSig->getGenericParams().back()->getDepth() + 1;
810808

811809
auto origDepth = 1;
812-
auto origSubMap = requirementSig->getSubstitutionMap(origSubs);
813810

814-
auto subMap =
815-
SubstitutionMap::combineSubstitutionMaps(baseSubMap,
816-
origSubMap,
817-
CombineSubstitutionMaps::AtDepth,
818-
baseDepth,
819-
origDepth,
820-
witnessThunkSig);
821-
822-
witnessThunkSig->getSubstitutions(subMap, newSubs);
811+
return SubstitutionMap::combineSubstitutionMaps(
812+
baseSubMap,
813+
origSubMap,
814+
CombineSubstitutionMaps::AtDepth,
815+
baseDepth,
816+
origDepth,
817+
witnessThunkSig);
823818
}
824819

825-
static void getWitnessMethodSubstitutions(ApplySite AI, SILFunction *F,
826-
ProtocolConformanceRef CRef,
827-
SmallVectorImpl<Substitution> &NewSubs) {
828-
auto &Module = AI.getModule();
829-
820+
static SubstitutionMap
821+
getWitnessMethodSubstitutions(SILModule &Module, ApplySite AI, SILFunction *F,
822+
ProtocolConformanceRef CRef) {
830823
auto requirementSig = AI.getOrigCalleeType()->getGenericSignature();
831824
auto witnessThunkSig = F->getLoweredFunctionType()->getGenericSignature();
832825

@@ -839,8 +832,9 @@ static void getWitnessMethodSubstitutions(ApplySite AI, SILFunction *F,
839832
*Module.getSwiftModule())
840833
== CRef.getRequirement();
841834

842-
getWitnessMethodSubstitutions(Module, CRef, requirementSig, witnessThunkSig,
843-
origSubs, isDefaultWitness, NewSubs);
835+
return getWitnessMethodSubstitutions(
836+
CRef, requirementSig, witnessThunkSig,
837+
origSubs, isDefaultWitness);
844838
}
845839

846840
/// Generate a new apply of a function_ref to replace an apply of a
@@ -858,14 +852,12 @@ devirtualizeWitnessMethod(ApplySite AI, SILFunction *F,
858852
// The complete set of substitutions may be different, e.g. because the found
859853
// witness thunk F may have been created by a specialization pass and have
860854
// additional generic parameters.
861-
SmallVector<Substitution, 4> NewSubs;
862-
863-
getWitnessMethodSubstitutions(AI, F, C, NewSubs);
855+
auto SubMap = getWitnessMethodSubstitutions(Module, AI, F, C);
864856

865857
// Figure out the exact bound type of the function to be called by
866858
// applying all substitutions.
867859
auto CalleeCanType = F->getLoweredFunctionType();
868-
auto SubstCalleeCanType = CalleeCanType->substGenericArgs(Module, NewSubs);
860+
auto SubstCalleeCanType = CalleeCanType->substGenericArgs(Module, SubMap);
869861

870862
// Collect arguments from the apply instruction.
871863
auto Arguments = SmallVector<SILValue, 4>();
@@ -894,6 +886,10 @@ devirtualizeWitnessMethod(ApplySite AI, SILFunction *F,
894886
auto ResultSILType = substConv.getSILResultType();
895887
ApplySite SAI;
896888

889+
SmallVector<Substitution, 4> NewSubs;
890+
if (auto GenericSig = CalleeCanType->getGenericSignature())
891+
GenericSig->getSubstitutions(SubMap, NewSubs);
892+
897893
SILValue ResultValue;
898894
if (auto *A = dyn_cast<ApplyInst>(AI)) {
899895
auto *NewAI =

lib/SILOptimizer/Utils/Generics.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,9 +1299,7 @@ FunctionSignaturePartialSpecializer::
12991299

13001300
void FunctionSignaturePartialSpecializer::computeClonerParamSubs(
13011301
SubstitutionList &ClonerParamSubs) {
1302-
SmallVector<Substitution, 4> List;
1303-
1304-
CalleeGenericSig->getSubstitutions(
1302+
auto SubMap = CalleeGenericSig->getSubstitutionMap(
13051303
[&](SubstitutableType *type) -> Type {
13061304
DEBUG(llvm::dbgs() << "\ngetSubstitution for ClonerParamSubs:\n"
13071305
<< Type(type) << "\n"
@@ -1312,8 +1310,10 @@ void FunctionSignaturePartialSpecializer::computeClonerParamSubs(
13121310
return SpecializedGenericEnv->mapTypeIntoContext(
13131311
SpecializedInterfaceTy);
13141312
},
1315-
LookUpConformanceInSignature(*SpecializedGenericSig), List);
1313+
LookUpConformanceInSignature(*SpecializedGenericSig));
13161314

1315+
SmallVector<Substitution, 4> List;
1316+
CalleeGenericSig->getSubstitutions(SubMap, List);
13171317
ClonerParamSubs = Ctx.AllocateCopy(List);
13181318
verifySubstitutionList(ClonerParamSubs, "ClonerParamSubs");
13191319
}

lib/Sema/CSApply.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,11 @@ void Solution::computeSubstitutions(
9595
ConformanceCheckFlags::Used));
9696
};
9797

98-
sig->getSubstitutions(QueryTypeSubstitutionMap{subs},
99-
lookupConformanceFn, result);
98+
auto subMap = sig->getSubstitutionMap(
99+
QueryTypeSubstitutionMap{subs},
100+
lookupConformanceFn);
101+
102+
sig->getSubstitutions(subMap, result);
100103
}
101104

102105
void Solution::computeSubstitutions(

lib/Sema/TypeCheckType.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,7 +2479,7 @@ Type TypeResolver::resolveSILBoxType(SILBoxTypeRepr *repr,
24792479
}
24802480

24812481
bool ok = true;
2482-
genericSig->getSubstitutions(
2482+
auto subMap = genericSig->getSubstitutionMap(
24832483
QueryTypeSubstitutionMap{genericArgMap},
24842484
[&](CanType depTy, Type replacement, ProtocolType *proto)
24852485
-> ProtocolConformanceRef {
@@ -2492,17 +2492,11 @@ Type TypeResolver::resolveSILBoxType(SILBoxTypeRepr *repr,
24922492
}
24932493

24942494
return *result;
2495-
},
2496-
genericArgs);
2495+
});
2496+
genericSig->getSubstitutions(subMap, genericArgs);
24972497

24982498
if (!ok)
24992499
return ErrorType::get(Context);
2500-
2501-
// Canonicalize the replacement types.
2502-
for (auto &arg : genericArgs) {
2503-
arg = Substitution(arg.getReplacement()->getCanonicalType(),
2504-
arg.getConformances());
2505-
}
25062500
}
25072501

25082502
auto layout = SILLayout::get(Context, genericSig, fields);

0 commit comments

Comments
 (0)