@@ -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
@@ -2313,12 +2309,13 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::partitionCallsByCallee(
2313
2309
// Track whether we already assigned original node to a callee.
2314
2310
bool UsedOrigNode = false ;
2315
2311
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 ())
2320
2318
continue ;
2321
- }
2322
2319
2323
2320
// Will be updated below to point to whatever (caller) node this callee edge
2324
2321
// should be moved to.
@@ -2361,12 +2358,10 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::partitionCallsByCallee(
2361
2358
}
2362
2359
2363
2360
// Don't need to move edge if we are using the original node;
2364
- if (CallerNodeToUse == Node) {
2365
- ++EI;
2361
+ if (CallerNodeToUse == Node)
2366
2362
continue ;
2367
- }
2368
2363
2369
- moveCalleeEdgeToNewCaller (EI , CallerNodeToUse);
2364
+ moveCalleeEdgeToNewCaller (Edge , CallerNodeToUse);
2370
2365
}
2371
2366
// Now that we are done moving edges, clean up any caller edges that ended
2372
2367
// up with no type or context ids. During moveCalleeEdgeToNewCaller all
@@ -3046,24 +3041,23 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::exportToDot(
3046
3041
template <typename DerivedCCG, typename FuncTy, typename CallTy>
3047
3042
typename CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::ContextNode *
3048
3043
CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::moveEdgeToNewCalleeClone(
3049
- const std::shared_ptr<ContextEdge> &Edge, EdgeIter *CallerEdgeI,
3044
+ const std::shared_ptr<ContextEdge> &Edge,
3050
3045
DenseSet<uint32_t > ContextIdsToMove) {
3051
3046
ContextNode *Node = Edge->Callee ;
3052
3047
assert (NodeToCallingFunc.count (Node));
3053
3048
ContextNode *Clone =
3054
3049
createNewNode (Node->IsAllocation , NodeToCallingFunc[Node], Node->Call );
3055
3050
Node->addClone (Clone);
3056
3051
Clone->MatchingCalls = Node->MatchingCalls ;
3057
- moveEdgeToExistingCalleeClone (Edge, Clone, CallerEdgeI, /* NewClone=*/ true ,
3052
+ moveEdgeToExistingCalleeClone (Edge, Clone, /* NewClone=*/ true ,
3058
3053
ContextIdsToMove);
3059
3054
return Clone;
3060
3055
}
3061
3056
3062
3057
template <typename DerivedCCG, typename FuncTy, typename CallTy>
3063
3058
void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
3064
3059
moveEdgeToExistingCalleeClone (const std::shared_ptr<ContextEdge> &Edge,
3065
- ContextNode *NewCallee, EdgeIter *CallerEdgeI,
3066
- bool NewClone,
3060
+ ContextNode *NewCallee, bool NewClone,
3067
3061
DenseSet<uint32_t > ContextIdsToMove) {
3068
3062
// NewCallee and Edge's current callee must be clones of the same original
3069
3063
// node (Edge's current callee may be the original node too).
@@ -3094,23 +3088,18 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
3094
3088
ContextIdsToMove.end ());
3095
3089
ExistingEdgeToNewCallee->AllocTypes |= Edge->AllocTypes ;
3096
3090
assert (Edge->ContextIds == ContextIdsToMove);
3097
- removeEdgeFromGraph (Edge.get (), CallerEdgeI, /* CalleeIter= */ false );
3091
+ removeEdgeFromGraph (Edge.get ());
3098
3092
} else {
3099
3093
// Otherwise just reconnect Edge to NewCallee.
3100
3094
Edge->Callee = NewCallee;
3101
3095
NewCallee->CallerEdges .push_back (Edge);
3102
3096
// 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 ());
3107
3098
// Don't need to update Edge's context ids since we are simply
3108
3099
// reconnecting it.
3109
3100
}
3110
3101
} else {
3111
3102
// Only moving a subset of Edge's ids.
3112
- if (CallerEdgeI)
3113
- ++(*CallerEdgeI);
3114
3103
// Compute the alloc type of the subset of ids being moved.
3115
3104
auto CallerEdgeAllocType = computeAllocType (ContextIdsToMove);
3116
3105
if (ExistingEdgeToNewCallee) {
@@ -3183,16 +3172,16 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::
3183
3172
3184
3173
template <typename DerivedCCG, typename FuncTy, typename CallTy>
3185
3174
void 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) {
3188
3177
3189
3178
ContextNode *OldCaller = Edge->Caller ;
3179
+ OldCaller->eraseCalleeEdge (Edge.get ());
3190
3180
3191
3181
// We might already have an edge to the new caller. If one exists we will
3192
3182
// reuse it.
3193
3183
auto ExistingEdgeToNewCaller = NewCaller->findEdgeFromCallee (Edge->Callee );
3194
3184
3195
- CalleeEdgeI = OldCaller->CalleeEdges .erase (CalleeEdgeI);
3196
3185
if (ExistingEdgeToNewCaller) {
3197
3186
// Since we already have an edge to NewCaller, simply move the ids
3198
3187
// onto it, and remove the existing Edge.
@@ -3417,22 +3406,20 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
3417
3406
// Iterate until we find no more opportunities for disambiguating the alloc
3418
3407
// types via cloning. In most cases this loop will terminate once the Node
3419
3408
// 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) {
3425
3414
// See if cloning the prior caller edge left this node with a single alloc
3426
3415
// type or a single caller. In that case no more cloning of Node is needed.
3427
3416
if (hasSingleAllocType (Node->AllocTypes ) || Node->CallerEdges .size () <= 1 )
3428
3417
break ;
3429
3418
3430
3419
// If the caller was not successfully matched to a call in the IR/summary,
3431
3420
// 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 ())
3434
3422
continue ;
3435
- }
3436
3423
3437
3424
// Only need to process the ids along this edge pertaining to the given
3438
3425
// allocation.
@@ -3441,10 +3428,9 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
3441
3428
if (!RecursiveContextIds.empty ())
3442
3429
CallerEdgeContextsForAlloc =
3443
3430
set_difference (CallerEdgeContextsForAlloc, RecursiveContextIds);
3444
- if (CallerEdgeContextsForAlloc.empty ()) {
3445
- ++EI;
3431
+ if (CallerEdgeContextsForAlloc.empty ())
3446
3432
continue ;
3447
- }
3433
+
3448
3434
auto CallerAllocTypeForAlloc = computeAllocType (CallerEdgeContextsForAlloc);
3449
3435
3450
3436
// Compute the node callee edge alloc types corresponding to the context ids
@@ -3471,10 +3457,8 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
3471
3457
if (allocTypeToUse (CallerAllocTypeForAlloc) ==
3472
3458
allocTypeToUse (Node->AllocTypes ) &&
3473
3459
allocTypesMatch<DerivedCCG, FuncTy, CallTy>(
3474
- CalleeEdgeAllocTypesForCallerEdge, Node->CalleeEdges )) {
3475
- ++EI;
3460
+ CalleeEdgeAllocTypesForCallerEdge, Node->CalleeEdges ))
3476
3461
continue ;
3477
- }
3478
3462
3479
3463
// First see if we can use an existing clone. Check each clone and its
3480
3464
// callee edges for matching alloc types.
@@ -3504,14 +3488,11 @@ void CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::identifyClones(
3504
3488
3505
3489
// The edge iterator is adjusted when we move the CallerEdge to the clone.
3506
3490
if (Clone)
3507
- moveEdgeToExistingCalleeClone (CallerEdge, Clone, &EI, /* NewClone=*/ false ,
3491
+ moveEdgeToExistingCalleeClone (CallerEdge, Clone, /* NewClone=*/ false ,
3508
3492
CallerEdgeContextsForAlloc);
3509
3493
else
3510
- Clone =
3511
- moveEdgeToNewCalleeClone (CallerEdge, &EI, CallerEdgeContextsForAlloc);
3494
+ Clone = moveEdgeToNewCalleeClone (CallerEdge, CallerEdgeContextsForAlloc);
3512
3495
3513
- assert (EI == Node->CallerEdges .end () ||
3514
- Node->AllocTypes != (uint8_t )AllocationType::None);
3515
3496
// Sanity check that no alloc types on clone or its edges are None.
3516
3497
assert (Clone->AllocTypes != (uint8_t )AllocationType::None);
3517
3498
}
@@ -3952,16 +3933,14 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
3952
3933
// assign this clone to.
3953
3934
std::map<FuncInfo, ContextNode *> FuncCloneToNewCallsiteCloneMap;
3954
3935
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) {
3960
3941
// Ignore any caller that does not have a recorded callsite Call.
3961
- if (!Edge->Caller ->hasCall ()) {
3962
- EI++;
3942
+ if (!Edge->Caller ->hasCall ())
3963
3943
continue ;
3964
- }
3965
3944
// If this caller already assigned to call a version of OrigFunc, need
3966
3945
// to ensure we can assign this callsite clone to that function clone.
3967
3946
if (CallsiteToCalleeFuncCloneMap.count (Edge->Caller )) {
@@ -4006,27 +3985,24 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4006
3985
FuncCloneCalledByCaller)) {
4007
3986
ContextNode *NewClone =
4008
3987
FuncCloneToNewCallsiteCloneMap[FuncCloneCalledByCaller];
4009
- moveEdgeToExistingCalleeClone (Edge, NewClone, &EI );
3988
+ moveEdgeToExistingCalleeClone (Edge, NewClone);
4010
3989
// Cleanup any none type edges cloned over.
4011
3990
removeNoneTypeCalleeEdges (NewClone);
4012
3991
} else {
4013
3992
// Create a new callsite clone.
4014
- ContextNode *NewClone = moveEdgeToNewCalleeClone (Edge, &EI );
3993
+ ContextNode *NewClone = moveEdgeToNewCalleeClone (Edge);
4015
3994
removeNoneTypeCalleeEdges (NewClone);
4016
3995
FuncCloneToNewCallsiteCloneMap[FuncCloneCalledByCaller] =
4017
3996
NewClone;
4018
3997
// Add to list of clones and process later.
4019
3998
ClonesWorklist.push_back (NewClone);
4020
- assert (EI == Clone->CallerEdges .end () ||
4021
- Clone->AllocTypes != (uint8_t )AllocationType::None);
4022
3999
assert (NewClone->AllocTypes != (uint8_t )AllocationType::None);
4023
4000
}
4024
4001
// Moving the caller edge may have resulted in some none type
4025
4002
// callee edges.
4026
4003
removeNoneTypeCalleeEdges (Clone);
4027
4004
// 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.
4030
4006
continue ;
4031
4007
}
4032
4008
@@ -4074,8 +4050,6 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4074
4050
RecordCalleeFuncOfCallsite (Edge->Caller ,
4075
4051
FuncCloneAssignedToCurCallsiteClone);
4076
4052
}
4077
-
4078
- EI++;
4079
4053
}
4080
4054
}
4081
4055
if (VerifyCCG) {
0 commit comments