2828#include " swift/SILOptimizer/Utils/InstructionDeleter.h"
2929#include " swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
3030#include " swift/SILOptimizer/Utils/SILInliner.h"
31+ #include " swift/SILOptimizer/Utils/StackNesting.h"
3132#include " llvm/ADT/SmallVector.h"
3233
3334using namespace swift ;
@@ -195,10 +196,12 @@ class MandatoryGenericSpecializer : public SILModuleTransform {
195196
196197 void run () override ;
197198
198- bool optimize (SILFunction *func, ClassHierarchyAnalysis *cha);
199+ bool optimize (SILFunction *func, ClassHierarchyAnalysis *cha,
200+ bool &invalidatedStackNesting);
199201
200202 bool optimizeInst (SILInstruction *inst, SILOptFunctionBuilder &funcBuilder,
201- InstructionDeleter &deleter, ClassHierarchyAnalysis *cha);
203+ InstructionDeleter &deleter, ClassHierarchyAnalysis *cha,
204+ bool &invalidatedStackNesting);
202205};
203206
204207
@@ -220,7 +223,7 @@ void MandatoryGenericSpecializer::run() {
220223 visited.insert (&function);
221224 }
222225 }
223-
226+
224227 while (!workList.empty ()) {
225228 SILFunction *func = workList.pop_back_val ();
226229 module ->linkFunction (func, SILModule::LinkingMode::LinkAll);
@@ -229,20 +232,26 @@ void MandatoryGenericSpecializer::run() {
229232
230233 // Perform generic specialization and other related optimization.
231234
235+ bool invalidatedStackNesting = false ;
236+
232237 // To avoid phase ordering problems of the involved optimizations, iterate
233238 // until we reach a fixed point.
234239 // This should always happen, but to be on the safe side, limit the number
235240 // of iterations to 10 (which is more than enough - usually the loop runs
236241 // 1 to 3 times).
237242 for (int i = 0 ; i < 10 ; i++) {
238- bool changed = optimize (func, cha);
243+ bool changed = optimize (func, cha, invalidatedStackNesting );
239244 if (changed) {
240245 invalidateAnalysis (func, SILAnalysis::InvalidationKind::FunctionBody);
241246 } else {
242247 break ;
243248 }
244249 }
245250
251+ if (invalidatedStackNesting) {
252+ StackNesting::fixNesting (func);
253+ }
254+
246255 // Continue specializing called functions.
247256 for (SILBasicBlock &block : *func) {
248257 for (SILInstruction &inst : block) {
@@ -260,7 +269,8 @@ void MandatoryGenericSpecializer::run() {
260269// / Specialize generic calls in \p func and do some other related optimizations:
261270// / devirtualization and constant-folding of the Builtin.canBeClass.
262271bool MandatoryGenericSpecializer::optimize (SILFunction *func,
263- ClassHierarchyAnalysis *cha) {
272+ ClassHierarchyAnalysis *cha,
273+ bool &invalidatedStackNesting) {
264274 bool changed = false ;
265275 SILOptFunctionBuilder funcBuilder (*this );
266276 InstructionDeleter deleter;
@@ -282,7 +292,7 @@ bool MandatoryGenericSpecializer::optimize(SILFunction *func,
282292 continue ;
283293
284294 for (SILInstruction *inst : deleter.updatingReverseRange (&block)) {
285- changed |= optimizeInst (inst, funcBuilder, deleter, cha);
295+ changed |= optimizeInst (inst, funcBuilder, deleter, cha, invalidatedStackNesting );
286296 }
287297 }
288298 deleter.cleanupDeadInstructions ();
@@ -295,7 +305,8 @@ bool MandatoryGenericSpecializer::optimize(SILFunction *func,
295305
296306bool MandatoryGenericSpecializer::
297307optimizeInst (SILInstruction *inst, SILOptFunctionBuilder &funcBuilder,
298- InstructionDeleter &deleter, ClassHierarchyAnalysis *cha) {
308+ InstructionDeleter &deleter, ClassHierarchyAnalysis *cha,
309+ bool &invalidatedStackNesting) {
299310 if (auto as = ApplySite::isa (inst)) {
300311
301312 bool changed = false ;
@@ -307,10 +318,22 @@ optimizeInst(SILInstruction *inst, SILOptFunctionBuilder &funcBuilder,
307318 as = newAS;
308319 }
309320
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+ }
312331 return changed;
313-
332+ }
333+
334+ auto fas = FullApplySite::isa (as.getInstruction ());
335+ assert (fas);
336+
314337 SILFunction *callee = fas.getReferencedFunctionOrNull ();
315338 if (!callee)
316339 return changed;
0 commit comments