Skip to content

Commit 6eb3672

Browse files
committed
[arc] Sink the re-running of ARC opts with frozen epilogue releases further into ARCSequenceOpts so that the loop visitor does not need to have any special handling for ARCSequenceOpts.
Previously, we would outside of ARCSequenceOpts, run ARCSequenceOpts twice with a flag set in one case and a flag unset in the other case. Now ARCSequenceOpts internally performs these two runs of the optimization.
1 parent af23d09 commit 6eb3672

File tree

9 files changed

+59
-22
lines changed

9 files changed

+59
-22
lines changed

include/swift/SILAnalysis/ARCAnalysis.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ class ConsumedArgToEpilogueReleaseMatcher {
148148
return I->second;
149149
}
150150

151+
SILInstruction *releaseForArgument(SILValue V) const {
152+
auto *Arg = dyn_cast<SILArgument>(V);
153+
if (!Arg)
154+
return nullptr;
155+
return releaseForArgument(Arg);
156+
}
157+
151158
/// Recompute the mapping from argument to consumed arg.
152159
void recompute();
153160

lib/SILAnalysis/ARCAnalysis.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,8 @@ ConsumedArgToEpilogueReleaseMatcher::ConsumedArgToEpilogueReleaseMatcher(
515515
}
516516

517517
void ConsumedArgToEpilogueReleaseMatcher::recompute() {
518+
ArgInstMap.clear();
519+
518520
// Find the return BB of F. If we fail, then bail.
519521
SILFunction::iterator BB;
520522
switch (Kind) {

lib/SILPasses/ARC/ARCSequenceOpts.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,9 @@ processFunctionWithoutLoopSupport(SILFunction &F, bool FreezePostDomReleases,
192192
//===----------------------------------------------------------------------===//
193193

194194
static bool processFunctionWithLoopSupport(
195-
SILFunction &F, bool FreezePostDomReleases, AliasAnalysis *AA,
196-
PostOrderAnalysis *POTA, LoopRegionFunctionInfo *LRFI, SILLoopInfo *LI,
197-
RCIdentityFunctionInfo *RCFI, ProgramTerminationFunctionInfo *PTFI) {
195+
SILFunction &F, AliasAnalysis *AA, PostOrderAnalysis *POTA,
196+
LoopRegionFunctionInfo *LRFI, SILLoopInfo *LI, RCIdentityFunctionInfo *RCFI,
197+
ProgramTerminationFunctionInfo *PTFI) {
198198
// GlobalARCOpts seems to be taking up a lot of compile time when running on
199199
// globalinit_func. Since that is not *that* interesting from an ARC
200200
// perspective (i.e. no ref count operations in a loop), disable it on such
@@ -205,7 +205,7 @@ static bool processFunctionWithLoopSupport(
205205
DEBUG(llvm::dbgs() << "***** Processing " << F.getName() << " *****\n");
206206

207207
LoopARCPairingContext Context(F, AA, LRFI, LI, RCFI, PTFI);
208-
return Context.process(FreezePostDomReleases);
208+
return Context.process();
209209
}
210210

211211
//===----------------------------------------------------------------------===//
@@ -256,9 +256,7 @@ class ARCSequenceOpts : public SILFunctionTransform {
256256
auto *LRFI = getAnalysis<LoopRegionAnalysis>()->get(F);
257257
auto *PTFI = getAnalysis<ProgramTerminationAnalysis>()->get(F);
258258

259-
if (processFunctionWithLoopSupport(*F, false, AA, POTA, LRFI, LI, RCFI,
260-
PTFI)) {
261-
processFunctionWithLoopSupport(*F, true, AA, POTA, LRFI, LI, RCFI, PTFI);
259+
if (processFunctionWithLoopSupport(*F, AA, POTA, LRFI, LI, RCFI, PTFI)) {
262260
invalidateAnalysis(SILAnalysis::InvalidationKind::CallsAndInstructions);
263261
}
264262
}

lib/SILPasses/ARC/GlobalARCPairingAnalysis.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -405,26 +405,45 @@ bool ARCPairingContext::performMatching(CodeMotionOrDeleteCallback &Callback) {
405405
//===----------------------------------------------------------------------===//
406406

407407
void LoopARCPairingContext::runOnLoop(SILLoop *L) {
408-
processRegion(LRFI->getRegion(L));
408+
auto *Region = LRFI->getRegion(L);
409+
if (processRegion(Region, false, false)) {
410+
// We do not recompute for now since we only look at the top function level
411+
// for post dominating releases.
412+
processRegion(Region, true, false);
413+
}
414+
415+
// Now that we have finished processing the loop, summarize the loop.
416+
Evaluator.summarizeLoop(Region);
409417
}
410418

411419
void LoopARCPairingContext::runOnFunction(SILFunction *F) {
412-
processRegion(LRFI->getTopLevelRegion());
420+
if (processRegion(LRFI->getTopLevelRegion(), false, false)) {
421+
// We recompute the final post dom release since we may have moved the final
422+
// post dominated releases.
423+
processRegion(LRFI->getTopLevelRegion(), true, true);
424+
}
413425
}
414426

415-
void LoopARCPairingContext::processRegion(const LoopRegion *Region) {
416-
bool NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases);
427+
bool LoopARCPairingContext::processRegion(const LoopRegion *Region,
428+
bool FreezePostDomReleases,
429+
bool RecomputePostDomReleases) {
430+
bool MadeChange = false;
431+
bool NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases,
432+
RecomputePostDomReleases);
417433
bool MatchedPair = Context.performMatching(Callback);
434+
MadeChange |= MatchedPair;
435+
Evaluator.clearLoopState(Region);
418436
Context.DecToIncStateMap.clear();
419437
Context.IncToDecStateMap.clear();
420438

421439
while (NestingDetected && MatchedPair) {
422-
Evaluator.clearLoopState(Region);
423-
NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases);
440+
NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases, false);
424441
MatchedPair = Context.performMatching(Callback);
442+
MadeChange |= MatchedPair;
443+
Evaluator.clearLoopState(Region);
425444
Context.DecToIncStateMap.clear();
426445
Context.IncToDecStateMap.clear();
427446
}
428447

429-
Evaluator.summarizeLoop(Region);
448+
return MadeChange;
430449
}

lib/SILPasses/ARC/GlobalARCPairingAnalysis.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@ struct LoopARCPairingContext : SILLoopVisitor {
143143
LoopRegionFunctionInfo *LRFI;
144144
SILLoopInfo *SLI;
145145
CodeMotionOrDeleteCallback Callback;
146-
bool FreezePostDomReleases = false;
147146

148147
LoopARCPairingContext(SILFunction &F, AliasAnalysis *AA,
149148
LoopRegionFunctionInfo *LRFI, SILLoopInfo *SLI,
@@ -154,16 +153,19 @@ struct LoopARCPairingContext : SILLoopVisitor {
154153
Context.IncToDecStateMap),
155154
LRFI(LRFI), SLI(SLI), Callback() {}
156155

157-
bool process(bool FreezePDReleases) {
158-
FreezePostDomReleases = FreezePDReleases;
156+
bool process() {
159157
run();
160-
return Callback.madeChange();
158+
if (!Callback.madeChange())
159+
return false;
160+
run();
161+
return true;
161162
}
162163

163164
void runOnLoop(SILLoop *L) override;
164165
void runOnFunction(SILFunction *F) override;
165166

166-
void processRegion(const LoopRegion *R);
167+
bool processRegion(const LoopRegion *R, bool FreezePostDomReleases,
168+
bool RecomputePostDomReleases);
167169
};
168170

169171
} // end swift namespace

lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,10 @@ LoopARCSequenceDataflowEvaluator::~LoopARCSequenceDataflowEvaluator() {
271271
}
272272

273273
bool LoopARCSequenceDataflowEvaluator::runOnLoop(
274-
const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases) {
274+
const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases,
275+
bool RecomputePostDomReleases) {
276+
if (RecomputePostDomReleases)
277+
ConsumedArgToReleaseMap.recompute();
275278
bool NestingDetected = processLoopBottomUp(R, FreezeOwnedArgEpilogueReleases);
276279
NestingDetected |= processLoopTopDown(R);
277280
return NestingDetected;

lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ class LoopARCSequenceDataflowEvaluator {
8787

8888
/// Perform the sequence dataflow, bottom up and top down on the loop region
8989
/// \p R.
90-
bool runOnLoop(const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases);
90+
bool runOnLoop(const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases,
91+
bool RecomputePostDomReleases);
9192

9293
/// Summarize the contents of the loop so that loops further up the loop tree
9394
/// can reason about the loop.

lib/SILPasses/ARC/RCStateTransitionVisitors.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,11 @@ BottomUpDataflowRCStateVisitor<ARCState>::visitStrongDecrement(ValueBase *V) {
7171
// If we are running with 'frozen' owned arg releases, check if we have a
7272
// frozen use in the side table. If so, this release must be known safe.
7373
if (FreezeOwnedArgEpilogueReleases) {
74-
State.updateKnownSafe(EpilogueReleaseMatcher.argumentHasRelease(Op));
74+
if (auto *OwnedRelease = EpilogueReleaseMatcher.releaseForArgument(Op)) {
75+
if (I != OwnedRelease) {
76+
State.updateKnownSafe(true);
77+
}
78+
}
7579
}
7680

7781
DEBUG(llvm::dbgs() << " REF COUNT DECREMENT! Known Safe: "

test/SILPasses/globalarcopts.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,3 +1934,4 @@ bb2(%3 : $ErrorType):
19341934
strong_release %0 : $Builtin.NativeObject
19351935
throw %3 : $ErrorType
19361936
}
1937+

0 commit comments

Comments
 (0)