int LowLink;
mutable NodeVectorT Callees;
- SmallPtrSet<Function *, 4> CalleeSet;
+ DenseMap<Function *, size_t> CalleeIndexMap;
/// \brief Basic constructor implements the scanning of F into Callees and
- /// CalleeSet.
+ /// CalleeIndexMap.
Node(LazyCallGraph &G, Function &F);
public:
/// escape at the module scope.
NodeVectorT EntryNodes;
- /// \brief Set of the entry nodes to the graph.
- SmallPtrSet<Function *, 4> EntryNodeSet;
+ /// \brief Map of the entry nodes in the graph to their indices in
+ /// \c EntryNodes.
+ DenseMap<Function *, size_t> EntryIndexMap;
/// \brief Allocator that holds all the call graph SCCs.
SpecificBumpPtrAllocator<SCC> SCCBPA;
static void findCallees(
SmallVectorImpl<Constant *> &Worklist, SmallPtrSetImpl<Constant *> &Visited,
SmallVectorImpl<PointerUnion<Function *, LazyCallGraph::Node *>> &Callees,
- SmallPtrSetImpl<Function *> &CalleeSet) {
+ DenseMap<Function *, size_t> &CalleeIndexMap) {
while (!Worklist.empty()) {
Constant *C = Worklist.pop_back_val();
// alias. Then a test of the address of the weak function against the new
// strong definition's address would be an effective way to determine the
// safety of optimizing a direct call edge.
- if (!F->isDeclaration() && CalleeSet.insert(F)) {
+ if (!F->isDeclaration() &&
+ CalleeIndexMap.insert(std::make_pair(F, Callees.size())).second) {
DEBUG(dbgs() << " Added callable function: " << F->getName()
<< "\n");
Callees.push_back(F);
// We've collected all the constant (and thus potentially function or
// function containing) operands to all of the instructions in the function.
// Process them (recursively) collecting every function found.
- findCallees(Worklist, Visited, Callees, CalleeSet);
+ findCallees(Worklist, Visited, Callees, CalleeIndexMap);
}
LazyCallGraph::LazyCallGraph(Module &M) : NextDFSNumber(0) {
<< "\n");
for (Function &F : M)
if (!F.isDeclaration() && !F.hasLocalLinkage())
- if (EntryNodeSet.insert(&F)) {
+ if (EntryIndexMap.insert(std::make_pair(&F, EntryNodes.size())).second) {
DEBUG(dbgs() << " Adding '" << F.getName()
<< "' to entry set of the graph.\n");
EntryNodes.push_back(&F);
DEBUG(dbgs() << " Adding functions referenced by global initializers to the "
"entry set.\n");
- findCallees(Worklist, Visited, EntryNodes, EntryNodeSet);
+ findCallees(Worklist, Visited, EntryNodes, EntryIndexMap);
for (auto &Entry : EntryNodes)
if (Function *F = Entry.dyn_cast<Function *>())
LazyCallGraph::LazyCallGraph(LazyCallGraph &&G)
: BPA(std::move(G.BPA)), NodeMap(std::move(G.NodeMap)),
EntryNodes(std::move(G.EntryNodes)),
- EntryNodeSet(std::move(G.EntryNodeSet)), SCCBPA(std::move(G.SCCBPA)),
+ EntryIndexMap(std::move(G.EntryIndexMap)), SCCBPA(std::move(G.SCCBPA)),
SCCMap(std::move(G.SCCMap)), LeafSCCs(std::move(G.LeafSCCs)),
DFSStack(std::move(G.DFSStack)),
SCCEntryNodes(std::move(G.SCCEntryNodes)),
BPA = std::move(G.BPA);
NodeMap = std::move(G.NodeMap);
EntryNodes = std::move(G.EntryNodes);
- EntryNodeSet = std::move(G.EntryNodeSet);
+ EntryIndexMap = std::move(G.EntryIndexMap);
SCCBPA = std::move(G.SCCBPA);
SCCMap = std::move(G.SCCMap);
LeafSCCs = std::move(G.LeafSCCs);