mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Previously, we were being very conservative and were not trying to look through any RCId uses. Now we understand how to look through RCIdentical instructions to pair a pin and unpin. We also understand how to use the new getRCUses API on RCIdentityAnalysis to get all uses of a value, looking through RCIdentical instructions. I also added some code to COWArrayOpts to teach it how to look through enum insts (which I needed). Additionally I got stuck and added support for automatic indentation in Debug statements. This is better than having to indent by hand every time. There were no significant perf changes since this code was not being emitted by the frontend. But without this +0 self causes COW to break. rdar://20267677 Swift SVN r26529
80 lines
2.8 KiB
C++
80 lines
2.8 KiB
C++
//===--- RCIdentityAnalysis.h ------------------------------*- C++ -*------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2015 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This is an analysis that determines the ref count identity (i.e. gc root) of
|
|
// a pointer. Any values with the same ref count identity are able to be
|
|
// retained and released interchangably.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SILANALYSIS_RCIDENTITYANALYSIS_H
|
|
#define SWIFT_SILANALYSIS_RCIDENTITYANALYSIS_H
|
|
|
|
#include "swift/SIL/SILValue.h"
|
|
#include "swift/SIL/SILArgument.h"
|
|
#include "swift/SILAnalysis/Analysis.h"
|
|
#include "swift/SILAnalysis/DominanceAnalysis.h"
|
|
#include "swift/SILPasses/PassManager.h"
|
|
|
|
namespace swift {
|
|
|
|
class DominanceAnalysis;
|
|
|
|
/// This class is a simple wrapper around an identity cache.
|
|
class RCIdentityAnalysis : public SILAnalysis {
|
|
llvm::DenseMap<SILValue, SILValue> Cache;
|
|
llvm::DenseSet<SILArgument *> VisitedArgs;
|
|
DominanceAnalysis *DA;
|
|
|
|
/// This number is arbitrary and conservative. At some point if compile time
|
|
/// is not an issue, this value should be made more aggressive (i.e. greater).
|
|
enum { MaxRecursionDepth = 16 };
|
|
|
|
public:
|
|
RCIdentityAnalysis(SILModule *, SILPassManager *PM)
|
|
: SILAnalysis(AnalysisKind::RCIdentity), Cache(), VisitedArgs(),
|
|
DA(PM->getAnalysis<DominanceAnalysis>()) {}
|
|
RCIdentityAnalysis(const RCIdentityAnalysis &) = delete;
|
|
RCIdentityAnalysis &operator=(const RCIdentityAnalysis &) = delete;
|
|
|
|
SILValue getRCIdentityRoot(SILValue V);
|
|
|
|
/// Return all recursive users of V, looking through users which
|
|
/// propagate RCIdentity.
|
|
void getRCUsers(SILValue V, llvm::SmallVectorImpl<SILInstruction *> &Users);
|
|
|
|
static bool classof(const SILAnalysis *S) {
|
|
return S->getKind() == AnalysisKind::RCIdentity;
|
|
}
|
|
|
|
virtual void invalidate(SILAnalysis::PreserveKind K) {
|
|
Cache.clear();
|
|
}
|
|
|
|
// TODO: Add function specific cache to save compile time.
|
|
virtual void invalidate(SILFunction* F, SILAnalysis::PreserveKind K) {
|
|
invalidate(K);
|
|
}
|
|
|
|
private:
|
|
SILValue getRCIdentityRootInner(SILValue V, unsigned RecursionDepth);
|
|
SILValue stripRCIdentityPreservingOps(SILValue V, unsigned RecursionDepth);
|
|
SILValue stripRCIdentityPreservingArgs(SILValue V, unsigned RecursionDepth);
|
|
SILValue stripOneRCIdentityIncomingValue(SILArgument *Arg, SILValue V);
|
|
bool findDominatingNonPayloadedEdge(SILBasicBlock *IncomingEdgeBB,
|
|
SILValue RCIdentity);
|
|
};
|
|
|
|
} // end swift namespace
|
|
|
|
#endif
|