diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -715,6 +715,21 @@ /// Return the map conaining all the knowledge we have from `llvm.assume`s. const RetainedKnowledgeMap &getKnowledgeMap() const { return KnowledgeMap; } + /// Return if \p To is potentially reachable form \p From or not + /// If the same query was answered, return cached result + bool getPotentiallyReachable(const Instruction &From, const Instruction &To) { + auto KeyPair = std::make_pair(&From, &To); + auto Iter = PotentiallyReachableMap.find(KeyPair); + if (Iter != PotentiallyReachableMap.end()) + return Iter->second; + const Function &F = *From.getFunction(); + bool Result = isPotentiallyReachable( + &From, &To, nullptr, AG.getAnalysis(F), + AG.getAnalysis(F)); + PotentiallyReachableMap.insert(std::make_pair(KeyPair, Result)); + return Result; + } + private: struct FunctionInfo { ~FunctionInfo(); @@ -774,6 +789,10 @@ /// Set of inlineable functions SmallPtrSet InlineableFunctions; + /// A map for caching results of queries for isPotentiallyReachable + DenseMap, bool> + PotentiallyReachableMap; + /// Give the Attributor access to the members so /// Attributor::identifyDefaultAbstractAttributes(...) can initialize them. friend struct Attributor; @@ -2374,16 +2393,17 @@ /// Returns true if 'From' instruction is assumed to reach, 'To' instruction. /// Users should provide two positions they are interested in, and the class /// determines (and caches) reachability. - bool isAssumedReachable(const Instruction *From, - const Instruction *To) const { - return isPotentiallyReachable(From, To); + bool isAssumedReachable(Attributor &A, const Instruction &From, + const Instruction &To) const { + return A.getInfoCache().getPotentiallyReachable(From, To); } /// Returns true if 'From' instruction is known to reach, 'To' instruction. /// Users should provide two positions they are interested in, and the class /// determines (and caches) reachability. - bool isKnownReachable(const Instruction *From, const Instruction *To) const { - return isPotentiallyReachable(From, To); + bool isKnownReachable(Attributor &A, const Instruction &From, + const Instruction &To) const { + return A.getInfoCache().getPotentiallyReachable(From, To); } /// Create an abstract attribute view for the position \p IRP. diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -2468,7 +2468,7 @@ const auto &ReachabilityAA = A.getAAFor(*this, IRPosition::function(*ScopeFn)); - if (!ReachabilityAA.isAssumedReachable(UserI, getCtxI())) + if (!ReachabilityAA.isAssumedReachable(A, *UserI, *getCtxI())) return true; if (auto *CB = dyn_cast(UserI)) {