2929
3030namespace swift {
3131
32+ struct SubstitutionMapWithLocalArchetypes {
33+ std::optional<SubstitutionMap> SubsMap;
34+ TypeSubstitutionMap LocalArchetypeSubs;
35+
36+ SubstitutionMapWithLocalArchetypes () {}
37+ SubstitutionMapWithLocalArchetypes (SubstitutionMap subs) : SubsMap(subs) {}
38+
39+ Type operator ()(SubstitutableType *type) {
40+ if (isa<LocalArchetypeType>(type))
41+ return QueryTypeSubstitutionMap{LocalArchetypeSubs}(type);
42+
43+ if (SubsMap)
44+ return Type (type).subst (*SubsMap);
45+
46+ return Type (type);
47+ }
48+
49+ ProtocolConformanceRef operator ()(CanType origType,
50+ Type substType,
51+ ProtocolDecl *proto) {
52+ if (isa<LocalArchetypeType>(origType))
53+ return proto->getParentModule ()->lookupConformance (substType, proto);
54+ if (SubsMap)
55+ return SubsMap->lookupConformance (origType, proto);
56+
57+ return ProtocolConformanceRef (proto);
58+ }
59+ };
60+
3261// / SILCloner - Abstract SIL visitor which knows how to clone instructions and
3362// / whose behavior can be customized by subclasses via the CRTP. This is meant
3463// / to be subclassed to implement inlining, function specialization, and other
@@ -49,7 +78,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
4978
5079 SILBuilder Builder;
5180 DominanceInfo *DomTree = nullptr ;
52- TypeSubstitutionMap LocalArchetypeSubs ;
81+ SubstitutionMapWithLocalArchetypes Functor ;
5382
5483 // The old-to-new value map.
5584 llvm::DenseMap<SILValue, SILValue> ValueMap;
@@ -78,7 +107,8 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
78107 explicit SILCloner (SILFunction &F, DominanceInfo *DT = nullptr )
79108 : Builder(F), DomTree(DT) {}
80109
81- explicit SILCloner (SILGlobalVariable *GlobVar) : Builder(GlobVar) {}
110+ explicit SILCloner (SILGlobalVariable *GlobVar)
111+ : Builder(GlobVar) {}
82112
83113 void clearClonerState () {
84114 ValueMap.clear ();
@@ -167,7 +197,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
167197 // / Register a re-mapping for local archetypes such as opened existentials.
168198 void registerLocalArchetypeRemapping (ArchetypeType *From,
169199 ArchetypeType *To) {
170- auto result = LocalArchetypeSubs.insert (
200+ auto result = Functor. LocalArchetypeSubs .insert (
171201 std::make_pair (CanArchetypeType (From), CanType (To)));
172202 assert (result.second );
173203 (void )result;
@@ -189,62 +219,31 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
189219 }
190220
191221 SubstitutionMap getOpSubstitutionMap (SubstitutionMap Subs) {
192- // If we have local archetypes to substitute, check whether that's
193- // relevant to this particular substitution.
194- if (!LocalArchetypeSubs.empty ()) {
195- if (Subs.hasLocalArchetypes ()) {
196- // If we found a type containing a local archetype, substitute
197- // open existentials throughout the substitution map.
198- Subs = Subs.subst (QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
199- MakeAbstractConformanceForGenericType ());
222+ auto substSubs = asImpl ().remapSubstitutionMap (Subs)
223+ .getCanonical (/* canonicalizeSignature*/ false );
224+
225+ #ifndef NDEBUG
226+ for (auto substConf : substSubs.getConformances ()) {
227+ if (substConf.isInvalid ()) {
228+ llvm::errs () << " Invalid conformance in SIL cloner:\n " ;
229+ if (Functor.SubsMap )
230+ Functor.SubsMap ->dump (llvm::errs ());
231+ llvm::errs () << " \n substitution map:\n " ;
232+ Subs.dump (llvm::errs ());
233+ llvm::errs () << " \n " ;
234+ abort ();
200235 }
201236 }
237+ #endif
202238
203- return asImpl ().remapSubstitutionMap (Subs)
204- .getCanonical (/* canonicalizeSignature*/ false );
239+ return substSubs;
205240 }
206241
207- SILType getTypeInClonedContext (SILType Ty) {
208- auto objectTy = Ty.getASTType ();
209- // Do not substitute local archetypes, if we do not have any.
210- if (!objectTy->hasLocalArchetype ())
211- return Ty;
212- // Do not substitute local archetypes, if it is not required.
213- // This is often the case when cloning basic blocks inside the same
214- // function.
215- if (LocalArchetypeSubs.empty ())
216- return Ty;
217-
218- // Substitute local archetypes, if we have any.
219- return Ty.subst (
220- Builder.getModule (),
221- QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
222- MakeAbstractConformanceForGenericType (),
223- CanGenericSignature ());
224- }
225242 SILType getOpType (SILType Ty) {
226- Ty = getTypeInClonedContext (Ty);
227243 return asImpl ().remapType (Ty);
228244 }
229245
230- CanType getASTTypeInClonedContext (Type ty) {
231- // Do not substitute local archetypes, if we do not have any.
232- if (!ty->hasLocalArchetype ())
233- return ty->getCanonicalType ();
234- // Do not substitute local archetypes, if it is not required.
235- // This is often the case when cloning basic blocks inside the same
236- // function.
237- if (LocalArchetypeSubs.empty ())
238- return ty->getCanonicalType ();
239-
240- return ty.subst (
241- QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
242- MakeAbstractConformanceForGenericType ()
243- )->getCanonicalType ();
244- }
245-
246246 CanType getOpASTType (CanType ty) {
247- ty = getASTTypeInClonedContext (ty);
248247 return asImpl ().remapASTType (ty);
249248 }
250249
@@ -352,17 +351,22 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
352351
353352 ProtocolConformanceRef getOpConformance (Type ty,
354353 ProtocolConformanceRef conformance) {
355- // If we have local archetypes to substitute, do so now.
356- if (ty->hasLocalArchetype () && !LocalArchetypeSubs.empty ()) {
357- conformance =
358- conformance.subst (ty,
359- QueryTypeSubstitutionMapOrIdentity{
360- LocalArchetypeSubs},
361- MakeAbstractConformanceForGenericType ());
354+ auto substConf = asImpl ().remapConformance (ty, conformance);
355+
356+ #ifndef NDEBUG
357+ if (substConf.isInvalid ()) {
358+ llvm::errs () << " Invalid conformance in SIL cloner:\n " ;
359+ if (Functor.SubsMap )
360+ Functor.SubsMap ->dump (llvm::errs ());
361+ llvm::errs () << " \n conformance:\n " ;
362+ conformance.dump (llvm::errs ());
363+ llvm::errs () << " original type:\n " ;
364+ ty.dump (llvm::errs ());
365+ abort ();
362366 }
367+ #endif
363368
364- return asImpl ().remapConformance (getASTTypeInClonedContext (ty),
365- conformance);
369+ return substConf;
366370 }
367371
368372 ArrayRef<ProtocolConformanceRef>
@@ -445,16 +449,31 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
445449 SILLocation remapLocation (SILLocation Loc) { return Loc; }
446450 const SILDebugScope *remapScope (const SILDebugScope *DS) { return DS; }
447451 SILType remapType (SILType Ty) {
448- return Ty;
449- }
452+ // Substitute local archetypes, if we have any.
453+ if (Ty.hasLocalArchetype ()) {
454+ Ty = Ty.subst (Builder.getModule (), Functor, Functor,
455+ CanGenericSignature ());
456+ }
450457
451- CanType remapASTType (CanType Ty) {
452458 return Ty;
453459 }
454460
461+ CanType remapASTType (CanType ty) {
462+ // Substitute local archetypes, if we have any.
463+ if (ty->hasLocalArchetype ())
464+ ty = ty.subst (Functor, Functor)->getCanonicalType ();
465+
466+ return ty;
467+ }
468+
455469 ProtocolConformanceRef remapConformance (Type Ty, ProtocolConformanceRef C) {
470+ // If we have local archetypes to substitute, do so now.
471+ if (Ty->hasLocalArchetype ())
472+ C = C.subst (Ty, Functor, Functor);
473+
456474 return C;
457475 }
476+
458477 // / Get the value that takes the place of the given `Value` within the cloned
459478 // / region. The given value must already have been mapped by this cloner.
460479 SILValue getMappedValue (SILValue Value);
@@ -464,7 +483,13 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
464483 SILBasicBlock *remapBasicBlock (SILBasicBlock *BB);
465484 void postProcess (SILInstruction *Orig, SILInstruction *Cloned);
466485
467- SubstitutionMap remapSubstitutionMap (SubstitutionMap Subs) { return Subs; }
486+ SubstitutionMap remapSubstitutionMap (SubstitutionMap Subs) {
487+ // If we have local archetypes to substitute, do so now.
488+ if (Subs.hasLocalArchetypes ())
489+ Subs = Subs.subst (Functor, Functor);
490+
491+ return Subs;
492+ }
468493
469494 // / This is called by either of the top-level visitors, cloneReachableBlocks
470495 // / or cloneSILFunction, after all other visitors are have been called.
0 commit comments