29
29
30
30
namespace swift {
31
31
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
+
32
61
// / SILCloner - Abstract SIL visitor which knows how to clone instructions and
33
62
// / whose behavior can be customized by subclasses via the CRTP. This is meant
34
63
// / to be subclassed to implement inlining, function specialization, and other
@@ -49,7 +78,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
49
78
50
79
SILBuilder Builder;
51
80
DominanceInfo *DomTree = nullptr ;
52
- TypeSubstitutionMap LocalArchetypeSubs ;
81
+ SubstitutionMapWithLocalArchetypes Functor ;
53
82
54
83
// The old-to-new value map.
55
84
llvm::DenseMap<SILValue, SILValue> ValueMap;
@@ -78,7 +107,8 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
78
107
explicit SILCloner (SILFunction &F, DominanceInfo *DT = nullptr )
79
108
: Builder(F), DomTree(DT) {}
80
109
81
- explicit SILCloner (SILGlobalVariable *GlobVar) : Builder(GlobVar) {}
110
+ explicit SILCloner (SILGlobalVariable *GlobVar)
111
+ : Builder(GlobVar) {}
82
112
83
113
void clearClonerState () {
84
114
ValueMap.clear ();
@@ -167,7 +197,7 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
167
197
// / Register a re-mapping for local archetypes such as opened existentials.
168
198
void registerLocalArchetypeRemapping (ArchetypeType *From,
169
199
ArchetypeType *To) {
170
- auto result = LocalArchetypeSubs.insert (
200
+ auto result = Functor. LocalArchetypeSubs .insert (
171
201
std::make_pair (CanArchetypeType (From), CanType (To)));
172
202
assert (result.second );
173
203
(void )result;
@@ -189,62 +219,31 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
189
219
}
190
220
191
221
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 ();
200
235
}
201
236
}
237
+ #endif
202
238
203
- return asImpl ().remapSubstitutionMap (Subs)
204
- .getCanonical (/* canonicalizeSignature*/ false );
239
+ return substSubs;
205
240
}
206
241
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
- }
225
242
SILType getOpType (SILType Ty) {
226
- Ty = getTypeInClonedContext (Ty);
227
243
return asImpl ().remapType (Ty);
228
244
}
229
245
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
-
246
246
CanType getOpASTType (CanType ty) {
247
- ty = getASTTypeInClonedContext (ty);
248
247
return asImpl ().remapASTType (ty);
249
248
}
250
249
@@ -352,17 +351,22 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
352
351
353
352
ProtocolConformanceRef getOpConformance (Type ty,
354
353
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 ();
362
366
}
367
+ #endif
363
368
364
- return asImpl ().remapConformance (getASTTypeInClonedContext (ty),
365
- conformance);
369
+ return substConf;
366
370
}
367
371
368
372
ArrayRef<ProtocolConformanceRef>
@@ -445,16 +449,31 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
445
449
SILLocation remapLocation (SILLocation Loc) { return Loc; }
446
450
const SILDebugScope *remapScope (const SILDebugScope *DS) { return DS; }
447
451
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
+ }
450
457
451
- CanType remapASTType (CanType Ty) {
452
458
return Ty;
453
459
}
454
460
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
+
455
469
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
+
456
474
return C;
457
475
}
476
+
458
477
// / Get the value that takes the place of the given `Value` within the cloned
459
478
// / region. The given value must already have been mapped by this cloner.
460
479
SILValue getMappedValue (SILValue Value);
@@ -464,7 +483,13 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
464
483
SILBasicBlock *remapBasicBlock (SILBasicBlock *BB);
465
484
void postProcess (SILInstruction *Orig, SILInstruction *Cloned);
466
485
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
+ }
468
493
469
494
// / This is called by either of the top-level visitors, cloneReachableBlocks
470
495
// / or cloneSILFunction, after all other visitors are have been called.
0 commit comments