diff --git a/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h b/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h index e80412a30564..096573f4da80 100644 --- a/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h +++ b/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h @@ -86,6 +86,16 @@ inline const Value *GetUnderlyingObjCPtr(const Value *V, return V; } +/// A wrapper for GetUnderlyingObjCPtr used for results memoization. +inline const Value * +GetUnderlyingObjCPtrCached(const Value *V, const DataLayout &DL, + DenseMap &Cache) { + if (auto InCache = Cache.lookup(V)) + return InCache; + + return Cache[V] = GetUnderlyingObjCPtr(V, DL); +} + /// The RCIdentity root of a value \p V is a dominating value U for which /// retaining or releasing U is equivalent to retaining or releasing V. In other /// words, ARC operations on \p V are equivalent to ARC operations on \p U. diff --git a/llvm/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp b/llvm/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp index f89fc8eb62aa..3004fffb9745 100644 --- a/llvm/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp +++ b/llvm/lib/Transforms/ObjCARC/ProvenanceAnalysis.cpp @@ -115,14 +115,6 @@ static bool IsStoredObjCPointer(const Value *P) { bool ProvenanceAnalysis::relatedCheck(const Value *A, const Value *B, const DataLayout &DL) { - // Skip past provenance pass-throughs. - A = GetUnderlyingObjCPtr(A, DL); - B = GetUnderlyingObjCPtr(B, DL); - - // Quick check. - if (A == B) - return true; - // Ask regular AliasAnalysis, for a first approximation. switch (AA->alias(A, B)) { case NoAlias: @@ -171,6 +163,13 @@ bool ProvenanceAnalysis::relatedCheck(const Value *A, const Value *B, bool ProvenanceAnalysis::related(const Value *A, const Value *B, const DataLayout &DL) { + A = GetUnderlyingObjCPtrCached(A, DL, UnderlyingObjCPtrCache); + B = GetUnderlyingObjCPtrCached(B, DL, UnderlyingObjCPtrCache); + + // Quick check. + if (A == B) + return true; + // Begin by inserting a conservative value into the map. If the insertion // fails, we have the answer already. If it succeeds, leave it there until we // compute the real answer to guard against recursive queries. diff --git a/llvm/lib/Transforms/ObjCARC/ProvenanceAnalysis.h b/llvm/lib/Transforms/ObjCARC/ProvenanceAnalysis.h index 5e676167a6a1..f21ea3666b15 100644 --- a/llvm/lib/Transforms/ObjCARC/ProvenanceAnalysis.h +++ b/llvm/lib/Transforms/ObjCARC/ProvenanceAnalysis.h @@ -56,6 +56,8 @@ class ProvenanceAnalysis { CachedResultsTy CachedResults; + DenseMap UnderlyingObjCPtrCache; + bool relatedCheck(const Value *A, const Value *B, const DataLayout &DL); bool relatedSelect(const SelectInst *A, const Value *B); bool relatedPHI(const PHINode *A, const Value *B); @@ -73,6 +75,7 @@ public: void clear() { CachedResults.clear(); + UnderlyingObjCPtrCache.clear(); } };