[LCG] Just move the allocator (now that we can) when moving a call

graph. This simplifies the custom move constructor operation to one of
walking the graph and updating the 'up' pointers to point to the new
location of the graph. Switch the nodes from a reference to a pointer
for the 'up' edge to facilitate this.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206450 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2014-04-17 07:25:59 +00:00
parent 40f67f5764
commit a30ccb064b
2 changed files with 17 additions and 34 deletions

View File

@ -230,9 +230,6 @@ private:
/// \brief Helper to copy a node from another graph into this one. /// \brief Helper to copy a node from another graph into this one.
Node *copyInto(const Node &OtherN); Node *copyInto(const Node &OtherN);
/// \brief Helper to move a node from another graph into this one.
Node *moveInto(Node &&OtherN);
}; };
/// \brief A node in the call graph. /// \brief A node in the call graph.
@ -243,7 +240,7 @@ private:
class LazyCallGraph::Node { class LazyCallGraph::Node {
friend class LazyCallGraph; friend class LazyCallGraph;
LazyCallGraph &G; LazyCallGraph *G;
Function &F; Function &F;
mutable NodeVectorT Callees; mutable NodeVectorT Callees;
SmallPtrSet<Function *, 4> CalleeSet; SmallPtrSet<Function *, 4> CalleeSet;
@ -265,8 +262,8 @@ public:
return F; return F;
}; };
iterator begin() const { return iterator(G, Callees); } iterator begin() const { return iterator(*G, Callees); }
iterator end() const { return iterator(G, Callees, iterator::IsAtEndT()); } iterator end() const { return iterator(*G, Callees, iterator::IsAtEndT()); }
/// Equality is defined as address equality. /// Equality is defined as address equality.
bool operator==(const Node &N) const { return this == &N; } bool operator==(const Node &N) const { return this == &N; }

View File

@ -46,7 +46,7 @@ static void findCallees(
} }
} }
LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F) : G(G), F(F) { LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F) : G(&G), F(F) {
SmallVector<Constant *, 16> Worklist; SmallVector<Constant *, 16> Worklist;
SmallPtrSet<Constant *, 16> Visited; SmallPtrSet<Constant *, 16> Visited;
// Find all the potential callees in this function. First walk the // Find all the potential callees in this function. First walk the
@ -65,7 +65,7 @@ LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F) : G(G), F(F) {
} }
LazyCallGraph::Node::Node(LazyCallGraph &G, const Node &OtherN) LazyCallGraph::Node::Node(LazyCallGraph &G, const Node &OtherN)
: G(G), F(OtherN.F), CalleeSet(OtherN.CalleeSet) { : G(&G), F(OtherN.F), CalleeSet(OtherN.CalleeSet) {
// Loop over the other node's callees, adding the Function*s to our list // Loop over the other node's callees, adding the Function*s to our list
// directly, and recursing to add the Node*s. // directly, and recursing to add the Node*s.
Callees.reserve(OtherN.Callees.size()); Callees.reserve(OtherN.Callees.size());
@ -76,16 +76,6 @@ LazyCallGraph::Node::Node(LazyCallGraph &G, const Node &OtherN)
Callees.push_back(G.copyInto(*OtherCallee.get<Node *>())); Callees.push_back(G.copyInto(*OtherCallee.get<Node *>()));
} }
LazyCallGraph::Node::Node(LazyCallGraph &G, Node &&OtherN)
: G(G), F(OtherN.F), Callees(std::move(OtherN.Callees)),
CalleeSet(std::move(OtherN.CalleeSet)) {
// Loop over our Callees. They've been moved from another node, but we need
// to move the Node*s to live under our bump ptr allocator.
for (auto &Callee : Callees)
if (Node *ChildN = Callee.dyn_cast<Node *>())
Callee = G.moveInto(std::move(*ChildN));
}
LazyCallGraph::LazyCallGraph(Module &M) { LazyCallGraph::LazyCallGraph(Module &M) {
for (Function &F : M) for (Function &F : M)
if (!F.isDeclaration() && !F.hasLocalLinkage()) if (!F.isDeclaration() && !F.hasLocalLinkage())
@ -113,18 +103,22 @@ LazyCallGraph::LazyCallGraph(const LazyCallGraph &G)
EntryNodes.push_back(copyInto(*EntryNode.get<Node *>())); EntryNodes.push_back(copyInto(*EntryNode.get<Node *>()));
} }
// FIXME: This would be crazy simpler if BumpPtrAllocator were movable without
// invalidating any of the allocated memory. We should make that be the case at
// some point and delete this.
LazyCallGraph::LazyCallGraph(LazyCallGraph &&G) LazyCallGraph::LazyCallGraph(LazyCallGraph &&G)
: EntryNodes(std::move(G.EntryNodes)), : BPA(std::move(G.BPA)), EntryNodes(std::move(G.EntryNodes)),
EntryNodeSet(std::move(G.EntryNodeSet)) { EntryNodeSet(std::move(G.EntryNodeSet)) {
// Loop over our EntryNodes. They've been moved from another graph, so we // Process all nodes updating the graph pointers.
// need to move the Node*s to live under our bump ptr allocator. We can just SmallVector<Node *, 16> Worklist;
// do this in-place.
for (auto &Entry : EntryNodes) for (auto &Entry : EntryNodes)
if (Node *EntryN = Entry.dyn_cast<Node *>()) if (Node *EntryN = Entry.dyn_cast<Node *>())
Entry = moveInto(std::move(*EntryN)); Worklist.push_back(EntryN);
while (!Worklist.empty()) {
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);
}
} }
LazyCallGraph::Node *LazyCallGraph::insertInto(Function &F, Node *&MappedN) { LazyCallGraph::Node *LazyCallGraph::insertInto(Function &F, Node *&MappedN) {
@ -139,14 +133,6 @@ LazyCallGraph::Node *LazyCallGraph::copyInto(const Node &OtherN) {
return new (N = BPA.Allocate()) Node(*this, OtherN); return new (N = BPA.Allocate()) Node(*this, OtherN);
} }
LazyCallGraph::Node *LazyCallGraph::moveInto(Node &&OtherN) {
Node *&N = NodeMap[&OtherN.F];
if (N)
return N;
return new (N = BPA.Allocate()) Node(*this, std::move(OtherN));
}
char LazyCallGraphAnalysis::PassID; char LazyCallGraphAnalysis::PassID;
LazyCallGraphPrinterPass::LazyCallGraphPrinterPass(raw_ostream &OS) : OS(OS) {} LazyCallGraphPrinterPass::LazyCallGraphPrinterPass(raw_ostream &OS) : OS(OS) {}