Files
swift-mirror/lib/SILOptimizer/ARC/GlobalARCSequenceDataflow.h
Michael Gottesman f718111a4f [arc] Integrate ImmutablePointerSet{,Factory} into ARC Sequence Opts.
This speeds and reduces memory consumption of test cases with large
CFGs. The specific test case that spawned this fix was a large function
with many dictionary assignments:

public func func_0(dictIn : [String : MyClass]) -> [String : MyClass] {
  var dictOut : [String : MyClass] = [:]
  dictOut["key5000"] = dictIn["key500"]
  dictOut["key5010"] = dictIn["key501"]
  dictOut["key5020"] = dictIn["key502"]
  dictOut["key5030"] = dictIn["key503"]
  dictOut["key5040"] = dictIn["key504"]
  ...
}

This continued for 10k - 20k values.

This commit reduces the compile time by 2.5x and reduces the amount of
memory allocated by ARC by 2.6x (the memory allocation number includes
memory that is subsequently freed).

rdar://24350646
2016-02-14 15:26:59 -08:00

114 lines
3.8 KiB
C++

//===- GlobalARCSequenceDataflow.h - ARC Sequence Flow Analysis -*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_GLOBALARCSEQUENCEDATAFLOW_H
#define SWIFT_SILOPTIMIZER_PASSMANAGER_ARC_GLOBALARCSEQUENCEDATAFLOW_H
#include "RefCountState.h"
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
#include "swift/SILOptimizer/Analysis/ProgramTerminationAnalysis.h"
#include "swift/Basic/BlotMapVector.h"
#include "swift/Basic/NullablePtr.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/Optional.h"
namespace swift {
class SILFunction;
class AliasAnalysis;
} // end swift namespace
namespace swift {
/// A class that implements the ARC sequence data flow.
class ARCSequenceDataflowEvaluator {
public:
// Forward declaration of private classes that are opaque in this header.
class ARCBBStateInfoHandle;
class ARCBBStateInfo;
class ARCBBState;
private:
/// The SILFunction that we are applying the dataflow to.
SILFunction &F;
/// The alias analysis that we are using for alias queries.
AliasAnalysis *AA;
/// The post order analysis we are using for computing post orders, reverse
/// post orders.
PostOrderAnalysis *POA;
/// An analysis which computes the identity root of a SILValue(), i.e. the
/// dominating origin SILValue of the reference count that by retaining or
/// releasing this value one is affecting.
RCIdentityFunctionInfo *RCIA;
/// The map from dataflow terminating decrements -> increment dataflow state.
BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap;
/// The map from dataflow terminating increment -> decrement dataflow state.
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap;
llvm::BumpPtrAllocator Allocator;
ImmutablePointerSetFactory<SILInstruction> SetFactory;
/// Stashed BB information.
ARCBBStateInfo *BBStateInfo;
ConsumedArgToEpilogueReleaseMatcher ConsumedArgToReleaseMap;
public:
ARCSequenceDataflowEvaluator(
SILFunction &F, AliasAnalysis *AA, PostOrderAnalysis *POA,
RCIdentityFunctionInfo *RCIA, ProgramTerminationFunctionInfo *PTFI,
BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap);
~ARCSequenceDataflowEvaluator();
/// Run the dataflow evaluator.
bool run(bool FreezePostDomReleases);
/// Clear all of the states we are tracking for the various basic blocks.
void clear();
SILFunction *getFunction() const { return &F; }
private:
/// Perform the bottom up data flow.
bool processBottomUp(bool freezePostDomReleases);
/// Perform the top down dataflow.
bool processTopDown();
/// Merge in the BottomUp state of any successors of DataHandle.getBB() into
/// DataHandle.getState().
void mergeSuccessors(ARCBBStateInfoHandle &DataHandle);
/// Merge in the TopDown state of any predecessors of DataHandle.getBB() into
/// DataHandle.getState().
void mergePredecessors(ARCBBStateInfoHandle &DataHandle);
bool processBBBottomUp(ARCBBState &BBState,
bool FreezeOwnedArgEpilogueReleases);
bool processBBTopDown(ARCBBState &BBState);
void computePostDominatingConsumedArgMap();
llvm::Optional<ARCBBStateInfoHandle> getBottomUpBBState(SILBasicBlock *BB);
llvm::Optional<ARCBBStateInfoHandle> getTopDownBBState(SILBasicBlock *BB);
};
} // end swift namespace
#endif