Skip to content

Commit 3b5846d

Browse files
committed
SIL: Sink local archetype substitution into remapSubstitutionMap()
1 parent 4de6dca commit 3b5846d

File tree

4 files changed

+72
-11
lines changed

4 files changed

+72
-11
lines changed

include/swift/SIL/SILCloner.h

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,35 @@
2929

3030
namespace 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,8 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
4978

5079
SILBuilder Builder;
5180
DominanceInfo *DomTree = nullptr;
52-
TypeSubstitutionMap LocalArchetypeSubs;
81+
SubstitutionMapWithLocalArchetypes Functor;
82+
TypeSubstitutionMap &LocalArchetypeSubs;
5383

5484
// The old-to-new value map.
5585
llvm::DenseMap<SILValue, SILValue> ValueMap;
@@ -76,9 +106,10 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
76106
using SILInstructionVisitor<ImplClass>::asImpl;
77107

78108
explicit SILCloner(SILFunction &F, DominanceInfo *DT = nullptr)
79-
: Builder(F), DomTree(DT) {}
109+
: Builder(F), DomTree(DT), LocalArchetypeSubs(Functor.LocalArchetypeSubs) {}
80110

81-
explicit SILCloner(SILGlobalVariable *GlobVar) : Builder(GlobVar) {}
111+
explicit SILCloner(SILGlobalVariable *GlobVar)
112+
: Builder(GlobVar), LocalArchetypeSubs(Functor.LocalArchetypeSubs) {}
82113

83114
void clearClonerState() {
84115
ValueMap.clear();
@@ -189,12 +220,6 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
189220
}
190221

191222
SubstitutionMap getOpSubstitutionMap(SubstitutionMap Subs) {
192-
// If we have local archetypes to substitute, do so now.
193-
if (Subs.hasLocalArchetypes() && !LocalArchetypeSubs.empty()) {
194-
Subs = Subs.subst(QueryTypeSubstitutionMapOrIdentity{LocalArchetypeSubs},
195-
MakeAbstractConformanceForGenericType());
196-
}
197-
198223
return asImpl().remapSubstitutionMap(Subs)
199224
.getCanonical(/*canonicalizeSignature*/false);
200225
}
@@ -441,7 +466,13 @@ class SILCloner : protected SILInstructionVisitor<ImplClass> {
441466
SILBasicBlock *remapBasicBlock(SILBasicBlock *BB);
442467
void postProcess(SILInstruction *Orig, SILInstruction *Cloned);
443468

444-
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) { return Subs; }
469+
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
470+
// If we have local archetypes to substitute, do so now.
471+
if (Subs.hasLocalArchetypes())
472+
Subs = Subs.subst(Functor, Functor);
473+
474+
return Subs;
475+
}
445476

446477
/// This is called by either of the top-level visitors, cloneReachableBlocks
447478
/// or cloneSILFunction, after all other visitors are have been called.

include/swift/SIL/TypeSubstCloner.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
148148
using SILClonerWithScopes<ImplClass>::getOpBasicBlock;
149149
using SILClonerWithScopes<ImplClass>::recordClonedInstruction;
150150
using SILClonerWithScopes<ImplClass>::recordFoldedValue;
151+
using SILClonerWithScopes<ImplClass>::LocalArchetypeSubs;
152+
using SILClonerWithScopes<ImplClass>::Functor;
151153

152154
TypeSubstCloner(SILFunction &To,
153155
SILFunction &From,
@@ -159,6 +161,7 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
159161
SubsMap(ApplySubs),
160162
Original(From),
161163
Inlining(Inlining) {
164+
Functor.SubsMap = ApplySubs;
162165
}
163166

164167
protected:
@@ -205,9 +208,10 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
205208
}
206209

207210
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
211+
Subs = Subs.subst(Functor, Functor);
212+
208213
auto context = getBuilder().getTypeExpansionContext();
209214

210-
Subs = Subs.subst(SubsMap);
211215
if (!Subs.hasOpaqueArchetypes() ||
212216
!context.shouldLookThroughOpaqueTypeArchetypes())
213217
return Subs;

lib/SILOptimizer/IPO/CrossModuleOptimization.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ class InstructionVisitor : public SILCloner<InstructionVisitor> {
143143
}
144144

145145
SubstitutionMap remapSubstitutionMap(SubstitutionMap Subs) {
146+
if (Subs.hasLocalArchetypes())
147+
Subs = Subs.subst(Functor, Functor);
148+
146149
CMS.makeSubstUsableFromInline(Subs);
147150
return Subs;
148151
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public protocol P1 {}
4+
5+
public protocol P2<A> {
6+
associatedtype A
7+
}
8+
9+
public struct S: P1 {}
10+
11+
public struct G<A>: P2 {}
12+
13+
public func callee<T: P2>(_: T) where T.A: P1 {}
14+
15+
@_transparent
16+
public func caller<A: P1>(_ p: any P2<A>) {
17+
callee(p)
18+
}
19+
20+
public func test(_ a: G<S>, _ b: G<S>) {
21+
return caller(b)
22+
}
23+

0 commit comments

Comments
 (0)