@@ -4457,14 +4457,24 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4457
4457
CallsiteToCalleeFuncCloneMap[Caller] = CalleeFunc;
4458
4458
};
4459
4459
4460
+ // Information for a single clone of this Func.
4461
+ struct FuncCloneInfo {
4462
+ // The function clone.
4463
+ FuncInfo FuncClone;
4464
+ // Remappings of each call of interest (from original uncloned call to the
4465
+ // corresponding cloned call in this function clone).
4466
+ std::map<CallInfo, CallInfo> CallMap;
4467
+ };
4468
+
4460
4469
// Walk all functions for which we saw calls with memprof metadata, and handle
4461
4470
// cloning for each of its calls.
4462
4471
for (auto &[Func, CallsWithMetadata] : FuncToCallsWithMetadata) {
4463
4472
FuncInfo OrigFunc (Func);
4464
- // Map from each clone of OrigFunc to a map of remappings of each call of
4465
- // interest (from original uncloned call to the corresponding cloned call in
4466
- // that function clone).
4467
- std::map<FuncInfo, std::map<CallInfo, CallInfo>> FuncClonesToCallMap;
4473
+ // Map from each clone number of OrigFunc to information about that function
4474
+ // clone (the function clone FuncInfo and call remappings). The index into
4475
+ // the vector is the clone number, as function clones are created and
4476
+ // numbered sequentially.
4477
+ std::vector<FuncCloneInfo> FuncCloneInfos;
4468
4478
for (auto &Call : CallsWithMetadata) {
4469
4479
ContextNode *Node = getNodeForInst (Call);
4470
4480
// Skip call if we do not have a node for it (all uses of its stack ids
@@ -4488,8 +4498,9 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4488
4498
// Record the clone of callsite node assigned to this function clone.
4489
4499
FuncCloneToCurNodeCloneMap[FuncClone] = CallsiteClone;
4490
4500
4491
- assert (FuncClonesToCallMap.count (FuncClone));
4492
- std::map<CallInfo, CallInfo> &CallMap = FuncClonesToCallMap[FuncClone];
4501
+ assert (FuncCloneInfos.size () > FuncClone.cloneNo ());
4502
+ std::map<CallInfo, CallInfo> &CallMap =
4503
+ FuncCloneInfos[FuncClone.cloneNo ()].CallMap ;
4493
4504
CallInfo CallClone (Call);
4494
4505
if (auto It = CallMap.find (Call); It != CallMap.end ())
4495
4506
CallClone = It->second ;
@@ -4528,10 +4539,10 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4528
4539
// than existing function clones, which would have been assigned to an
4529
4540
// earlier clone in the list (we assign callsite clones to function
4530
4541
// clones greedily).
4531
- if (FuncClonesToCallMap .size () < NodeCloneCount) {
4542
+ if (FuncCloneInfos .size () < NodeCloneCount) {
4532
4543
// If this is the first callsite copy, assign to original function.
4533
4544
if (NodeCloneCount == 1 ) {
4534
- // Since FuncClonesToCallMap is empty in this case, no clones have
4545
+ // Since FuncCloneInfos is empty in this case, no clones have
4535
4546
// been created for this function yet, and no callers should have
4536
4547
// been assigned a function clone for this callee node yet.
4537
4548
assert (llvm::none_of (
@@ -4540,7 +4551,7 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4540
4551
}));
4541
4552
// Initialize with empty call map, assign Clone to original function
4542
4553
// and its callers, and skip to the next clone.
4543
- FuncClonesToCallMap[ OrigFunc] = {} ;
4554
+ FuncCloneInfos. push_back ({ OrigFunc, {}}) ;
4544
4555
AssignCallsiteCloneToFuncClone (
4545
4556
OrigFunc, Call, Clone,
4546
4557
AllocationCallToContextNodeMap.count (Call));
@@ -4572,14 +4583,14 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4572
4583
}
4573
4584
4574
4585
// Clone function and save it along with the CallInfo map created
4575
- // during cloning in the FuncClonesToCallMap .
4586
+ // during cloning in the FuncCloneInfos .
4576
4587
std::map<CallInfo, CallInfo> NewCallMap;
4577
- unsigned CloneNo = FuncClonesToCallMap .size ();
4588
+ unsigned CloneNo = FuncCloneInfos .size ();
4578
4589
assert (CloneNo > 0 && " Clone 0 is the original function, which "
4579
4590
" should already exist in the map" );
4580
4591
FuncInfo NewFuncClone = cloneFunctionForCallsite (
4581
4592
OrigFunc, Call, NewCallMap, CallsWithMetadata, CloneNo);
4582
- FuncClonesToCallMap. emplace ( NewFuncClone, std::move (NewCallMap));
4593
+ FuncCloneInfos. push_back ({ NewFuncClone, std::move (NewCallMap)} );
4583
4594
FunctionClonesAnalysis++;
4584
4595
Changed = true ;
4585
4596
@@ -4681,7 +4692,7 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4681
4692
CallInfo OrigCall (Callee->getOrigNode ()->Call );
4682
4693
OrigCall.setCloneNo (0 );
4683
4694
std::map<CallInfo, CallInfo> &CallMap =
4684
- FuncClonesToCallMap [NewFuncClone] ;
4695
+ FuncCloneInfos [NewFuncClone. cloneNo ()]. CallMap ;
4685
4696
assert (CallMap.count (OrigCall));
4686
4697
CallInfo NewCall (CallMap[OrigCall]);
4687
4698
assert (NewCall);
@@ -4819,13 +4830,13 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
4819
4830
// clone of OrigFunc for another caller during this iteration over
4820
4831
// its caller edges.
4821
4832
if (!FuncCloneAssignedToCurCallsiteClone) {
4822
- // Find first function in FuncClonesToCallMap without an assigned
4833
+ // Find first function in FuncCloneInfos without an assigned
4823
4834
// clone of this callsite Node. We should always have one
4824
4835
// available at this point due to the earlier cloning when the
4825
- // FuncClonesToCallMap size was smaller than the clone number.
4826
- for (auto &CF : FuncClonesToCallMap ) {
4827
- if (!FuncCloneToCurNodeCloneMap.count (CF.first )) {
4828
- FuncCloneAssignedToCurCallsiteClone = CF.first ;
4836
+ // FuncCloneInfos size was smaller than the clone number.
4837
+ for (auto &CF : FuncCloneInfos ) {
4838
+ if (!FuncCloneToCurNodeCloneMap.count (CF.FuncClone )) {
4839
+ FuncCloneAssignedToCurCallsiteClone = CF.FuncClone ;
4829
4840
break ;
4830
4841
}
4831
4842
}
0 commit comments