Skip to content

Commit 63028be

Browse files
committed
SILCloner: Redo local archetype remapping
1 parent e9b6f0b commit 63028be

File tree

3 files changed

+64
-59
lines changed

3 files changed

+64
-59
lines changed

include/swift/SIL/SILCloner.h

Lines changed: 58 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "swift/AST/ConformanceLookup.h"
2121
#include "swift/AST/GenericEnvironment.h"
22+
#include "swift/AST/LocalArchetypeRequirementCollector.h"
2223
#include "swift/AST/ProtocolConformance.h"
2324
#include "swift/SIL/BasicBlockUtils.h"
2425
#include "swift/SIL/DebugUtils.h"
@@ -32,14 +33,47 @@ namespace swift {
3233

3334
struct SubstitutionMapWithLocalArchetypes {
3435
std::optional<SubstitutionMap> SubsMap;
35-
TypeSubstitutionMap LocalArchetypeSubs;
36+
llvm::DenseMap<GenericEnvironment *, GenericEnvironment *> LocalArchetypeSubs;
37+
GenericSignature BaseGenericSig;
38+
llvm::ArrayRef<GenericEnvironment *> CapturedEnvs;
39+
40+
bool hasLocalArchetypes() const {
41+
return !LocalArchetypeSubs.empty() || !CapturedEnvs.empty();
42+
}
3643

3744
SubstitutionMapWithLocalArchetypes() {}
3845
SubstitutionMapWithLocalArchetypes(SubstitutionMap subs) : SubsMap(subs) {}
3946

4047
Type operator()(SubstitutableType *type) {
41-
if (isa<LocalArchetypeType>(type))
42-
return QueryTypeSubstitutionMap{LocalArchetypeSubs}(type);
48+
if (auto *local = dyn_cast<LocalArchetypeType>(type)) {
49+
auto *origEnv = local->getGenericEnvironment();
50+
51+
// Special handling of captured environments, which don't appear in
52+
// LocalArchetypeSubs. This only happens with the LocalArchetypeTransform
53+
// in SILGenLocalArchetype.cpp.
54+
auto found = LocalArchetypeSubs.find(origEnv);
55+
if (found == LocalArchetypeSubs.end()) {
56+
if (std::find(CapturedEnvs.begin(), CapturedEnvs.end(), origEnv)
57+
== CapturedEnvs.end()) {
58+
return Type();
59+
}
60+
61+
// Map the local archetype to an interface type in the new generic
62+
// signature.
63+
MapLocalArchetypesOutOfContext mapOutOfContext(BaseGenericSig,
64+
CapturedEnvs);
65+
auto interfaceTy = mapOutOfContext(local);
66+
67+
// Map this interface type into the new generic environment to get
68+
// a primary archetype.
69+
return interfaceTy.subst(*SubsMap);
70+
}
71+
72+
auto *newEnv = found->second;
73+
74+
auto interfaceTy = local->getInterfaceType();
75+
return newEnv->mapTypeIntoContext(interfaceTy);
76+
}
4377

4478
if (SubsMap)
4579
return Type(type).subst(*SubsMap);
@@ -210,10 +244,12 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
210244
}
211245

212246
/// Register a re-mapping for local archetypes such as opened existentials.
213-
void registerLocalArchetypeRemapping(ArchetypeType *From,
214-
ArchetypeType *To) {
215-
auto result = Functor.LocalArchetypeSubs.insert(
216-
std::make_pair(CanArchetypeType(From), CanType(To)));
247+
void registerLocalArchetypeRemapping(GenericEnvironment *From,
248+
GenericEnvironment *To) {
249+
ASSERT(From->getGenericSignature()->getMaxDepth()
250+
== To->getGenericSignature()->getMaxDepth());
251+
252+
auto result = Functor.LocalArchetypeSubs.insert(std::make_pair(From, To));
217253
assert(result.second);
218254
(void)result;
219255
}
@@ -344,13 +380,17 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
344380
}
345381

346382
void remapRootOpenedType(CanOpenedArchetypeType archetypeTy) {
347-
assert(archetypeTy->isRoot());
348-
349-
auto origExistentialTy = archetypeTy->getExistentialType()
383+
auto *origEnv = archetypeTy->getGenericEnvironment();
384+
auto subMap = origEnv->getOuterSubstitutions();
385+
ASSERT(!subMap && "Transform the substitution map!");
386+
auto origExistentialTy = origEnv->getOpenedExistentialType()
350387
->getCanonicalType();
388+
351389
auto substExistentialTy = getOpASTType(origExistentialTy);
352-
auto replacementTy = OpenedArchetypeType::get(substExistentialTy);
353-
registerLocalArchetypeRemapping(archetypeTy, replacementTy);
390+
auto *newEnv = GenericEnvironment::forOpenedExistential(
391+
substExistentialTy, subMap, UUID::fromTime());
392+
393+
registerLocalArchetypeRemapping(origEnv, newEnv);
354394
}
355395

356396
/// SILCloner will take care of debug scope on the instruction
@@ -469,7 +509,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
469509
SILType remapType(SILType Ty) {
470510
if (Functor.SubsMap || Ty.hasLocalArchetype()) {
471511
SubstOptions options(std::nullopt);
472-
if (!Functor.LocalArchetypeSubs.empty())
512+
if (Functor.hasLocalArchetypes())
473513
options |= SubstFlags::SubstituteLocalArchetypes;
474514

475515
Ty = Ty.subst(Builder.getModule(), Functor, Functor,
@@ -494,7 +534,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
494534
CanType remapASTType(CanType ty) {
495535
if (Functor.SubsMap || ty->hasLocalArchetype()) {
496536
SubstOptions options(std::nullopt);
497-
if (!Functor.LocalArchetypeSubs.empty())
537+
if (Functor.hasLocalArchetypes())
498538
options |= SubstFlags::SubstituteLocalArchetypes;
499539

500540
ty = ty.subst(Functor, Functor, options)->getCanonicalType();
@@ -518,7 +558,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
518558
ProtocolConformanceRef remapConformance(Type Ty, ProtocolConformanceRef C) {
519559
if (Functor.SubsMap || Ty->hasLocalArchetype()) {
520560
SubstOptions options(std::nullopt);
521-
if (!Functor.LocalArchetypeSubs.empty())
561+
if (Functor.hasLocalArchetypes())
522562
options |= SubstFlags::SubstituteLocalArchetypes;
523563

524564
C = C.subst(Ty, Functor, Functor, options);
@@ -541,9 +581,9 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
541581

542582
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
543583
// If we have local archetypes to substitute, do so now.
544-
if (Subs.getRecursiveProperties().hasLocalArchetype() || Functor.SubsMap) {
584+
if (Functor.SubsMap || Subs.getRecursiveProperties().hasLocalArchetype()) {
545585
SubstOptions options(std::nullopt);
546-
if (!Functor.LocalArchetypeSubs.empty())
586+
if (Functor.hasLocalArchetypes())
547587
options |= SubstFlags::SubstituteLocalArchetypes;
548588

549589
Subs = Subs.subst(Functor, Functor, options);
@@ -2909,20 +2949,7 @@ void SILCloner<ImplClass>::visitOpenPackElementInst(
29092949
openedShapeClass,
29102950
newContextSubs);
29112951

2912-
// Associate the old opened archetypes with the new ones.
2913-
SmallVector<ArchetypeType*, 4> oldOpenedArchetypes;
2914-
origEnv->forEachPackElementArchetype([&](ElementArchetypeType *oldType) {
2915-
oldOpenedArchetypes.push_back(oldType);
2916-
});
2917-
{
2918-
size_t nextOldIndex = 0;
2919-
newEnv->forEachPackElementArchetype([&](ElementArchetypeType *newType) {
2920-
ArchetypeType *oldType = oldOpenedArchetypes[nextOldIndex++];
2921-
registerLocalArchetypeRemapping(oldType, newType);
2922-
});
2923-
assert(nextOldIndex == oldOpenedArchetypes.size() &&
2924-
"different opened archetype count");
2925-
}
2952+
registerLocalArchetypeRemapping(origEnv, newEnv);
29262953

29272954
recordClonedInstruction(
29282955
Inst, getBuilder().createOpenPackElement(loc, newIndexValue, newEnv));

lib/SILGen/SILGenLocalArchetype.cpp

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,33 +46,10 @@ class LocalArchetypeTransform : public SILCloner<LocalArchetypeTransform> {
4646
// index and depth.
4747
Functor.SubsMap = env->getForwardingSubstitutionMap();
4848

49-
// Local archetypes map to generic parameters at higher depths.
50-
MapLocalArchetypesOutOfContext mapOutOfContext(sig.baseGenericSig,
51-
sig.capturedEnvs);
52-
53-
// For each captured environment...
54-
for (auto *capturedEnv : sig.capturedEnvs) {
55-
// For each introduced generic parameter...
56-
auto localParams = capturedEnv->getGenericSignature()
57-
.getInnermostGenericParams();
58-
for (auto *gp : localParams) {
59-
// Get the local archetype from the captured environment.
60-
auto origArchetypeTy = capturedEnv->mapTypeIntoContext(gp)
61-
->castTo<LocalArchetypeType>();
62-
63-
// Map the local archetype to an interface type in the new generic
64-
// signature.
65-
auto substInterfaceTy = mapOutOfContext(origArchetypeTy);
66-
67-
// Map this interface type into the new generic environment to get
68-
// a primary archetype.
69-
auto substArchetypeTy = env->mapTypeIntoContext(substInterfaceTy)
70-
->castTo<PrimaryArchetypeType>();
71-
72-
// Remember this correspondence.
73-
registerLocalArchetypeRemapping(origArchetypeTy, substArchetypeTy);
74-
}
75-
}
49+
// Captured local archetypes map to primary archetypes at higher
50+
// depths.
51+
Functor.BaseGenericSig = sig.baseGenericSig;
52+
Functor.CapturedEnvs = sig.capturedEnvs;
7653
}
7754

7855
void doIt() {

lib/SILOptimizer/Transforms/CSE.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,8 @@ bool CSE::processOpenExistentialRef(OpenExistentialRefInst *Inst,
908908
// opened archetypes trivial.
909909
InstructionCloner Cloner(Inst->getFunction());
910910
Cloner.registerLocalArchetypeRemapping(
911-
OldOpenedArchetype->castTo<ArchetypeType>(), NewOpenedArchetype);
911+
OldOpenedArchetype->getGenericEnvironment(),
912+
NewOpenedArchetype->getGenericEnvironment());
912913
auto &Builder = Cloner.getBuilder();
913914

914915
// Now clone each candidate and replace the opened archetype

0 commit comments

Comments
 (0)