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 @@ -2646,6 +2646,12 @@ return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F); } + /// Return if the edge from \p From BB to \p To BB is assumed dead. + /// This is specifically useful in AAReachability. + virtual bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const { + return false; + } + /// See AbstractAttribute::getName() const std::string getName() const override { return "AAIsDead"; } 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 @@ -3093,6 +3093,10 @@ /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override; + bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override { + return !AssumedLiveEdges.count(std::make_pair(From, To)); + } + /// See AbstractAttribute::trackStatistics() void trackStatistics() const override {} @@ -3170,6 +3174,9 @@ /// Collection of instructions that are known to not transfer control. SmallSetVector KnownDeadEnds; + /// Collection of all assumed live edges + DenseSet> AssumedLiveEdges; + /// Collection of all assumed live BasicBlocks. DenseSet AssumedLiveBlocks; }; @@ -3340,6 +3347,9 @@ "Non-terminator expected to have a single successor!"); Worklist.push_back(AliveSuccessor); } else { + // record the assumed live edge + AssumedLiveEdges.insert( + std::make_pair(I->getParent(), AliveSuccessor->getParent())); if (assumeLive(A, *AliveSuccessor->getParent())) Worklist.push_back(AliveSuccessor); }