Files
swift-mirror/lib/SILOptimizer/ARC/ARCLoopOpts.cpp
Michael Gottesman e152746277 [arc] Split GlobalARCPairingAnalysis into the matching set builder part and the
top level driver . Move the top level driver of the pairing analysis into
ARCSequenceOpts and have ARCSequenceOpts use ARCMatchingSetBuilder directly.

This patch is the first in a series of patches that improve ARC compile
time performance by ensuring that ARC only visits the full CFG at most
one time.

Previously when ARC was split into an analysis and a pass, the split in
the codebase occurred at the boundary in between ARCSequenceOpts and
ARCPairingAnalysis. I used a callback to allow ARCSequenceOpts to inject
code into ARCPairingAnalysis.

Now that the analysis has been moved together with the pass this
unnecessarily complicates the code. More importantly though it creates
obstacles towards reducing compile time by visiting the CFG only once.

Specifically, we need to visit the full cfg once to gather interesting
instructions. Then when performing the actual dataflow analysis, we only
visit the interesting instructions. This causes an interesting problem
since retains/releases can have dependencies on each other implying that
I need to be able to update where various "interesting instructions" are
located after ARC moves it. The "interesting instruction" information is
stored at the pairing analysis level, but the moving/removal of
instructions is injected in via the callback.

By moving the top level driver part of ARCPairingAnalysis into
ARCSequenceOpts, we simplify the code by eliminating the dependency
injection callback and also make it easier to manage the cached CFG
state in the face of the ARC optimizer moving/removing retains/releases.
2016-02-14 14:56:13 -08:00

94 lines
3.2 KiB
C++

//===--- ARCLoopOpts.cpp --------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// This is a pass that runs multiple interrelated loop passes on a function. It
/// also provides caching of certain analysis information that is used by all of
/// the passes.
///
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "arc-sequence-opts"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "ARCSequenceOpts.h"
#include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
#include "swift/SILOptimizer/Analysis/LoopAnalysis.h"
#include "swift/SILOptimizer/Analysis/LoopRegionAnalysis.h"
#include "swift/SILOptimizer/Analysis/ProgramTerminationAnalysis.h"
#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
using namespace swift;
//===----------------------------------------------------------------------===//
// Top Level Driver
//===----------------------------------------------------------------------===//
namespace {
class ARCLoopOpts : public SILFunctionTransform {
void run() override {
auto *F = getFunction();
// If ARC optimizations are disabled, don't optimize anything and bail.
if (!getOptions().EnableARCOptimizations)
return;
// Skip global init functions.
if (F->getName().startswith("globalinit_"))
return;
auto *LA = getAnalysis<SILLoopAnalysis>();
auto *LI = LA->get(F);
auto *DA = getAnalysis<DominanceAnalysis>();
auto *DI = DA->get(F);
// Canonicalize the loops, invalidating if we need to.
if (canonicalizeAllLoops(DI, LI)) {
// We preserve loop info and the dominator tree.
DA->lockInvalidation();
LA->lockInvalidation();
PM->invalidateAnalysis(F, SILAnalysis::InvalidationKind::FunctionBody);
DA->unlockInvalidation();
LA->unlockInvalidation();
}
// Get all of the analyses that we need.
auto *AA = getAnalysis<AliasAnalysis>();
auto *RCFI = getAnalysis<RCIdentityAnalysis>()->get(F);
auto *LRFI = getAnalysis<LoopRegionAnalysis>()->get(F);
ProgramTerminationFunctionInfo PTFI(F);
// Create all of our visitors, register them with the visitor group, and
// run.
LoopARCPairingContext LoopARCContext(*F, AA, LRFI, LI, RCFI, &PTFI);
SILLoopVisitorGroup VisitorGroup(F, LI);
VisitorGroup.addVisitor(&LoopARCContext);
VisitorGroup.run();
if (LoopARCContext.madeChange()) {
invalidateAnalysis(SILAnalysis::InvalidationKind::CallsAndInstructions);
}
}
StringRef getName() override { return "ARC Loop Opts"; }
};
} // end anonymous namespace
SILTransform *swift::createARCLoopOpts() {
return new ARCLoopOpts();
}