diff --git a/llvm/include/llvm/Analysis/LazyCallGraph.h b/llvm/include/llvm/Analysis/LazyCallGraph.h index 0580f4d7b226c0..a6b4345a4e09fd 100644 --- a/llvm/include/llvm/Analysis/LazyCallGraph.h +++ b/llvm/include/llvm/Analysis/LazyCallGraph.h @@ -884,7 +884,9 @@ class LazyCallGraph { RefSCC *RC = nullptr; /// Build the begin iterator for a node. - postorder_ref_scc_iterator(LazyCallGraph &G) : G(&G), RC(getRC(G, 0)) {} + postorder_ref_scc_iterator(LazyCallGraph &G) : G(&G), RC(getRC(G, 0)) { + incrementUntilNonEmptyRefSCC(); + } /// Build the end iterator for a node. This is selected purely by overload. postorder_ref_scc_iterator(LazyCallGraph &G, IsAtEndT /*Nonce*/) : G(&G) {} @@ -899,6 +901,17 @@ class LazyCallGraph { return G.PostOrderRefSCCs[Index]; } + // Keep incrementing until RC is non-empty (or null). + void incrementUntilNonEmptyRefSCC() { + while (RC && RC->size() == 0) + increment(); + } + + void increment() { + assert(RC && "Cannot increment the end iterator!"); + RC = getRC(*G, G->RefSCCIndices.find(RC)->second + 1); + } + public: bool operator==(const postorder_ref_scc_iterator &Arg) const { return G == Arg.G && RC == Arg.RC; @@ -908,8 +921,8 @@ class LazyCallGraph { using iterator_facade_base::operator++; postorder_ref_scc_iterator &operator++() { - assert(RC && "Cannot increment the end iterator!"); - RC = getRC(*G, G->RefSCCIndices.find(RC)->second + 1); + increment(); + incrementUntilNonEmptyRefSCC(); return *this; } }; diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp index 0007c54b16d073..d3e1aa7c8d9a82 100644 --- a/llvm/lib/Analysis/LazyCallGraph.cpp +++ b/llvm/lib/Analysis/LazyCallGraph.cpp @@ -1544,15 +1544,9 @@ void LazyCallGraph::removeDeadFunction(Function &F) { assert(C.size() == 1 && "Dead functions must be in a singular SCC"); assert(RC.size() == 1 && "Dead functions must be in a singular RefSCC"); - auto RCIndexI = RefSCCIndices.find(&RC); - int RCIndex = RCIndexI->second; - PostOrderRefSCCs.erase(PostOrderRefSCCs.begin() + RCIndex); - RefSCCIndices.erase(RCIndexI); - for (int i = RCIndex, Size = PostOrderRefSCCs.size(); i < Size; ++i) - RefSCCIndices[PostOrderRefSCCs[i]] = i; - // Finally clear out all the data structures from the node down through the - // components. + // components. postorder_ref_scc_iterator will skip empty RefSCCs, so no need + // to adjust LazyCallGraph data structures. N.clear(); N.G = nullptr; N.F = nullptr;