Skip to content

Commit 507ff29

Browse files
[memprof] Introduce handleCallSite (NFC) (#149724)
Continuing the effort to refactor readMemProf, this patch introduces handlCallSite to handle, well, call sites. Moving the code requires taking CallSiteEntry and CallSiteEntryHash out of readMemProf. We could simplify some code, but I'm keeping this patch very simple to facilitate the review process. For example, we could simplify the control flow near the end of readMemProf, but we can address that later.
1 parent f3a3270 commit 507ff29

File tree

1 file changed

+59
-49
lines changed

1 file changed

+59
-49
lines changed

llvm/lib/Transforms/Instrumentation/MemProfUse.cpp

Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
432489
static 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

Comments
 (0)