@@ -692,32 +692,28 @@ class CallsiteContextGraph {
692692
693693  // / Create a clone of Edge's callee and move Edge to that new callee node,
694694  // / performing the necessary context id and allocation type updates.
695-   // / If callee's caller edge iterator is supplied, it is updated when removing
696-   // / the edge from that list. If ContextIdsToMove is non-empty, only that
697-   // / subset of Edge's ids are moved to an edge to the new callee.
695+   // / If ContextIdsToMove is non-empty, only that subset of Edge's ids are
696+   // / moved to an edge to the new callee.
698697  ContextNode *
699698  moveEdgeToNewCalleeClone (const  std::shared_ptr<ContextEdge> &Edge,
700-                            EdgeIter *CallerEdgeI = nullptr ,
701699                           DenseSet<uint32_t > ContextIdsToMove = {});
702700
703701  // / Change the callee of Edge to existing callee clone NewCallee, performing
704702  // / the necessary context id and allocation type updates.
705-   // / If callee's caller edge iterator is supplied, it is updated when removing
706-   // / the edge from that list. If ContextIdsToMove is non-empty, only that
707-   // / subset of Edge's ids are moved to an edge to the new callee.
703+   // / If ContextIdsToMove is non-empty, only that subset of Edge's ids are
704+   // / moved to an edge to the new callee.
708705  void  moveEdgeToExistingCalleeClone (const  std::shared_ptr<ContextEdge> &Edge,
709706                                     ContextNode *NewCallee,
710-                                      EdgeIter *CallerEdgeI = nullptr ,
711707                                     bool  NewClone = false ,
712708                                     DenseSet<uint32_t > ContextIdsToMove = {});
713709
714710  // / Change the caller of the edge at the given callee edge iterator to be
715711  // / NewCaller, performing the necessary context id and allocation type
716-   // / updates. The iterator  is updated as  the edge is removed from the list of 
717-   // / callee edges in the original caller. This is similar to  the above 
718-   // / moveEdgeToExistingCalleeClone, but a simplified version of it as we always 
719-   // / move the given edge and all of its context ids. 
720-   void   moveCalleeEdgeToNewCaller (EdgeIter &CalleeEdgeI,  ContextNode *NewCaller);
712+   // / updates. This  is similar to  the above moveEdgeToExistingCalleeClone, but 
713+   // / a simplified version of it as we always move  the given edge and all of its 
714+   // / context ids. 
715+   void   moveCalleeEdgeToNewCaller ( const  std::shared_ptr<ContextEdge> &Edge, 
716+                                   ContextNode *NewCaller);
721717
722718  // / Recursively perform cloning on the graph for the given Node and its
723719  // / callers, in order to uniquely identify the allocation behavior of an
@@ -2313,12 +2309,13 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::partitionCallsByCallee(
23132309  //  Track whether we already assigned original node to a callee.
23142310  bool  UsedOrigNode = false ;
23152311  assert (NodeToCallingFunc[Node]);
2316-   for  (auto  EI = Node->CalleeEdges .begin (); EI != Node->CalleeEdges .end ();) {
2317-     auto  Edge = *EI;
2318-     if  (!Edge->Callee ->hasCall ()) {
2319-       ++EI;
2312+   //  Iterate over a copy of Node's callee edges, since we may need to remove
2313+   //  edges in moveCalleeEdgeToNewCaller, and this simplifies the handling and
2314+   //  makes it less error-prone.
2315+   auto  CalleeEdges = Node->CalleeEdges ;
2316+   for  (auto  &Edge : CalleeEdges) {
2317+     if  (!Edge->Callee ->hasCall ())
23202318      continue ;
2321-     }
23222319
23232320    //  Will be updated below to point to whatever (caller) node this callee edge
23242321    //  should be moved to.
@@ -2361,12 +2358,10 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::partitionCallsByCallee(
23612358    }
23622359
23632360    //  Don't need to move edge if we are using the original node;
2364-     if  (CallerNodeToUse == Node) {
2365-       ++EI;
2361+     if  (CallerNodeToUse == Node)
23662362      continue ;
2367-     }
23682363
2369-     moveCalleeEdgeToNewCaller (EI , CallerNodeToUse);
2364+     moveCalleeEdgeToNewCaller (Edge , CallerNodeToUse);
23702365  }
23712366  //  Now that we are done moving edges, clean up any caller edges that ended
23722367  //  up with no type or context ids. During moveCalleeEdgeToNewCaller all
@@ -3046,24 +3041,23 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::exportToDot(
30463041template  <typename  DerivedCCG, typename  FuncTy, typename  CallTy>
30473042typename  CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::ContextNode *
30483043CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::moveEdgeToNewCalleeClone(
3049-     const  std::shared_ptr<ContextEdge> &Edge, EdgeIter *CallerEdgeI, 
3044+     const  std::shared_ptr<ContextEdge> &Edge,
30503045    DenseSet<uint32_t > ContextIdsToMove) {
30513046  ContextNode *Node = Edge->Callee ;
30523047  assert (NodeToCallingFunc.count (Node));
30533048  ContextNode *Clone =
30543049      createNewNode (Node->IsAllocation , NodeToCallingFunc[Node], Node->Call );
30553050  Node->addClone (Clone);
30563051  Clone->MatchingCalls  = Node->MatchingCalls ;
3057-   moveEdgeToExistingCalleeClone (Edge, Clone, CallerEdgeI,  /* NewClone=*/ true ,
3052+   moveEdgeToExistingCalleeClone (Edge, Clone, /* NewClone=*/ true ,
30583053                                ContextIdsToMove);
30593054  return  Clone;
30603055}
30613056
30623057template  <typename  DerivedCCG, typename  FuncTy, typename  CallTy>
30633058void  CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
30643059    moveEdgeToExistingCalleeClone (const  std::shared_ptr<ContextEdge> &Edge,
3065-                                   ContextNode *NewCallee, EdgeIter *CallerEdgeI,
3066-                                   bool  NewClone,
3060+                                   ContextNode *NewCallee, bool  NewClone,
30673061                                  DenseSet<uint32_t > ContextIdsToMove) {
30683062  //  NewCallee and Edge's current callee must be clones of the same original
30693063  //  node (Edge's current callee may be the original node too).
@@ -3094,23 +3088,18 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
30943088                                                      ContextIdsToMove.end ());
30953089      ExistingEdgeToNewCallee->AllocTypes  |= Edge->AllocTypes ;
30963090      assert (Edge->ContextIds  == ContextIdsToMove);
3097-       removeEdgeFromGraph (Edge.get (), CallerEdgeI,  /* CalleeIter= */ false );
3091+       removeEdgeFromGraph (Edge.get ());
30983092    } else  {
30993093      //  Otherwise just reconnect Edge to NewCallee.
31003094      Edge->Callee  = NewCallee;
31013095      NewCallee->CallerEdges .push_back (Edge);
31023096      //  Remove it from callee where it was previously connected.
3103-       if  (CallerEdgeI)
3104-         *CallerEdgeI = OldCallee->CallerEdges .erase (*CallerEdgeI);
3105-       else 
3106-         OldCallee->eraseCallerEdge (Edge.get ());
3097+       OldCallee->eraseCallerEdge (Edge.get ());
31073098      //  Don't need to update Edge's context ids since we are simply
31083099      //  reconnecting it.
31093100    }
31103101  } else  {
31113102    //  Only moving a subset of Edge's ids.
3112-     if  (CallerEdgeI)
3113-       ++(*CallerEdgeI);
31143103    //  Compute the alloc type of the subset of ids being moved.
31153104    auto  CallerEdgeAllocType = computeAllocType (ContextIdsToMove);
31163105    if  (ExistingEdgeToNewCallee) {
@@ -3183,16 +3172,16 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
31833172
31843173template  <typename  DerivedCCG, typename  FuncTy, typename  CallTy>
31853174void  CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
3186-     moveCalleeEdgeToNewCaller (EdgeIter &CalleeEdgeI, ContextNode *NewCaller) { 
3187-   auto  Edge = *CalleeEdgeI; 
3175+     moveCalleeEdgeToNewCaller (const  std::shared_ptr<ContextEdge> &Edge, 
3176+                               ContextNode *NewCaller) { 
31883177
31893178  ContextNode *OldCaller = Edge->Caller ;
3179+   OldCaller->eraseCalleeEdge (Edge.get ());
31903180
31913181  //  We might already have an edge to the new caller. If one exists we will
31923182  //  reuse it.
31933183  auto  ExistingEdgeToNewCaller = NewCaller->findEdgeFromCallee (Edge->Callee );
31943184
3195-   CalleeEdgeI = OldCaller->CalleeEdges .erase (CalleeEdgeI);
31963185  if  (ExistingEdgeToNewCaller) {
31973186    //  Since we already have an edge to NewCaller, simply move the ids
31983187    //  onto it, and remove the existing Edge.
@@ -3417,22 +3406,20 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
34173406  //  Iterate until we find no more opportunities for disambiguating the alloc
34183407  //  types via cloning. In most cases this loop will terminate once the Node
34193408  //  has a single allocation type, in which case no more cloning is needed.
3420-   //  We need to be able to remove Edge from CallerEdges, so  need to adjust 
3421-   //  iterator inside  the loop. 
3422-   for  ( auto  EI = Node-> CallerEdges . begin (); EI != Node-> CallerEdges . end ();) { 
3423-      auto  CallerEdge  = *EI ;
3424- 
3409+   //  Iterate over a copy of Node's caller edges, since we may  need to remove 
3410+   //  edges in  the moveEdgeTo* methods, and this simplifies the handling and 
3411+   //  makes it less error-prone. 
3412+   auto  CallerEdges  = Node-> CallerEdges ;
3413+    for  ( auto  &CallerEdge : CallerEdges) { 
34253414    //  See if cloning the prior caller edge left this node with a single alloc
34263415    //  type or a single caller. In that case no more cloning of Node is needed.
34273416    if  (hasSingleAllocType (Node->AllocTypes ) || Node->CallerEdges .size () <= 1 )
34283417      break ;
34293418
34303419    //  If the caller was not successfully matched to a call in the IR/summary,
34313420    //  there is no point in trying to clone for it as we can't update that call.
3432-     if  (!CallerEdge->Caller ->hasCall ()) {
3433-       ++EI;
3421+     if  (!CallerEdge->Caller ->hasCall ())
34343422      continue ;
3435-     }
34363423
34373424    //  Only need to process the ids along this edge pertaining to the given
34383425    //  allocation.
@@ -3441,10 +3428,9 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
34413428    if  (!RecursiveContextIds.empty ())
34423429      CallerEdgeContextsForAlloc =
34433430          set_difference (CallerEdgeContextsForAlloc, RecursiveContextIds);
3444-     if  (CallerEdgeContextsForAlloc.empty ()) {
3445-       ++EI;
3431+     if  (CallerEdgeContextsForAlloc.empty ())
34463432      continue ;
3447-     } 
3433+ 
34483434    auto  CallerAllocTypeForAlloc = computeAllocType (CallerEdgeContextsForAlloc);
34493435
34503436    //  Compute the node callee edge alloc types corresponding to the context ids
@@ -3471,10 +3457,8 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
34713457    if  (allocTypeToUse (CallerAllocTypeForAlloc) ==
34723458            allocTypeToUse (Node->AllocTypes ) &&
34733459        allocTypesMatch<DerivedCCG, FuncTy, CallTy>(
3474-             CalleeEdgeAllocTypesForCallerEdge, Node->CalleeEdges )) {
3475-       ++EI;
3460+             CalleeEdgeAllocTypesForCallerEdge, Node->CalleeEdges ))
34763461      continue ;
3477-     }
34783462
34793463    //  First see if we can use an existing clone. Check each clone and its
34803464    //  callee edges for matching alloc types.
@@ -3504,14 +3488,11 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
35043488
35053489    //  The edge iterator is adjusted when we move the CallerEdge to the clone.
35063490    if  (Clone)
3507-       moveEdgeToExistingCalleeClone (CallerEdge, Clone, &EI,  /* NewClone=*/ false ,
3491+       moveEdgeToExistingCalleeClone (CallerEdge, Clone, /* NewClone=*/ false ,
35083492                                    CallerEdgeContextsForAlloc);
35093493    else 
3510-       Clone =
3511-           moveEdgeToNewCalleeClone (CallerEdge, &EI, CallerEdgeContextsForAlloc);
3494+       Clone = moveEdgeToNewCalleeClone (CallerEdge, CallerEdgeContextsForAlloc);
35123495
3513-     assert (EI == Node->CallerEdges .end () ||
3514-            Node->AllocTypes  != (uint8_t )AllocationType::None);
35153496    //  Sanity check that no alloc types on clone or its edges are None.
35163497    assert (Clone->AllocTypes  != (uint8_t )AllocationType::None);
35173498  }
@@ -3952,16 +3933,14 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
39523933        //  assign this clone to.
39533934        std::map<FuncInfo, ContextNode *> FuncCloneToNewCallsiteCloneMap;
39543935        FuncInfo FuncCloneAssignedToCurCallsiteClone;
3955-         //  We need to be able to remove Edge from CallerEdges, so  need to adjust 
3956-         //  iterator  in the loop. 
3957-         for  ( auto  EI = Clone-> CallerEdges . begin (); 
3958-              EI ! = Clone->CallerEdges . end ();) { 
3959-            auto  Edge = *EI; 
3936+         //  Iterate over a copy of Clone's caller edges, since we may  need to
3937+         //  remove edges  in the moveEdgeTo* methods, and this simplifies the 
3938+         //  handling and makes it less error-prone. 
3939+         auto  CloneCallerEdges  = Clone->CallerEdges ; 
3940+         for  ( auto  & Edge : CloneCallerEdges) { 
39603941          //  Ignore any caller that does not have a recorded callsite Call.
3961-           if  (!Edge->Caller ->hasCall ()) {
3962-             EI++;
3942+           if  (!Edge->Caller ->hasCall ())
39633943            continue ;
3964-           }
39653944          //  If this caller already assigned to call a version of OrigFunc, need
39663945          //  to ensure we can assign this callsite clone to that function clone.
39673946          if  (CallsiteToCalleeFuncCloneMap.count (Edge->Caller )) {
@@ -4006,27 +3985,24 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
40063985                      FuncCloneCalledByCaller)) {
40073986                ContextNode *NewClone =
40083987                    FuncCloneToNewCallsiteCloneMap[FuncCloneCalledByCaller];
4009-                 moveEdgeToExistingCalleeClone (Edge, NewClone, &EI );
3988+                 moveEdgeToExistingCalleeClone (Edge, NewClone);
40103989                //  Cleanup any none type edges cloned over.
40113990                removeNoneTypeCalleeEdges (NewClone);
40123991              } else  {
40133992                //  Create a new callsite clone.
4014-                 ContextNode *NewClone = moveEdgeToNewCalleeClone (Edge, &EI );
3993+                 ContextNode *NewClone = moveEdgeToNewCalleeClone (Edge);
40153994                removeNoneTypeCalleeEdges (NewClone);
40163995                FuncCloneToNewCallsiteCloneMap[FuncCloneCalledByCaller] =
40173996                    NewClone;
40183997                //  Add to list of clones and process later.
40193998                ClonesWorklist.push_back (NewClone);
4020-                 assert (EI == Clone->CallerEdges .end () ||
4021-                        Clone->AllocTypes  != (uint8_t )AllocationType::None);
40223999                assert (NewClone->AllocTypes  != (uint8_t )AllocationType::None);
40234000              }
40244001              //  Moving the caller edge may have resulted in some none type
40254002              //  callee edges.
40264003              removeNoneTypeCalleeEdges (Clone);
40274004              //  We will handle the newly created callsite clone in a subsequent
4028-               //  iteration over this Node's Clones. Continue here since we
4029-               //  already adjusted iterator EI while moving the edge.
4005+               //  iteration over this Node's Clones.
40304006              continue ;
40314007            }
40324008
@@ -4074,8 +4050,6 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
40744050            RecordCalleeFuncOfCallsite (Edge->Caller ,
40754051                                       FuncCloneAssignedToCurCallsiteClone);
40764052          }
4077- 
4078-           EI++;
40794053        }
40804054      }
40814055      if  (VerifyCCG) {
0 commit comments