summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2014-04-30 07:45:27 +0000
committerChandler Carruth <chandlerc@gmail.com>2014-04-30 07:45:27 +0000
commit6253c04fc9aefef98586e181329be742e7bb8d15 (patch)
tree386506ca61f6a799c33d5e3f94f2dcf2eb3a79bd /lib
parent28ea58283bb8a5f37ca6b41d7296641da570aaca (diff)
downloadllvm-6253c04fc9aefef98586e181329be742e7bb8d15.tar.gz
llvm-6253c04fc9aefef98586e181329be742e7bb8d15.tar.bz2
llvm-6253c04fc9aefef98586e181329be742e7bb8d15.tar.xz
[LCG] Actually test the *basic* edge removal bits (IE, the non-SCC
bits), and discover that it's totally broken. Yay tests. Boo bug. Fix the basic edge removal so that it works by nulling out the removed edges rather than actually removing them. This leaves the indices valid in the map from callee to index, and preserves some of the locality for iterating over edges. The iterator is made bidirectional to reflect that it now has to skip over null entries, and the skipping logic is layered onto it. As future work, I would like to track essentially the "load factor" of the edge list, and when it falls below a threshold do a compaction. An alternative I considered (and continue to consider) is storing the callees in a doubly linked list where each element of the list is in a set (which is essentially the classical linked-hash-table datastructure). The problem with that approach is that either you need to heap allocate the linked list nodes and use pointers to them, or use a bucket hash table (with even *more* linked list pointer overhead!), etc. It's pretty easy to get 5x overhead for values that are just pointers. So far, I think punching holes in the vector, and periodic compaction is likely to be much more efficient overall in the space/time tradeoff. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207619 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/LazyCallGraph.cpp12
1 files changed, 8 insertions, 4 deletions
diff --git a/lib/Analysis/LazyCallGraph.cpp b/lib/Analysis/LazyCallGraph.cpp
index 05757e1e2f..dd940a98f3 100644
--- a/lib/Analysis/LazyCallGraph.cpp
+++ b/lib/Analysis/LazyCallGraph.cpp
@@ -88,7 +88,7 @@ void LazyCallGraph::Node::removeEdgeInternal(Function &Callee) {
assert(IndexMapI != CalleeIndexMap.end() &&
"Callee not in the callee set for this caller?");
- Callees.erase(Callees.begin() + IndexMapI->second);
+ Callees[IndexMapI->second] = nullptr;
CalleeIndexMap.erase(IndexMapI);
}
@@ -115,11 +115,14 @@ LazyCallGraph::LazyCallGraph(Module &M) : NextDFSNumber(0) {
"entry set.\n");
findCallees(Worklist, Visited, EntryNodes, EntryIndexMap);
- for (auto &Entry : EntryNodes)
+ for (auto &Entry : EntryNodes) {
+ assert(!Entry.isNull() &&
+ "We can't have removed edges before we finish the constructor!");
if (Function *F = Entry.dyn_cast<Function *>())
SCCEntryNodes.push_back(F);
else
SCCEntryNodes.push_back(&Entry.get<Node *>()->getFunction());
+ }
}
LazyCallGraph::LazyCallGraph(LazyCallGraph &&G)
@@ -391,8 +394,9 @@ void LazyCallGraph::updateGraphPtrs() {
Node *N = Worklist.pop_back_val();
N->G = this;
for (auto &Callee : N->Callees)
- if (Node *CalleeN = Callee.dyn_cast<Node *>())
- Worklist.push_back(CalleeN);
+ if (!Callee.isNull())
+ if (Node *CalleeN = Callee.dyn_cast<Node *>())
+ Worklist.push_back(CalleeN);
}
}