static RetEffect MakeNoRet() {
return RetEffect(NoRet);
}
+
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ ID.AddInteger((unsigned) K);
+ ID.AddInteger((unsigned) O);
+ }
};
//===----------------------------------------------------------------------===//
namespace {
class RetainSummary {
- /// Args - an ordered vector of (index, ArgEffect) pairs, where index
+ /// Args - a map of (index, ArgEffect) pairs, where index
/// specifies the argument (starting from 0). This can be sparsely
/// populated; arguments with no entry in Args use 'DefaultArgEffect'.
ArgEffects Args;
return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
Receiver == Other.Receiver && Ret == Other.Ret;
}
+
+ /// Profile this summary for inclusion in a FoldingSet.
+ void Profile(llvm::FoldingSetNodeID& ID) const {
+ ID.Add(Args);
+ ID.Add(DefaultArgEffect);
+ ID.Add(Receiver);
+ ID.Add(Ret);
+ }
+
+ /// A retain summary is simple if it has no ArgEffects other than the default.
+ bool isSimple() const {
+ return Args.isEmpty();
+ }
};
} // end anonymous namespace
typedef ObjCSummaryCache ObjCMethodSummariesTy;
+ typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
+
//==-----------------------------------------------------------------==//
// Data.
//==-----------------------------------------------------------------==//
/// Objective-C objects.
RetEffect ObjCInitRetE;
- RetainSummary DefaultSummary;
- const RetainSummary *StopSummary;
+ /// SimpleSummaries - Used for uniquing summaries that don't have special
+ /// effects.
+ llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
//==-----------------------------------------------------------------==//
// Methods.
public:
RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
-
- const RetainSummary *getDefaultSummary() {
- return &DefaultSummary;
- }
const RetainSummary *getUnarySummary(const FunctionType* FT,
UnaryFuncKind func);
const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
const RetainSummary *getCFCreateGetRuleSummary(const FunctionDecl *FD);
- const RetainSummary *getPersistentSummary(ArgEffects AE, RetEffect RetEff,
- ArgEffect ReceiverEff = DoNothing,
- ArgEffect DefaultEff = MayEscape);
+ const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
- const RetainSummary *getPersistentSummary(RetEffect RE,
+ const RetainSummary *getPersistentSummary(RetEffect RetEff,
ArgEffect ReceiverEff = DoNothing,
ArgEffect DefaultEff = MayEscape) {
- return getPersistentSummary(getArgEffects(), RE, ReceiverEff, DefaultEff);
+ RetainSummary Summ(getArgEffects(), RetEff, DefaultEff, ReceiverEff);
+ return getPersistentSummary(Summ);
}
- const RetainSummary *getPersistentStopSummary() {
- if (StopSummary)
- return StopSummary;
-
- StopSummary = getPersistentSummary(RetEffect::MakeNoRet(),
- StopTracking, StopTracking);
+ const RetainSummary *getDefaultSummary() {
+ return getPersistentSummary(RetEffect::MakeNoRet(),
+ DoNothing, MayEscape);
+ }
- return StopSummary;
+ const RetainSummary *getPersistentStopSummary() {
+ return getPersistentSummary(RetEffect::MakeNoRet(),
+ StopTracking, StopTracking);
}
void InitializeClassMethodSummaries();
ObjCInitRetE(gcenabled
? RetEffect::MakeGCNotOwned()
: (usesARC ? RetEffect::MakeARCNotOwned()
- : RetEffect::MakeOwnedWhenTrackedReceiver())),
- DefaultSummary(AF.getEmptyMap() /* per-argument effects (none) */,
- RetEffect::MakeNoRet() /* return effect */,
- MayEscape, /* default argument effect */
- DoNothing /* receiver effect */),
- StopSummary(0) {
-
+ : RetEffect::MakeOwnedWhenTrackedReceiver())) {
InitializeClassMethodSummaries();
InitializeMethodSummaries();
}
bool isARCEnabled() const { return ARCEnabled; }
bool isARCorGCEnabled() const { return GCEnabled || ARCEnabled; }
-
- const RetainSummary *copySummary(const RetainSummary *OldSumm) {
- RetainSummary *Summ = (RetainSummary *) BPAlloc.Allocate<RetainSummary>();
- new (Summ) RetainSummary(*OldSumm);
- return Summ;
- }
};
// Used to avoid allocating long-term (BPAlloc'd) memory for default retain
~RetainSummaryTemplate() {
if (Accessed)
- RealSummary = Manager.copySummary(&ScratchSummary);
+ RealSummary = Manager.getPersistentSummary(ScratchSummary);
}
RetainSummary &operator*() {
}
const RetainSummary *
-RetainSummaryManager::getPersistentSummary(ArgEffects AE, RetEffect RetEff,
- ArgEffect ReceiverEff,
- ArgEffect DefaultEff) {
- // Create the summary and return it.
+RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) {
+ // Unique "simple" summaries -- those without ArgEffects.
+ if (OldSumm.isSimple()) {
+ llvm::FoldingSetNodeID ID;
+ OldSumm.Profile(ID);
+
+ void *Pos;
+ CachedSummaryNode *N = SimpleSummaries.FindNodeOrInsertPos(ID, Pos);
+
+ if (!N) {
+ N = (CachedSummaryNode *) BPAlloc.Allocate<CachedSummaryNode>();
+ new (N) CachedSummaryNode(OldSumm);
+ SimpleSummaries.InsertNode(N, Pos);
+ }
+
+ return &N->getValue();
+ }
+
RetainSummary *Summ = (RetainSummary *) BPAlloc.Allocate<RetainSummary>();
- new (Summ) RetainSummary(AE, RetEff, DefaultEff, ReceiverEff);
+ new (Summ) RetainSummary(OldSumm);
return Summ;
}
if (!FD)
return;
- RetainSummaryTemplate Template(Summ, DefaultSummary, *this);
+ RetainSummaryTemplate Template(Summ, *getDefaultSummary(), *this);
// Effects on the parameters.
unsigned parm_idx = 0;
if (!MD)
return;
- RetainSummaryTemplate Template(Summ, DefaultSummary, *this);
+ RetainSummaryTemplate Template(Summ, *getDefaultSummary(), *this);
bool isTrackedLoc = false;
// Effects on the receiver.