@@ -429,6 +429,63 @@ handleAllocSite(Instruction &I, CallBase *CI,
429429 }
430430}
431431
432+ // Helper struct for maintaining refs to callsite data. As an alternative we
433+ // could store a pointer to the CallSiteInfo struct but we also need the frame
434+ // index. Using ArrayRefs instead makes it a little easier to read.
435+ struct CallSiteEntry {
436+ // Subset of frames for the corresponding CallSiteInfo.
437+ ArrayRef<Frame> Frames;
438+ // Potential targets for indirect calls.
439+ ArrayRef<GlobalValue::GUID> CalleeGuids;
440+
441+ // Only compare Frame contents.
442+ // Use pointer-based equality instead of ArrayRef's operator== which does
443+ // element-wise comparison. We want to check if it's the same slice of the
444+ // underlying array, not just equivalent content.
445+ bool operator ==(const CallSiteEntry &Other) const {
446+ return Frames.data () == Other.Frames .data () &&
447+ Frames.size () == Other.Frames .size ();
448+ }
449+ };
450+
451+ struct CallSiteEntryHash {
452+ size_t operator ()(const CallSiteEntry &Entry) const {
453+ return computeFullStackId (Entry.Frames );
454+ }
455+ };
456+
457+ static void handleCallSite (
458+ Instruction &I, const Function *CalledFunction,
459+ ArrayRef<uint64_t > InlinedCallStack,
460+ const std::unordered_set<CallSiteEntry, CallSiteEntryHash> &CallSiteEntries,
461+ Module &M, std::set<std::vector<uint64_t >> &MatchedCallSites) {
462+ auto &Ctx = M.getContext ();
463+ for (const auto &CallSiteEntry : CallSiteEntries) {
464+ // If we found and thus matched all frames on the call, create and
465+ // attach call stack metadata.
466+ if (stackFrameIncludesInlinedCallStack (CallSiteEntry.Frames ,
467+ InlinedCallStack)) {
468+ NumOfMemProfMatchedCallSites++;
469+ addCallsiteMetadata (I, InlinedCallStack, Ctx);
470+
471+ // Try to attach indirect call metadata if possible.
472+ if (!CalledFunction)
473+ addVPMetadata (M, I, CallSiteEntry.CalleeGuids );
474+
475+ // Only need to find one with a matching call stack and add a single
476+ // callsite metadata.
477+
478+ // Accumulate call site matching information upon request.
479+ if (ClPrintMemProfMatchInfo) {
480+ std::vector<uint64_t > CallStack;
481+ append_range (CallStack, InlinedCallStack);
482+ MatchedCallSites.insert (std::move (CallStack));
483+ }
484+ break ;
485+ }
486+ }
487+ }
488+
432489static void readMemprof (Module &M, Function &F,
433490 IndexedInstrProfReader *MemProfReader,
434491 const TargetLibraryInfo &TLI,
@@ -499,31 +556,6 @@ static void readMemprof(Module &M, Function &F,
499556 // (allocation info and the callsites).
500557 std::map<uint64_t , std::set<const AllocationInfo *>> LocHashToAllocInfo;
501558
502- // Helper struct for maintaining refs to callsite data. As an alternative we
503- // could store a pointer to the CallSiteInfo struct but we also need the frame
504- // index. Using ArrayRefs instead makes it a little easier to read.
505- struct CallSiteEntry {
506- // Subset of frames for the corresponding CallSiteInfo.
507- ArrayRef<Frame> Frames;
508- // Potential targets for indirect calls.
509- ArrayRef<GlobalValue::GUID> CalleeGuids;
510-
511- // Only compare Frame contents.
512- // Use pointer-based equality instead of ArrayRef's operator== which does
513- // element-wise comparison. We want to check if it's the same slice of the
514- // underlying array, not just equivalent content.
515- bool operator ==(const CallSiteEntry &Other) const {
516- return Frames.data () == Other.Frames .data () &&
517- Frames.size () == Other.Frames .size ();
518- }
519- };
520-
521- struct CallSiteEntryHash {
522- size_t operator ()(const CallSiteEntry &Entry) const {
523- return computeFullStackId (Entry.Frames );
524- }
525- };
526-
527559 // For the callsites we need to record slices of the frame array (see comments
528560 // below where the map entries are added) along with their CalleeGuids.
529561 std::map<uint64_t , std::unordered_set<CallSiteEntry, CallSiteEntryHash>>
@@ -633,30 +665,8 @@ static void readMemprof(Module &M, Function &F,
633665 // Otherwise, add callsite metadata. If we reach here then we found the
634666 // instruction's leaf location in the callsites map and not the allocation
635667 // map.
636- for (const auto &CallSiteEntry : CallSitesIter->second ) {
637- // If we found and thus matched all frames on the call, create and
638- // attach call stack metadata.
639- if (stackFrameIncludesInlinedCallStack (CallSiteEntry.Frames ,
640- InlinedCallStack)) {
641- NumOfMemProfMatchedCallSites++;
642- addCallsiteMetadata (I, InlinedCallStack, Ctx);
643-
644- // Try to attach indirect call metadata if possible.
645- if (!CalledFunction)
646- addVPMetadata (M, I, CallSiteEntry.CalleeGuids );
647-
648- // Only need to find one with a matching call stack and add a single
649- // callsite metadata.
650-
651- // Accumulate call site matching information upon request.
652- if (ClPrintMemProfMatchInfo) {
653- std::vector<uint64_t > CallStack;
654- append_range (CallStack, InlinedCallStack);
655- MatchedCallSites.insert (std::move (CallStack));
656- }
657- break ;
658- }
659- }
668+ handleCallSite (I, CalledFunction, InlinedCallStack, CallSitesIter->second ,
669+ M, MatchedCallSites);
660670 }
661671 }
662672}
0 commit comments