@@ -530,6 +530,9 @@ class CallsiteContextGraph {
530530 // / multiple different callee target functions.
531531 void handleCallsitesWithMultipleTargets ();
532532
533+ // / Mark backedges via the standard DFS based backedge algorithm.
534+ void markBackedges ();
535+
533536 // Try to partition calls on the given node (already placed into the AllCalls
534537 // array) by callee function, creating new copies of Node as needed to hold
535538 // calls with different callees, and moving the callee edges appropriately.
@@ -740,6 +743,7 @@ class CallsiteContextGraph {
740743 void moveCalleeEdgeToNewCaller (const std::shared_ptr<ContextEdge> &Edge,
741744 ContextNode *NewCaller);
742745
746+ // / Recursive helper for marking backedges via DFS.
743747 void markBackedges (ContextNode *Node, DenseSet<const ContextNode *> &Visited,
744748 DenseSet<const ContextNode *> &CurrentStack);
745749
@@ -2108,6 +2112,8 @@ ModuleCallsiteContextGraph::ModuleCallsiteContextGraph(
21082112
21092113 handleCallsitesWithMultipleTargets ();
21102114
2115+ markBackedges ();
2116+
21112117 // Strip off remaining callsite metadata, no longer needed.
21122118 for (auto &FuncEntry : FuncToCallsWithMetadata)
21132119 for (auto &Call : FuncEntry.second )
@@ -2204,6 +2210,8 @@ IndexCallsiteContextGraph::IndexCallsiteContextGraph(
22042210 updateStackNodes ();
22052211
22062212 handleCallsitesWithMultipleTargets ();
2213+
2214+ markBackedges ();
22072215}
22082216
22092217template <typename DerivedCCG, typename FuncTy, typename CallTy>
@@ -3405,6 +3413,27 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
34053413
34063414// This is the standard DFS based backedge discovery algorithm.
34073415template <typename DerivedCCG, typename FuncTy, typename CallTy>
3416+ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::markBackedges() {
3417+ // If we are cloning recursive contexts, find and mark backedges from all root
3418+ // callers, using the typical DFS based backedge analysis.
3419+ if (!CloneRecursiveContexts)
3420+ return ;
3421+ DenseSet<const ContextNode *> Visited;
3422+ DenseSet<const ContextNode *> CurrentStack;
3423+ for (auto &Entry : NonAllocationCallToContextNodeMap) {
3424+ auto *Node = Entry.second ;
3425+ if (Node->isRemoved ())
3426+ continue ;
3427+ // It is a root if it doesn't have callers.
3428+ if (!Node->CallerEdges .empty ())
3429+ continue ;
3430+ markBackedges (Node, Visited, CurrentStack);
3431+ assert (CurrentStack.empty ());
3432+ }
3433+ }
3434+
3435+ // Recursive helper for above markBackedges method.
3436+ template <typename DerivedCCG, typename FuncTy, typename CallTy>
34083437void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::markBackedges(
34093438 ContextNode *Node, DenseSet<const ContextNode *> &Visited,
34103439 DenseSet<const ContextNode *> &CurrentStack) {
@@ -3429,22 +3458,7 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::markBackedges(
34293458
34303459template <typename DerivedCCG, typename FuncTy, typename CallTy>
34313460void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones() {
3432- // If we are cloning recursive contexts, find and mark backedges from all root
3433- // callers, using the typical DFS based backedge analysis.
34343461 DenseSet<const ContextNode *> Visited;
3435- if (CloneRecursiveContexts) {
3436- DenseSet<const ContextNode *> CurrentStack;
3437- for (auto &Entry : NonAllocationCallToContextNodeMap) {
3438- auto *Node = Entry.second ;
3439- if (Node->isRemoved ())
3440- continue ;
3441- // It is a root if it doesn't have callers.
3442- if (!Node->CallerEdges .empty ())
3443- continue ;
3444- markBackedges (Node, Visited, CurrentStack);
3445- assert (CurrentStack.empty ());
3446- }
3447- }
34483462 for (auto &Entry : AllocationCallToContextNodeMap) {
34493463 Visited.clear ();
34503464 identifyClones (Entry.second , Visited, Entry.second ->getContextIds ());
0 commit comments