Skip to content

Commit

Permalink
[arc] Sink the re-running of ARC opts with frozen epilogue releases f…
Browse files Browse the repository at this point in the history
…urther 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.
  • Loading branch information
gottesmm committed Dec 9, 2015
1 parent af23d09 commit 6eb3672
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 22 deletions.
7 changes: 7 additions & 0 deletions include/swift/SILAnalysis/ARCAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ class ConsumedArgToEpilogueReleaseMatcher {
return I->second;
}

SILInstruction *releaseForArgument(SILValue V) const {
auto *Arg = dyn_cast<SILArgument>(V);
if (!Arg)
return nullptr;
return releaseForArgument(Arg);
}

/// Recompute the mapping from argument to consumed arg.
void recompute();

Expand Down
2 changes: 2 additions & 0 deletions lib/SILAnalysis/ARCAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ ConsumedArgToEpilogueReleaseMatcher::ConsumedArgToEpilogueReleaseMatcher(
}

void ConsumedArgToEpilogueReleaseMatcher::recompute() {
ArgInstMap.clear();

// Find the return BB of F. If we fail, then bail.
SILFunction::iterator BB;
switch (Kind) {
Expand Down
12 changes: 5 additions & 7 deletions lib/SILPasses/ARC/ARCSequenceOpts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ processFunctionWithoutLoopSupport(SILFunction &F, bool FreezePostDomReleases,
//===----------------------------------------------------------------------===//

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

LoopARCPairingContext Context(F, AA, LRFI, LI, RCFI, PTFI);
return Context.process(FreezePostDomReleases);
return Context.process();
}

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

if (processFunctionWithLoopSupport(*F, false, AA, POTA, LRFI, LI, RCFI,
PTFI)) {
processFunctionWithLoopSupport(*F, true, AA, POTA, LRFI, LI, RCFI, PTFI);
if (processFunctionWithLoopSupport(*F, AA, POTA, LRFI, LI, RCFI, PTFI)) {
invalidateAnalysis(SILAnalysis::InvalidationKind::CallsAndInstructions);
}
}
Expand Down
33 changes: 26 additions & 7 deletions lib/SILPasses/ARC/GlobalARCPairingAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,26 +405,45 @@ bool ARCPairingContext::performMatching(CodeMotionOrDeleteCallback &Callback) {
//===----------------------------------------------------------------------===//

void LoopARCPairingContext::runOnLoop(SILLoop *L) {
processRegion(LRFI->getRegion(L));
auto *Region = LRFI->getRegion(L);
if (processRegion(Region, false, false)) {
// We do not recompute for now since we only look at the top function level
// for post dominating releases.
processRegion(Region, true, false);
}

// Now that we have finished processing the loop, summarize the loop.
Evaluator.summarizeLoop(Region);
}

void LoopARCPairingContext::runOnFunction(SILFunction *F) {
processRegion(LRFI->getTopLevelRegion());
if (processRegion(LRFI->getTopLevelRegion(), false, false)) {
// We recompute the final post dom release since we may have moved the final
// post dominated releases.
processRegion(LRFI->getTopLevelRegion(), true, true);
}
}

void LoopARCPairingContext::processRegion(const LoopRegion *Region) {
bool NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases);
bool LoopARCPairingContext::processRegion(const LoopRegion *Region,
bool FreezePostDomReleases,
bool RecomputePostDomReleases) {
bool MadeChange = false;
bool NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases,
RecomputePostDomReleases);
bool MatchedPair = Context.performMatching(Callback);
MadeChange |= MatchedPair;
Evaluator.clearLoopState(Region);
Context.DecToIncStateMap.clear();
Context.IncToDecStateMap.clear();

while (NestingDetected && MatchedPair) {
Evaluator.clearLoopState(Region);
NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases);
NestingDetected = Evaluator.runOnLoop(Region, FreezePostDomReleases, false);
MatchedPair = Context.performMatching(Callback);
MadeChange |= MatchedPair;
Evaluator.clearLoopState(Region);
Context.DecToIncStateMap.clear();
Context.IncToDecStateMap.clear();
}

Evaluator.summarizeLoop(Region);
return MadeChange;
}
12 changes: 7 additions & 5 deletions lib/SILPasses/ARC/GlobalARCPairingAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ struct LoopARCPairingContext : SILLoopVisitor {
LoopRegionFunctionInfo *LRFI;
SILLoopInfo *SLI;
CodeMotionOrDeleteCallback Callback;
bool FreezePostDomReleases = false;

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

bool process(bool FreezePDReleases) {
FreezePostDomReleases = FreezePDReleases;
bool process() {
run();
return Callback.madeChange();
if (!Callback.madeChange())
return false;
run();
return true;
}

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

void processRegion(const LoopRegion *R);
bool processRegion(const LoopRegion *R, bool FreezePostDomReleases,
bool RecomputePostDomReleases);
};

} // end swift namespace
Expand Down
5 changes: 4 additions & 1 deletion lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,10 @@ LoopARCSequenceDataflowEvaluator::~LoopARCSequenceDataflowEvaluator() {
}

bool LoopARCSequenceDataflowEvaluator::runOnLoop(
const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases) {
const LoopRegion *R, bool FreezeOwnedArgEpilogueReleases,
bool RecomputePostDomReleases) {
if (RecomputePostDomReleases)
ConsumedArgToReleaseMap.recompute();
bool NestingDetected = processLoopBottomUp(R, FreezeOwnedArgEpilogueReleases);
NestingDetected |= processLoopTopDown(R);
return NestingDetected;
Expand Down
3 changes: 2 additions & 1 deletion lib/SILPasses/ARC/GlobalLoopARCSequenceDataflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ class LoopARCSequenceDataflowEvaluator {

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

/// Summarize the contents of the loop so that loops further up the loop tree
/// can reason about the loop.
Expand Down
6 changes: 5 additions & 1 deletion lib/SILPasses/ARC/RCStateTransitionVisitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ BottomUpDataflowRCStateVisitor<ARCState>::visitStrongDecrement(ValueBase *V) {
// If we are running with 'frozen' owned arg releases, check if we have a
// frozen use in the side table. If so, this release must be known safe.
if (FreezeOwnedArgEpilogueReleases) {
State.updateKnownSafe(EpilogueReleaseMatcher.argumentHasRelease(Op));
if (auto *OwnedRelease = EpilogueReleaseMatcher.releaseForArgument(Op)) {
if (I != OwnedRelease) {
State.updateKnownSafe(true);
}
}
}

DEBUG(llvm::dbgs() << " REF COUNT DECREMENT! Known Safe: "
Expand Down
1 change: 1 addition & 0 deletions test/SILPasses/globalarcopts.sil
Original file line number Diff line number Diff line change
Expand Up @@ -1934,3 +1934,4 @@ bb2(%3 : $ErrorType):
strong_release %0 : $Builtin.NativeObject
throw %3 : $ErrorType
}

0 comments on commit 6eb3672

Please sign in to comment.