@@ -444,6 +444,12 @@ static SILValue skipConvert(SILValue v) {
444
444
return pa;
445
445
}
446
446
447
+ static SILAnalysis::InvalidationKind
448
+ analysisInvalidationKind (const bool &modifiedCFG) {
449
+ return modifiedCFG ? SILAnalysis::InvalidationKind::FunctionBody
450
+ : SILAnalysis::InvalidationKind::CallsAndInstructions;
451
+ }
452
+
447
453
// / Rewrite a partial_apply convert_escape_to_noescape sequence with a single
448
454
// / apply/try_apply user to a partial_apply [stack] terminated with a
449
455
// / dealloc_stack placed after the apply.
@@ -468,9 +474,10 @@ static SILValue skipConvert(SILValue v) {
468
474
// / caller needs to use the StackNesting utility to update the dealloc_stack
469
475
// / nesting.
470
476
static SILValue tryRewriteToPartialApplyStack (
471
- ConvertEscapeToNoEscapeInst *cvt,
472
- SILInstruction *closureUser, InstructionDeleter &deleter,
473
- llvm::DenseMap<SILInstruction *, SILInstruction *> &memoized) {
477
+ ConvertEscapeToNoEscapeInst *cvt, SILInstruction *closureUser,
478
+ DominanceAnalysis *dominanceAnalysis, InstructionDeleter &deleter,
479
+ llvm::DenseMap<SILInstruction *, SILInstruction *> &memoized,
480
+ const bool &modifiedCFG) {
474
481
475
482
auto *origPA = dyn_cast<PartialApplyInst>(skipConvert (cvt->getOperand ()));
476
483
if (!origPA)
@@ -567,16 +574,24 @@ static SILValue tryRewriteToPartialApplyStack(
567
574
auto loc = RegularLocation (builder.getInsertionPointLoc ());
568
575
builder.createDeallocStack (loc, newPA);
569
576
insertDestroyOfCapturedArguments (newPA, builder);
570
- // dealloc_stack of the in_guaranteed capture is inserted
571
- insertDeallocOfCapturedArguments (newPA, builder);
572
577
});
578
+ // The CFG may have been modified during this run. If it was, the dominance
579
+ // analysis would no longer be valid. Invalidate it now if necessary,
580
+ // according to the kinds of changes that may have been made. Note that if
581
+ // the CFG hasn't been modified, this is a noop thanks to
582
+ // DominanceAnalysis::shouldInvalidate's definition.
583
+ dominanceAnalysis->invalidate (closureUser->getFunction (),
584
+ analysisInvalidationKind (modifiedCFG));
585
+ // Insert dealloc_stacks of any in_guaranteed captures.
586
+ insertDeallocOfCapturedArguments (
587
+ newPA, dominanceAnalysis->get (closureUser->getFunction ()));
573
588
return closure;
574
589
}
575
590
576
591
static bool tryExtendLifetimeToLastUse (
577
- ConvertEscapeToNoEscapeInst *cvt,
592
+ ConvertEscapeToNoEscapeInst *cvt, DominanceAnalysis *dominanceAnalysis,
578
593
llvm::DenseMap<SILInstruction *, SILInstruction *> &memoized,
579
- InstructionDeleter &deleter) {
594
+ InstructionDeleter &deleter, const bool &modifiedCFG ) {
580
595
// If there is a single user that is an apply this is simple: extend the
581
596
// lifetime of the operand until after the apply.
582
597
auto *singleUser = lookThroughRebastractionUsers (cvt, memoized);
@@ -597,8 +612,9 @@ static bool tryExtendLifetimeToLastUse(
597
612
return false ;
598
613
}
599
614
600
- if (SILValue closure = tryRewriteToPartialApplyStack (cvt, singleUser,
601
- deleter, memoized)) {
615
+ if (SILValue closure = tryRewriteToPartialApplyStack (
616
+ cvt, singleUser, dominanceAnalysis, deleter, memoized,
617
+ /* const*/ modifiedCFG)) {
602
618
if (auto *cfi = dyn_cast<ConvertFunctionInst>(closure))
603
619
closure = cfi->getOperand ();
604
620
if (endAsyncLet && isa<MarkDependenceInst>(closure)) {
@@ -993,8 +1009,9 @@ static bool fixupCopyBlockWithoutEscaping(CopyBlockWithoutEscapingInst *cb,
993
1009
return true ;
994
1010
}
995
1011
996
- static bool fixupClosureLifetimes (SILFunction &fn, bool &checkStackNesting,
997
- bool &modifiedCFG) {
1012
+ static bool fixupClosureLifetimes (SILFunction &fn,
1013
+ DominanceAnalysis *dominanceAnalysis,
1014
+ bool &checkStackNesting, bool &modifiedCFG) {
998
1015
bool changed = false ;
999
1016
1000
1017
// tryExtendLifetimeToLastUse uses a cache of recursive instruction use
@@ -1027,7 +1044,9 @@ static bool fixupClosureLifetimes(SILFunction &fn, bool &checkStackNesting,
1027
1044
}
1028
1045
}
1029
1046
1030
- if (tryExtendLifetimeToLastUse (cvt, memoizedQueries, updater.getDeleter ())) {
1047
+ if (tryExtendLifetimeToLastUse (cvt, dominanceAnalysis, memoizedQueries,
1048
+ updater.getDeleter (),
1049
+ /* const*/ modifiedCFG)) {
1031
1050
changed = true ;
1032
1051
checkStackNesting = true ;
1033
1052
continue ;
@@ -1064,15 +1083,15 @@ class ClosureLifetimeFixup : public SILFunctionTransform {
1064
1083
bool checkStackNesting = false ;
1065
1084
bool modifiedCFG = false ;
1066
1085
1067
- if (fixupClosureLifetimes (*getFunction (), checkStackNesting, modifiedCFG)) {
1086
+ auto *dominanceAnalysis = PM->getAnalysis <DominanceAnalysis>();
1087
+
1088
+ if (fixupClosureLifetimes (*getFunction (), dominanceAnalysis,
1089
+ checkStackNesting, modifiedCFG)) {
1068
1090
if (checkStackNesting){
1069
1091
modifiedCFG |=
1070
1092
StackNesting::fixNesting (getFunction ()) == StackNesting::Changes::CFG;
1071
1093
}
1072
- if (modifiedCFG)
1073
- invalidateAnalysis (SILAnalysis::InvalidationKind::FunctionBody);
1074
- else
1075
- invalidateAnalysis (SILAnalysis::InvalidationKind::CallsAndInstructions);
1094
+ invalidateAnalysis (analysisInvalidationKind (modifiedCFG));
1076
1095
}
1077
1096
LLVM_DEBUG (getFunction ()->verify ());
1078
1097
0 commit comments