Index: llvm/include/llvm/Transforms/IPO/Attributor.h =================================================================== --- llvm/include/llvm/Transforms/IPO/Attributor.h +++ llvm/include/llvm/Transforms/IPO/Attributor.h @@ -715,6 +715,19 @@ /// Return the map conaining all the knowledge we have from `llvm.assume`s. const RetainedKnowledgeMap &getKnowledgeMap() const { return KnowledgeMap; } + bool getPotentiallyReachable(const Instruction *From, const Instruction *To) { + auto KeyPair = std::make_pair(From, To); + auto Iter = PotentiallyReachableMap.find(KeyPair); + const Function &F = *From->getFunction(); + if (Iter != PotentiallyReachableMap.end()) + return Iter->second; + 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 +787,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; @@ -2291,16 +2308,21 @@ /// 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(const Instruction *From, const Instruction *To, + Attributor &A) const { + const auto &LivenessAA = + A.getAAFor(*this, IRPosition::value(*From)); + if (A.isAssumedDead(*From, this, &LivenessAA)) + return false; + 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(const Instruction *From, const Instruction *To, + Attributor &A) const { + return A.getInfoCache().getPotentiallyReachable(From, To); } /// Create an abstract attribute view for the position \p IRP. Index: llvm/lib/Transforms/IPO/AttributorAttributes.cpp =================================================================== --- llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -2469,7 +2469,7 @@ const auto &ReachabilityAA = A.getAAFor(*this, IRPosition::function(*ScopeFn)); - if (!ReachabilityAA.isAssumedReachable(UserI, getCtxI())) + if (!ReachabilityAA.isAssumedReachable(UserI, getCtxI(), A)) return true; if (auto *CB = dyn_cast(UserI)) {