@@ -692,32 +692,28 @@ class CallsiteContextGraph {
692
692
693
693
// / Create a clone of Edge's callee and move Edge to that new callee node,
694
694
// / 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.
698
697
ContextNode *
699
698
moveEdgeToNewCalleeClone (const std::shared_ptr<ContextEdge> &Edge,
700
- EdgeIter *CallerEdgeI = nullptr ,
701
699
DenseSet<uint32_t > ContextIdsToMove = {});
702
700
703
701
// / Change the callee of Edge to existing callee clone NewCallee, performing
704
702
// / 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.
708
705
void moveEdgeToExistingCalleeClone (const std::shared_ptr<ContextEdge> &Edge,
709
706
ContextNode *NewCallee,
710
- EdgeIter *CallerEdgeI = nullptr ,
711
707
bool NewClone = false ,
712
708
DenseSet<uint32_t > ContextIdsToMove = {});
713
709
714
710
// / Change the caller of the edge at the given callee edge iterator to be
715
711
// / 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);
721
717
722
718
// / Recursively perform cloning on the graph for the given Node and its
723
719
// / callers, in order to uniquely identify the allocation behavior of an
@@ -2301,12 +2297,13 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::partitionCallsByCallee(
2301
2297
// Track whether we already assigned original node to a callee.
2302
2298
bool UsedOrigNode = false ;
2303
2299
assert (NodeToCallingFunc[Node]);
2304
- for (auto EI = Node->CalleeEdges .begin (); EI != Node->CalleeEdges .end ();) {
2305
- auto Edge = *EI;
2306
- if (!Edge->Callee ->hasCall ()) {
2307
- ++EI;
2300
+ // Iterate over a copy of Node's callee edges, since we may need to remove
2301
+ // edges in moveCalleeEdgeToNewCaller, and this simplifies the handling and
2302
+ // makes it less error-prone.
2303
+ auto CalleeEdges = Node->CalleeEdges ;
2304
+ for (auto &Edge : CalleeEdges) {
2305
+ if (!Edge->Callee ->hasCall ())
2308
2306
continue ;
2309
- }
2310
2307
2311
2308
// Will be updated below to point to whatever (caller) node this callee edge
2312
2309
// should be moved to.
@@ -2349,12 +2346,10 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::partitionCallsByCallee(
2349
2346
}
2350
2347
2351
2348
// Don't need to move edge if we are using the original node;
2352
- if (CallerNodeToUse == Node) {
2353
- ++EI;
2349
+ if (CallerNodeToUse == Node)
2354
2350
continue ;
2355
- }
2356
2351
2357
- moveCalleeEdgeToNewCaller (EI , CallerNodeToUse);
2352
+ moveCalleeEdgeToNewCaller (Edge , CallerNodeToUse);
2358
2353
}
2359
2354
// Now that we are done moving edges, clean up any caller edges that ended
2360
2355
// up with no type or context ids. During moveCalleeEdgeToNewCaller all
@@ -3038,24 +3033,23 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::exportToDot(
3038
3033
template <typename DerivedCCG, typename FuncTy, typename CallTy>
3039
3034
typename CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::ContextNode *
3040
3035
CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::moveEdgeToNewCalleeClone(
3041
- const std::shared_ptr<ContextEdge> &Edge, EdgeIter *CallerEdgeI,
3036
+ const std::shared_ptr<ContextEdge> &Edge,
3042
3037
DenseSet<uint32_t > ContextIdsToMove) {
3043
3038
ContextNode *Node = Edge->Callee ;
3044
3039
assert (NodeToCallingFunc.count (Node));
3045
3040
ContextNode *Clone =
3046
3041
createNewNode (Node->IsAllocation , NodeToCallingFunc[Node], Node->Call );
3047
3042
Node->addClone (Clone);
3048
3043
Clone->MatchingCalls = Node->MatchingCalls ;
3049
- moveEdgeToExistingCalleeClone (Edge, Clone, CallerEdgeI, /* NewClone=*/ true ,
3044
+ moveEdgeToExistingCalleeClone (Edge, Clone, /* NewClone=*/ true ,
3050
3045
ContextIdsToMove);
3051
3046
return Clone;
3052
3047
}
3053
3048
3054
3049
template <typename DerivedCCG, typename FuncTy, typename CallTy>
3055
3050
void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
3056
3051
moveEdgeToExistingCalleeClone (const std::shared_ptr<ContextEdge> &Edge,
3057
- ContextNode *NewCallee, EdgeIter *CallerEdgeI,
3058
- bool NewClone,
3052
+ ContextNode *NewCallee, bool NewClone,
3059
3053
DenseSet<uint32_t > ContextIdsToMove) {
3060
3054
// NewCallee and Edge's current callee must be clones of the same original
3061
3055
// node (Edge's current callee may be the original node too).
@@ -3086,23 +3080,18 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
3086
3080
ContextIdsToMove.end ());
3087
3081
ExistingEdgeToNewCallee->AllocTypes |= Edge->AllocTypes ;
3088
3082
assert (Edge->ContextIds == ContextIdsToMove);
3089
- removeEdgeFromGraph (Edge.get (), CallerEdgeI, /* CalleeIter= */ false );
3083
+ removeEdgeFromGraph (Edge.get ());
3090
3084
} else {
3091
3085
// Otherwise just reconnect Edge to NewCallee.
3092
3086
Edge->Callee = NewCallee;
3093
3087
NewCallee->CallerEdges .push_back (Edge);
3094
3088
// Remove it from callee where it was previously connected.
3095
- if (CallerEdgeI)
3096
- *CallerEdgeI = OldCallee->CallerEdges .erase (*CallerEdgeI);
3097
- else
3098
- OldCallee->eraseCallerEdge (Edge.get ());
3089
+ OldCallee->eraseCallerEdge (Edge.get ());
3099
3090
// Don't need to update Edge's context ids since we are simply
3100
3091
// reconnecting it.
3101
3092
}
3102
3093
} else {
3103
3094
// Only moving a subset of Edge's ids.
3104
- if (CallerEdgeI)
3105
- ++CallerEdgeI;
3106
3095
// Compute the alloc type of the subset of ids being moved.
3107
3096
auto CallerEdgeAllocType = computeAllocType (ContextIdsToMove);
3108
3097
if (ExistingEdgeToNewCallee) {
@@ -3175,16 +3164,16 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
3175
3164
3176
3165
template <typename DerivedCCG, typename FuncTy, typename CallTy>
3177
3166
void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
3178
- moveCalleeEdgeToNewCaller (EdgeIter &CalleeEdgeI, ContextNode *NewCaller) {
3179
- auto Edge = *CalleeEdgeI;
3167
+ moveCalleeEdgeToNewCaller (const std::shared_ptr<ContextEdge> &Edge,
3168
+ ContextNode *NewCaller) {
3180
3169
3181
3170
ContextNode *OldCaller = Edge->Caller ;
3171
+ OldCaller->eraseCalleeEdge (Edge.get ());
3182
3172
3183
3173
// We might already have an edge to the new caller. If one exists we will
3184
3174
// reuse it.
3185
3175
auto ExistingEdgeToNewCaller = NewCaller->findEdgeFromCallee (Edge->Callee );
3186
3176
3187
- CalleeEdgeI = OldCaller->CalleeEdges .erase (CalleeEdgeI);
3188
3177
if (ExistingEdgeToNewCaller) {
3189
3178
// Since we already have an edge to NewCaller, simply move the ids
3190
3179
// onto it, and remove the existing Edge.
@@ -3409,22 +3398,20 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
3409
3398
// Iterate until we find no more opportunities for disambiguating the alloc
3410
3399
// types via cloning. In most cases this loop will terminate once the Node
3411
3400
// has a single allocation type, in which case no more cloning is needed.
3412
- // We need to be able to remove Edge from CallerEdges, so need to adjust
3413
- // iterator inside the loop.
3414
- for ( auto EI = Node-> CallerEdges . begin (); EI != Node-> CallerEdges . end ();) {
3415
- auto CallerEdge = *EI ;
3416
-
3401
+ // Iterate over a copy of Node's caller edges, since we may need to remove
3402
+ // edges in the moveEdgeTo* methods, and this simplifies the handling and
3403
+ // makes it less error-prone.
3404
+ auto CallerEdges = Node-> CallerEdges ;
3405
+ for ( auto &CallerEdge : CallerEdges) {
3417
3406
// See if cloning the prior caller edge left this node with a single alloc
3418
3407
// type or a single caller. In that case no more cloning of Node is needed.
3419
3408
if (hasSingleAllocType (Node->AllocTypes ) || Node->CallerEdges .size () <= 1 )
3420
3409
break ;
3421
3410
3422
3411
// If the caller was not successfully matched to a call in the IR/summary,
3423
3412
// there is no point in trying to clone for it as we can't update that call.
3424
- if (!CallerEdge->Caller ->hasCall ()) {
3425
- ++EI;
3413
+ if (!CallerEdge->Caller ->hasCall ())
3426
3414
continue ;
3427
- }
3428
3415
3429
3416
// Only need to process the ids along this edge pertaining to the given
3430
3417
// allocation.
@@ -3433,10 +3420,9 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
3433
3420
if (!RecursiveContextIds.empty ())
3434
3421
CallerEdgeContextsForAlloc =
3435
3422
set_difference (CallerEdgeContextsForAlloc, RecursiveContextIds);
3436
- if (CallerEdgeContextsForAlloc.empty ()) {
3437
- ++EI;
3423
+ if (CallerEdgeContextsForAlloc.empty ())
3438
3424
continue ;
3439
- }
3425
+
3440
3426
auto CallerAllocTypeForAlloc = computeAllocType (CallerEdgeContextsForAlloc);
3441
3427
3442
3428
// Compute the node callee edge alloc types corresponding to the context ids
@@ -3463,10 +3449,8 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
3463
3449
if (allocTypeToUse (CallerAllocTypeForAlloc) ==
3464
3450
allocTypeToUse (Node->AllocTypes ) &&
3465
3451
allocTypesMatch<DerivedCCG, FuncTy, CallTy>(
3466
- CalleeEdgeAllocTypesForCallerEdge, Node->CalleeEdges )) {
3467
- ++EI;
3452
+ CalleeEdgeAllocTypesForCallerEdge, Node->CalleeEdges ))
3468
3453
continue ;
3469
- }
3470
3454
3471
3455
// First see if we can use an existing clone. Check each clone and its
3472
3456
// callee edges for matching alloc types.
@@ -3496,14 +3480,11 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
3496
3480
3497
3481
// The edge iterator is adjusted when we move the CallerEdge to the clone.
3498
3482
if (Clone)
3499
- moveEdgeToExistingCalleeClone (CallerEdge, Clone, &EI, /* NewClone=*/ false ,
3483
+ moveEdgeToExistingCalleeClone (CallerEdge, Clone, /* NewClone=*/ false ,
3500
3484
CallerEdgeContextsForAlloc);
3501
3485
else
3502
- Clone =
3503
- moveEdgeToNewCalleeClone (CallerEdge, &EI, CallerEdgeContextsForAlloc);
3486
+ Clone = moveEdgeToNewCalleeClone (CallerEdge, CallerEdgeContextsForAlloc);
3504
3487
3505
- assert (EI == Node->CallerEdges .end () ||
3506
- Node->AllocTypes != (uint8_t )AllocationType::None);
3507
3488
// Sanity check that no alloc types on clone or its edges are None.
3508
3489
assert (Clone->AllocTypes != (uint8_t )AllocationType::None);
3509
3490
}
@@ -3944,16 +3925,14 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
3944
3925
// assign this clone to.
3945
3926
std::map<FuncInfo, ContextNode *> FuncCloneToNewCallsiteCloneMap;
3946
3927
FuncInfo FuncCloneAssignedToCurCallsiteClone;
3947
- // We need to be able to remove Edge from CallerEdges, so need to adjust
3948
- // iterator in the loop.
3949
- for ( auto EI = Clone-> CallerEdges . begin ();
3950
- EI ! = Clone->CallerEdges . end ();) {
3951
- auto Edge = *EI;
3928
+ // Iterate over a copy of Clone's caller edges, since we may need to
3929
+ // remove edges in the moveEdgeTo* methods, and this simplifies the
3930
+ // handling and makes it less error-prone.
3931
+ auto CloneCallerEdges = Clone->CallerEdges ;
3932
+ for ( auto & Edge : CloneCallerEdges) {
3952
3933
// Ignore any caller that does not have a recorded callsite Call.
3953
- if (!Edge->Caller ->hasCall ()) {
3954
- EI++;
3934
+ if (!Edge->Caller ->hasCall ())
3955
3935
continue ;
3956
- }
3957
3936
// If this caller already assigned to call a version of OrigFunc, need
3958
3937
// to ensure we can assign this callsite clone to that function clone.
3959
3938
if (CallsiteToCalleeFuncCloneMap.count (Edge->Caller )) {
@@ -3998,27 +3977,24 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
3998
3977
FuncCloneCalledByCaller)) {
3999
3978
ContextNode *NewClone =
4000
3979
FuncCloneToNewCallsiteCloneMap[FuncCloneCalledByCaller];
4001
- moveEdgeToExistingCalleeClone (Edge, NewClone, &EI );
3980
+ moveEdgeToExistingCalleeClone (Edge, NewClone);
4002
3981
// Cleanup any none type edges cloned over.
4003
3982
removeNoneTypeCalleeEdges (NewClone);
4004
3983
} else {
4005
3984
// Create a new callsite clone.
4006
- ContextNode *NewClone = moveEdgeToNewCalleeClone (Edge, &EI );
3985
+ ContextNode *NewClone = moveEdgeToNewCalleeClone (Edge);
4007
3986
removeNoneTypeCalleeEdges (NewClone);
4008
3987
FuncCloneToNewCallsiteCloneMap[FuncCloneCalledByCaller] =
4009
3988
NewClone;
4010
3989
// Add to list of clones and process later.
4011
3990
ClonesWorklist.push_back (NewClone);
4012
- assert (EI == Clone->CallerEdges .end () ||
4013
- Clone->AllocTypes != (uint8_t )AllocationType::None);
4014
3991
assert (NewClone->AllocTypes != (uint8_t )AllocationType::None);
4015
3992
}
4016
3993
// Moving the caller edge may have resulted in some none type
4017
3994
// callee edges.
4018
3995
removeNoneTypeCalleeEdges (Clone);
4019
3996
// We will handle the newly created callsite clone in a subsequent
4020
- // iteration over this Node's Clones. Continue here since we
4021
- // already adjusted iterator EI while moving the edge.
3997
+ // iteration over this Node's Clones.
4022
3998
continue ;
4023
3999
}
4024
4000
@@ -4066,8 +4042,6 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4066
4042
RecordCalleeFuncOfCallsite (Edge->Caller ,
4067
4043
FuncCloneAssignedToCurCallsiteClone);
4068
4044
}
4069
-
4070
- EI++;
4071
4045
}
4072
4046
}
4073
4047
if (VerifyCCG) {
0 commit comments