@@ -4457,14 +4457,24 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
44574457 CallsiteToCalleeFuncCloneMap[Caller] = CalleeFunc;
44584458 };
44594459
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+
44604469 // Walk all functions for which we saw calls with memprof metadata, and handle
44614470 // cloning for each of its calls.
44624471 for (auto &[Func, CallsWithMetadata] : FuncToCallsWithMetadata) {
44634472 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;
44684478 for (auto &Call : CallsWithMetadata) {
44694479 ContextNode *Node = getNodeForInst (Call);
44704480 // 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() {
44884498 // Record the clone of callsite node assigned to this function clone.
44894499 FuncCloneToCurNodeCloneMap[FuncClone] = CallsiteClone;
44904500
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 ;
44934504 CallInfo CallClone (Call);
44944505 if (auto It = CallMap.find (Call); It != CallMap.end ())
44954506 CallClone = It->second ;
@@ -4528,10 +4539,10 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
45284539 // than existing function clones, which would have been assigned to an
45294540 // earlier clone in the list (we assign callsite clones to function
45304541 // clones greedily).
4531- if (FuncClonesToCallMap .size () < NodeCloneCount) {
4542+ if (FuncCloneInfos .size () < NodeCloneCount) {
45324543 // If this is the first callsite copy, assign to original function.
45334544 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
45354546 // been created for this function yet, and no callers should have
45364547 // been assigned a function clone for this callee node yet.
45374548 assert (llvm::none_of (
@@ -4540,7 +4551,7 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
45404551 }));
45414552 // Initialize with empty call map, assign Clone to original function
45424553 // and its callers, and skip to the next clone.
4543- FuncClonesToCallMap[ OrigFunc] = {} ;
4554+ FuncCloneInfos. push_back ({ OrigFunc, {}}) ;
45444555 AssignCallsiteCloneToFuncClone (
45454556 OrigFunc, Call, Clone,
45464557 AllocationCallToContextNodeMap.count (Call));
@@ -4572,14 +4583,14 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
45724583 }
45734584
45744585 // Clone function and save it along with the CallInfo map created
4575- // during cloning in the FuncClonesToCallMap .
4586+ // during cloning in the FuncCloneInfos .
45764587 std::map<CallInfo, CallInfo> NewCallMap;
4577- unsigned CloneNo = FuncClonesToCallMap .size ();
4588+ unsigned CloneNo = FuncCloneInfos .size ();
45784589 assert (CloneNo > 0 && " Clone 0 is the original function, which "
45794590 " should already exist in the map" );
45804591 FuncInfo NewFuncClone = cloneFunctionForCallsite (
45814592 OrigFunc, Call, NewCallMap, CallsWithMetadata, CloneNo);
4582- FuncClonesToCallMap. emplace ( NewFuncClone, std::move (NewCallMap));
4593+ FuncCloneInfos. push_back ({ NewFuncClone, std::move (NewCallMap)} );
45834594 FunctionClonesAnalysis++;
45844595 Changed = true ;
45854596
@@ -4681,7 +4692,7 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
46814692 CallInfo OrigCall (Callee->getOrigNode ()->Call );
46824693 OrigCall.setCloneNo (0 );
46834694 std::map<CallInfo, CallInfo> &CallMap =
4684- FuncClonesToCallMap [NewFuncClone] ;
4695+ FuncCloneInfos [NewFuncClone. cloneNo ()]. CallMap ;
46854696 assert (CallMap.count (OrigCall));
46864697 CallInfo NewCall (CallMap[OrigCall]);
46874698 assert (NewCall);
@@ -4819,13 +4830,13 @@ bool CallsiteContextGraph<DerivedCCG, FuncTy, CallTy>::assignFunctions() {
48194830 // clone of OrigFunc for another caller during this iteration over
48204831 // its caller edges.
48214832 if (!FuncCloneAssignedToCurCallsiteClone) {
4822- // Find first function in FuncClonesToCallMap without an assigned
4833+ // Find first function in FuncCloneInfos without an assigned
48234834 // clone of this callsite Node. We should always have one
48244835 // 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 ;
48294840 break ;
48304841 }
48314842 }
0 commit comments