mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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.
94 lines
3.2 KiB
C++
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();
|
|
}
|