Skip to content

Commit b426502

Browse files
committed
SIL: Use MapLocalArchetypesOutOfContext directly from buildSILFunctionThunkType()
1 parent 39b4bda commit b426502

File tree

1 file changed

+37
-108
lines changed

1 file changed

+37
-108
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 37 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -2902,48 +2902,23 @@ CanSILFunctionType swift::getNativeSILFunctionType(
29022902
/// Build a generic signature and environment for a re-abstraction thunk.
29032903
///
29042904
/// Most thunks share the generic environment with their original function.
2905-
/// The one exception is if the thunk type involves an open existential,
2906-
/// in which case we "promote" the opened existential to a new generic parameter.
2907-
///
2908-
/// \param localArchetypes - the list of local archetypes to promote
2909-
/// into the signature, if any
2910-
/// \param genericEnv - the new generic environment
2911-
/// \param contextSubs - map non-local archetypes from the original function
2912-
/// to archetypes in the thunk
2913-
/// \param interfaceSubs - map interface types to old archetypes
2905+
/// The one exception is if the thunk type involves local archetypes,
2906+
/// in which case we "promote" the local archetypes to new generic parameters.
29142907
static CanGenericSignature
29152908
buildThunkSignature(SILFunction *fn,
2916-
ArrayRef<CanLocalArchetypeType> localArchetypes,
2909+
CanGenericSignature baseGenericSig,
2910+
ArrayRef<GenericEnvironment *> capturedEnvs,
29172911
GenericEnvironment *&genericEnv,
2918-
SubstitutionMap &contextSubs,
2919-
SubstitutionMap &interfaceSubs,
2920-
llvm::DenseMap<ArchetypeType*, Type> &contextLocalArchetypes) {
2921-
auto *mod = fn->getModule().getSwiftModule();
2922-
auto &ctx = mod->getASTContext();
2912+
SubstitutionMap &interfaceSubs) {
2913+
auto &ctx = fn->getASTContext();
29232914
auto forwardingSubs = fn->getForwardingSubstitutionMap();
29242915

29252916
// If there are no local archetypes, we just inherit the generic
29262917
// environment from the parent function.
2927-
if (localArchetypes.empty()) {
2928-
auto genericSig =
2929-
fn->getLoweredFunctionType()->getInvocationGenericSignature();
2918+
if (capturedEnvs.empty()) {
29302919
genericEnv = fn->getGenericEnvironment();
29312920
interfaceSubs = forwardingSubs;
2932-
contextSubs = interfaceSubs;
2933-
return genericSig;
2934-
}
2935-
2936-
// Get the existing generic signature.
2937-
auto baseGenericSig =
2938-
fn->getLoweredFunctionType()->getInvocationGenericSignature();
2939-
2940-
SmallVector<GenericEnvironment *, 2> capturedEnvs;
2941-
for (auto archetype : localArchetypes) {
2942-
auto *genericEnv = archetype->getGenericEnvironment();
2943-
if (std::find(capturedEnvs.begin(), capturedEnvs.end(), genericEnv)
2944-
== capturedEnvs.end()) {
2945-
capturedEnvs.push_back(genericEnv);
2946-
}
2921+
return baseGenericSig;
29472922
}
29482923

29492924
auto genericSig = buildGenericSignatureWithCapturedEnvironments(
@@ -2952,44 +2927,11 @@ buildThunkSignature(SILFunction *fn,
29522927

29532928
genericEnv = genericSig.getGenericEnvironment();
29542929

2955-
MapLocalArchetypesOutOfContext mapOutOfContext(baseGenericSig, capturedEnvs);
2956-
2957-
// Map the local archetypes to their new parameter types.
2958-
for (auto localArchetype : localArchetypes) {
2959-
auto thunkInterfaceType = Type(localArchetype).subst(
2960-
mapOutOfContext,
2961-
MakeAbstractConformanceForGenericType(),
2962-
SubstFlags::PreservePackExpansionLevel |
2963-
SubstFlags::SubstituteLocalArchetypes);
2964-
auto thunkArchetype = genericEnv->mapTypeIntoContext(
2965-
thunkInterfaceType);
2966-
contextLocalArchetypes.insert(std::make_pair(localArchetype,
2967-
thunkArchetype));
2968-
}
2969-
2970-
// Calculate substitutions to map the caller's archetypes to the thunk's
2971-
// archetypes.
2972-
if (auto calleeGenericSig = fn->getLoweredFunctionType()
2973-
->getInvocationGenericSignature()) {
2974-
contextSubs = SubstitutionMap::get(
2975-
calleeGenericSig,
2976-
genericEnv->getForwardingSubstitutionMap());
2977-
}
2978-
29792930
// Calculate substitutions to map interface types to the caller's archetypes.
29802931
interfaceSubs = buildSubstitutionMapWithCapturedEnvironments(
29812932
forwardingSubs, genericSig, capturedEnvs);
29822933
LLVM_DEBUG(llvm::dbgs() << "Thunk substitution map: " << interfaceSubs << "\n");
29832934

2984-
for (auto pair : contextLocalArchetypes) {
2985-
auto substArchetype = Type(pair.second).subst(interfaceSubs);
2986-
if (!pair.first->isEqual(substArchetype)) {
2987-
llvm::errs() << "Expected: "; pair.first->dump(llvm::errs());
2988-
llvm::errs() << "Got: "; substArchetype->dump(llvm::errs());
2989-
abort();
2990-
}
2991-
}
2992-
29932935
return genericSig.getCanonicalSignature();
29942936
}
29952937

@@ -3026,12 +2968,14 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
30262968
extInfoBuilder = extInfoBuilder.withNoEscape(false);
30272969

30282970
// Does the thunk type involve a local archetype type?
3029-
SmallVector<CanLocalArchetypeType, 8> localArchetypes;
2971+
SmallVector<GenericEnvironment *, 2> capturedEnvs;
30302972
auto archetypeVisitor = [&](CanType t) {
30312973
if (auto local = dyn_cast<LocalArchetypeType>(t)) {
3032-
auto root = local.getRoot();
3033-
if (llvm::find(localArchetypes, root) == localArchetypes.end())
3034-
localArchetypes.push_back(root);
2974+
auto *genericEnv = local->getGenericEnvironment();
2975+
if (std::find(capturedEnvs.begin(), capturedEnvs.end(), genericEnv)
2976+
== capturedEnvs.end()) {
2977+
capturedEnvs.push_back(genericEnv);
2978+
}
30352979
}
30362980
};
30372981

@@ -3043,57 +2987,42 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
30432987
// Use the generic signature from the context if the thunk involves
30442988
// generic parameters.
30452989
CanGenericSignature genericSig;
3046-
SubstitutionMap contextSubs;
3047-
llvm::DenseMap<ArchetypeType*, Type> contextLocalArchetypes;
2990+
CanGenericSignature baseGenericSig;
30482991

3049-
if (!localArchetypes.empty() ||
2992+
if (!capturedEnvs.empty() ||
30502993
expectedType->hasPrimaryArchetype() ||
30512994
sourceType->hasPrimaryArchetype()) {
2995+
// Get the existing generic signature.
2996+
baseGenericSig = fn->getLoweredFunctionType()
2997+
->getInvocationGenericSignature();
2998+
30522999
genericSig = buildThunkSignature(fn,
3053-
localArchetypes,
3000+
baseGenericSig,
3001+
capturedEnvs,
30543002
genericEnv,
3055-
contextSubs,
3056-
interfaceSubs,
3057-
contextLocalArchetypes);
3003+
interfaceSubs);
30583004
}
30593005

3060-
auto substTypeHelper = [&](SubstitutableType *type) -> Type {
3061-
// If it's a local archetype, do an ad-hoc mapping through the
3062-
// map produced by buildThunkSignature.
3063-
if (auto *archetype = dyn_cast<LocalArchetypeType>(type)) {
3064-
assert(!contextLocalArchetypes.empty());
3065-
3066-
// Decline to map non-root archetypes; subst() will come back
3067-
// to us later and ask about the root.
3068-
if (!archetype->isRoot())
3069-
return Type();
3070-
3071-
auto it = contextLocalArchetypes.find(archetype);
3072-
assert(it != contextLocalArchetypes.end());
3073-
return it->second;
3074-
}
3075-
3076-
// Otherwise, use the context substitutions.
3077-
return Type(type).subst(contextSubs);
3078-
};
3079-
auto substConformanceHelper =
3080-
LookUpConformanceInSubstitutionMap(contextSubs);
3081-
3082-
// Utility function to apply contextSubs, and also replace the
3083-
// opened existential with the new archetype.
3006+
MapLocalArchetypesOutOfContext mapOutOfContext(baseGenericSig, capturedEnvs);
30843007
auto substFormalTypeIntoThunkContext =
30853008
[&](CanType t) -> CanType {
3086-
return t.subst(substTypeHelper, substConformanceHelper,
3087-
SubstFlags::SubstituteLocalArchetypes)
3009+
return genericEnv->mapTypeIntoContext(
3010+
t.subst(mapOutOfContext,
3011+
MakeAbstractConformanceForGenericType(),
3012+
SubstFlags::PreservePackExpansionLevel |
3013+
SubstFlags::SubstituteLocalArchetypes))
30883014
->getCanonicalType();
30893015
};
30903016
auto substLoweredTypeIntoThunkContext =
30913017
[&](CanSILFunctionType t) -> CanSILFunctionType {
3092-
return SILType::getPrimitiveObjectType(t)
3093-
.subst(fn->getModule(), substTypeHelper, substConformanceHelper,
3094-
CanGenericSignature(),
3095-
SubstFlags::SubstituteLocalArchetypes)
3096-
.castTo<SILFunctionType>();
3018+
return cast<SILFunctionType>(
3019+
genericEnv->mapTypeIntoContext(
3020+
Type(t).subst(mapOutOfContext,
3021+
MakeAbstractConformanceForGenericType(),
3022+
SubstFlags::PreservePackExpansionLevel |
3023+
SubstFlags::SubstituteLocalArchetypes |
3024+
SubstFlags::AllowLoweredTypes))
3025+
->getCanonicalType());
30973026
};
30983027

30993028
sourceType = substLoweredTypeIntoThunkContext(sourceType);

0 commit comments

Comments
 (0)