@@ -47,6 +47,86 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
47
47
}
48
48
}
49
49
50
+ // A helper class for cloning different kinds of apply instructions.
51
+ // Supports cloning of self-recursive functions.
52
+ class ApplySiteCloningHelper {
53
+ SILValue Callee;
54
+ SubstitutionList Subs;
55
+ SmallVector<SILValue, 8 > Args;
56
+ SmallVector<Substitution, 8 > NewSubsList;
57
+ SmallVector<Substitution, 8 > RecursiveSubsList;
58
+
59
+ public:
60
+ ApplySiteCloningHelper (ApplySite AI, TypeSubstCloner &Cloner)
61
+ : Callee(Cloner.getOpValue(AI.getCallee())) {
62
+ SILType SubstCalleeSILType = Cloner.getOpType (AI.getSubstCalleeSILType ());
63
+
64
+ Args = Cloner.template getOpValueArray <8 >(AI.getArguments ());
65
+ SILBuilder &Builder = Cloner.getBuilder ();
66
+ Builder.setCurrentDebugScope (Cloner.super ::getOpScope (AI.getDebugScope ()));
67
+
68
+ // Remap substitutions.
69
+ NewSubsList = Cloner.getOpSubstitutions (AI.getSubstitutions ());
70
+ Subs = NewSubsList;
71
+
72
+ if (!Cloner.Inlining ) {
73
+ FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(AI.getCallee ());
74
+ if (FRI && FRI->getReferencedFunction () == AI.getFunction () &&
75
+ Subs == Cloner.ApplySubs ) {
76
+ // Handle recursions by replacing the apply to the callee with an
77
+ // apply to the newly specialized function, but only if substitutions
78
+ // are the same.
79
+ auto LoweredFnTy = Builder.getFunction ().getLoweredFunctionType ();
80
+ auto RecursiveSubstCalleeSILType = LoweredFnTy;
81
+ auto GenSig = LoweredFnTy->getGenericSignature ();
82
+ if (GenSig) {
83
+ // Compute substitutions for the specialized function. These
84
+ // substitutions may be different from the original ones, e.g.
85
+ // there can be less substitutions.
86
+ GenSig->getSubstitutions (AI.getFunction ()
87
+ ->getLoweredFunctionType ()
88
+ ->getGenericSignature ()
89
+ ->getSubstitutionMap (Subs),
90
+ RecursiveSubsList);
91
+ // Use the new set of substitutions to compute the new
92
+ // substituted callee type.
93
+ RecursiveSubstCalleeSILType = LoweredFnTy->substGenericArgs (
94
+ AI.getModule (), RecursiveSubsList);
95
+ }
96
+
97
+ // The specialized recursive function may have different calling
98
+ // convention for parameters. E.g. some of former indirect parameters
99
+ // may become direct. Some of indirect return values may become
100
+ // direct. Do not replace the callee in that case.
101
+ if (SubstCalleeSILType.getSwiftRValueType () ==
102
+ RecursiveSubstCalleeSILType) {
103
+ Subs = RecursiveSubsList;
104
+ Callee = Builder.createFunctionRef (
105
+ Cloner.getOpLocation (AI.getLoc ()), &Builder.getFunction ());
106
+ SubstCalleeSILType =
107
+ SILType::getPrimitiveObjectType (RecursiveSubstCalleeSILType);
108
+ }
109
+ }
110
+ }
111
+
112
+ assert (Subs.empty () ||
113
+ SubstCalleeSILType ==
114
+ Callee->getType ().substGenericArgs (AI.getModule (), Subs));
115
+ }
116
+
117
+ ArrayRef<SILValue> getArguments () const {
118
+ return Args;
119
+ }
120
+
121
+ SILValue getCallee () const {
122
+ return Callee;
123
+ }
124
+
125
+ SubstitutionList getSubstitutions () const {
126
+ return Subs;
127
+ }
128
+ };
129
+
50
130
public:
51
131
using SILClonerWithScopes<ImplClass>::asImpl;
52
132
using SILClonerWithScopes<ImplClass>::getBuilder;
@@ -105,79 +185,32 @@ class TypeSubstCloner : public SILClonerWithScopes<ImplClass> {
105
185
}
106
186
107
187
void visitApplyInst (ApplyInst *Inst) {
108
- auto Args = this ->template getOpValueArray <8 >(Inst->getArguments ());
109
-
110
- // Handle recursions by replacing the apply to the callee with an apply to
111
- // the newly specialized function, but only if substitutions are the same.
112
- SILBuilder &Builder = getBuilder ();
113
- Builder.setCurrentDebugScope (super::getOpScope (Inst->getDebugScope ()));
114
- SILValue CalleeVal = Inst->getCallee ();
115
- if (!Inlining) {
116
- auto *FRI = dyn_cast<FunctionRefInst>(CalleeVal);
117
- if (FRI && FRI->getReferencedFunction () == Inst->getFunction () &&
118
- Inst->getSubstitutions () == this ->ApplySubs ) {
119
- FRI = Builder.createFunctionRef (getOpLocation (Inst->getLoc ()),
120
- &Builder.getFunction ());
121
- ApplyInst *NAI =
122
- Builder.createApply (getOpLocation (Inst->getLoc ()), FRI, Args, Inst->isNonThrowing ());
123
- doPostProcess (Inst, NAI);
124
- return ;
125
- }
126
- }
127
-
128
- SmallVector<Substitution, 16 > TempSubstList;
129
- for (auto &Sub : Inst->getSubstitutions ()) {
130
- TempSubstList.push_back (asImpl ().getOpSubstitution (Sub));
131
- }
188
+ ApplySiteCloningHelper Helper (ApplySite::isa (Inst), *this );
189
+ ApplyInst *N =
190
+ getBuilder ().createApply (getOpLocation (Inst->getLoc ()),
191
+ Helper.getCallee (), Helper.getSubstitutions (),
192
+ Helper.getArguments (), Inst->isNonThrowing ());
193
+ doPostProcess (Inst, N);
194
+ }
132
195
133
- ApplyInst *N = Builder.createApply (
134
- getOpLocation (Inst->getLoc ()), getOpValue (CalleeVal),
135
- TempSubstList, Args, Inst->isNonThrowing ());
196
+ void visitTryApplyInst (TryApplyInst *Inst) {
197
+ ApplySiteCloningHelper Helper (ApplySite::isa (Inst), *this );
198
+ TryApplyInst *N = getBuilder ().createTryApply (
199
+ getOpLocation (Inst->getLoc ()), Helper.getCallee (),
200
+ Helper.getSubstitutions (), Helper.getArguments (),
201
+ getOpBasicBlock (Inst->getNormalBB ()),
202
+ getOpBasicBlock (Inst->getErrorBB ()));
136
203
doPostProcess (Inst, N);
137
204
}
138
205
139
206
void visitPartialApplyInst (PartialApplyInst *Inst) {
140
- auto Args = this ->template getOpValueArray <8 >(Inst->getArguments ());
141
-
142
- // Handle recursions by replacing the apply to the callee with an apply to
143
- // the newly specialized function.
144
- SILValue CalleeVal = Inst->getCallee ();
145
- SILBuilderWithPostProcess<TypeSubstCloner, 4 > Builder (this , Inst);
146
- Builder.setCurrentDebugScope (super::getOpScope (Inst->getDebugScope ()));
147
- SmallVector<Substitution, 16 > TempSubstList;
148
- if (!Inlining) {
149
- auto *FRI = dyn_cast<FunctionRefInst>(CalleeVal);
150
- if (FRI && FRI->getReferencedFunction () == Inst->getFunction ()) {
151
- auto LoweredFnTy = Builder.getFunction ().getLoweredFunctionType ();
152
- auto GenSig = LoweredFnTy->getGenericSignature ();
153
- if (GenSig) {
154
- GenSig->getSubstitutions (
155
- Inst->getFunction ()
156
- ->getLoweredFunctionType ()
157
- ->getGenericSignature ()
158
- ->getSubstitutionMap (Inst->getSubstitutions ()),
159
- TempSubstList);
160
- }
161
- for (auto &Sub : TempSubstList) {
162
- Sub = asImpl ().getOpSubstitution (Sub);
163
- }
164
- SubstitutionList Subs = TempSubstList;
165
- FRI = Builder.createFunctionRef (getOpLocation (Inst->getLoc ()),
166
- &Builder.getFunction ());
167
- Builder.createPartialApply (
168
- getOpLocation (Inst->getLoc ()), FRI, Subs, Args,
169
- Inst->getType ().getAs <SILFunctionType>()->getCalleeConvention ());
170
- return ;
171
- }
172
- }
173
-
174
- for (auto &Sub : Inst->getSubstitutions ()) {
175
- TempSubstList.push_back (asImpl ().getOpSubstitution (Sub));
176
- }
177
-
178
- Builder.createPartialApply (
179
- getOpLocation (Inst->getLoc ()), getOpValue (CalleeVal), TempSubstList,
180
- Args, Inst->getType ().getAs <SILFunctionType>()->getCalleeConvention ());
207
+ ApplySiteCloningHelper Helper (ApplySite::isa (Inst), *this );
208
+ auto ParamConvention =
209
+ Inst->getType ().getAs <SILFunctionType>()->getCalleeConvention ();
210
+ PartialApplyInst *N = getBuilder ().createPartialApply (
211
+ getOpLocation (Inst->getLoc ()), Helper.getCallee (),
212
+ Helper.getSubstitutions (), Helper.getArguments (), ParamConvention);
213
+ doPostProcess (Inst, N);
181
214
}
182
215
183
216
// / Attempt to simplify a conditional checked cast.
0 commit comments