Skip to content

Commit d51e347

Browse files
committed
[LazyCallGraph] Ignore empty RefSCCs rather than shift RefSCCs when removing dead functions
This is in preparation for D115545 which attempts to delete discardable functions if they are unused. With that change, shifting RefSCCs becomes noticeable in compile time. This change makes the LCG update negligible again. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D116776
1 parent d7986bf commit d51e347

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

llvm/include/llvm/Analysis/LazyCallGraph.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,9 @@ class LazyCallGraph {
884884
RefSCC *RC = nullptr;
885885

886886
/// Build the begin iterator for a node.
887-
postorder_ref_scc_iterator(LazyCallGraph &G) : G(&G), RC(getRC(G, 0)) {}
887+
postorder_ref_scc_iterator(LazyCallGraph &G) : G(&G), RC(getRC(G, 0)) {
888+
incrementUntilNonEmptyRefSCC();
889+
}
888890

889891
/// Build the end iterator for a node. This is selected purely by overload.
890892
postorder_ref_scc_iterator(LazyCallGraph &G, IsAtEndT /*Nonce*/) : G(&G) {}
@@ -899,6 +901,17 @@ class LazyCallGraph {
899901
return G.PostOrderRefSCCs[Index];
900902
}
901903

904+
// Keep incrementing until RC is non-empty (or null).
905+
void incrementUntilNonEmptyRefSCC() {
906+
while (RC && RC->size() == 0)
907+
increment();
908+
}
909+
910+
void increment() {
911+
assert(RC && "Cannot increment the end iterator!");
912+
RC = getRC(*G, G->RefSCCIndices.find(RC)->second + 1);
913+
}
914+
902915
public:
903916
bool operator==(const postorder_ref_scc_iterator &Arg) const {
904917
return G == Arg.G && RC == Arg.RC;
@@ -908,8 +921,8 @@ class LazyCallGraph {
908921

909922
using iterator_facade_base::operator++;
910923
postorder_ref_scc_iterator &operator++() {
911-
assert(RC && "Cannot increment the end iterator!");
912-
RC = getRC(*G, G->RefSCCIndices.find(RC)->second + 1);
924+
increment();
925+
incrementUntilNonEmptyRefSCC();
913926
return *this;
914927
}
915928
};

llvm/lib/Analysis/LazyCallGraph.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,15 +1544,9 @@ void LazyCallGraph::removeDeadFunction(Function &F) {
15441544
assert(C.size() == 1 && "Dead functions must be in a singular SCC");
15451545
assert(RC.size() == 1 && "Dead functions must be in a singular RefSCC");
15461546

1547-
auto RCIndexI = RefSCCIndices.find(&RC);
1548-
int RCIndex = RCIndexI->second;
1549-
PostOrderRefSCCs.erase(PostOrderRefSCCs.begin() + RCIndex);
1550-
RefSCCIndices.erase(RCIndexI);
1551-
for (int i = RCIndex, Size = PostOrderRefSCCs.size(); i < Size; ++i)
1552-
RefSCCIndices[PostOrderRefSCCs[i]] = i;
1553-
15541547
// Finally clear out all the data structures from the node down through the
1555-
// components.
1548+
// components. postorder_ref_scc_iterator will skip empty RefSCCs, so no need
1549+
// to adjust LazyCallGraph data structures.
15561550
N.clear();
15571551
N.G = nullptr;
15581552
N.F = nullptr;

0 commit comments

Comments
 (0)