28
28
#include " swift/SILOptimizer/Utils/InstructionDeleter.h"
29
29
#include " swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
30
30
#include " swift/SILOptimizer/Utils/SILInliner.h"
31
+ #include " swift/SILOptimizer/Utils/StackNesting.h"
31
32
#include " llvm/ADT/SmallVector.h"
32
33
33
34
using namespace swift ;
@@ -195,10 +196,12 @@ class MandatoryGenericSpecializer : public SILModuleTransform {
195
196
196
197
void run () override ;
197
198
198
- bool optimize (SILFunction *func, ClassHierarchyAnalysis *cha);
199
+ bool optimize (SILFunction *func, ClassHierarchyAnalysis *cha,
200
+ bool &invalidatedStackNesting);
199
201
200
202
bool optimizeInst (SILInstruction *inst, SILOptFunctionBuilder &funcBuilder,
201
- InstructionDeleter &deleter, ClassHierarchyAnalysis *cha);
203
+ InstructionDeleter &deleter, ClassHierarchyAnalysis *cha,
204
+ bool &invalidatedStackNesting);
202
205
};
203
206
204
207
@@ -220,7 +223,7 @@ void MandatoryGenericSpecializer::run() {
220
223
visited.insert (&function);
221
224
}
222
225
}
223
-
226
+
224
227
while (!workList.empty ()) {
225
228
SILFunction *func = workList.pop_back_val ();
226
229
module ->linkFunction (func, SILModule::LinkingMode::LinkAll);
@@ -229,20 +232,26 @@ void MandatoryGenericSpecializer::run() {
229
232
230
233
// Perform generic specialization and other related optimization.
231
234
235
+ bool invalidatedStackNesting = false ;
236
+
232
237
// To avoid phase ordering problems of the involved optimizations, iterate
233
238
// until we reach a fixed point.
234
239
// This should always happen, but to be on the safe side, limit the number
235
240
// of iterations to 10 (which is more than enough - usually the loop runs
236
241
// 1 to 3 times).
237
242
for (int i = 0 ; i < 10 ; i++) {
238
- bool changed = optimize (func, cha);
243
+ bool changed = optimize (func, cha, invalidatedStackNesting );
239
244
if (changed) {
240
245
invalidateAnalysis (func, SILAnalysis::InvalidationKind::FunctionBody);
241
246
} else {
242
247
break ;
243
248
}
244
249
}
245
250
251
+ if (invalidatedStackNesting) {
252
+ StackNesting::fixNesting (func);
253
+ }
254
+
246
255
// Continue specializing called functions.
247
256
for (SILBasicBlock &block : *func) {
248
257
for (SILInstruction &inst : block) {
@@ -260,7 +269,8 @@ void MandatoryGenericSpecializer::run() {
260
269
// / Specialize generic calls in \p func and do some other related optimizations:
261
270
// / devirtualization and constant-folding of the Builtin.canBeClass.
262
271
bool MandatoryGenericSpecializer::optimize (SILFunction *func,
263
- ClassHierarchyAnalysis *cha) {
272
+ ClassHierarchyAnalysis *cha,
273
+ bool &invalidatedStackNesting) {
264
274
bool changed = false ;
265
275
SILOptFunctionBuilder funcBuilder (*this );
266
276
InstructionDeleter deleter;
@@ -282,7 +292,7 @@ bool MandatoryGenericSpecializer::optimize(SILFunction *func,
282
292
continue ;
283
293
284
294
for (SILInstruction *inst : deleter.updatingReverseRange (&block)) {
285
- changed |= optimizeInst (inst, funcBuilder, deleter, cha);
295
+ changed |= optimizeInst (inst, funcBuilder, deleter, cha, invalidatedStackNesting );
286
296
}
287
297
}
288
298
deleter.cleanupDeadInstructions ();
@@ -295,7 +305,8 @@ bool MandatoryGenericSpecializer::optimize(SILFunction *func,
295
305
296
306
bool MandatoryGenericSpecializer::
297
307
optimizeInst (SILInstruction *inst, SILOptFunctionBuilder &funcBuilder,
298
- InstructionDeleter &deleter, ClassHierarchyAnalysis *cha) {
308
+ InstructionDeleter &deleter, ClassHierarchyAnalysis *cha,
309
+ bool &invalidatedStackNesting) {
299
310
if (auto as = ApplySite::isa (inst)) {
300
311
301
312
bool changed = false ;
@@ -307,10 +318,22 @@ optimizeInst(SILInstruction *inst, SILOptFunctionBuilder &funcBuilder,
307
318
as = newAS;
308
319
}
309
320
310
- auto fas = FullApplySite::isa (as.getInstruction ());
311
- if (!fas)
321
+ if (auto *pai = dyn_cast<PartialApplyInst>(as)) {
322
+ SILBuilderContext builderCtxt (funcBuilder.getModule ());
323
+ if (tryOptimizeApplyOfPartialApply (pai, builderCtxt, deleter.getCallbacks ())) {
324
+ // Try to delete the partial_apply.
325
+ // We don't need to copy all arguments again (to extend their lifetimes),
326
+ // because it was already done in tryOptimizeApplyOfPartialApply.
327
+ tryDeleteDeadClosure (pai, deleter.getCallbacks (), /* needKeepArgsAlive=*/ false );
328
+ invalidatedStackNesting = true ;
329
+ return true ;
330
+ }
312
331
return changed;
313
-
332
+ }
333
+
334
+ auto fas = FullApplySite::isa (as.getInstruction ());
335
+ assert (fas);
336
+
314
337
SILFunction *callee = fas.getReferencedFunctionOrNull ();
315
338
if (!callee)
316
339
return changed;
0 commit comments