-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[memprof] Introduce handleCallSite (NFC) #149724
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[memprof] Introduce handleCallSite (NFC) #149724
Conversation
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.
@llvm/pr-subscribers-llvm-transforms Author: Kazu Hirata (kazutakahirata) ChangesContinuing the effort to refactor readMemProf, this patch introduces Moving the code requires taking CallSiteEntry and CallSiteEntryHash We could simplify some code, but I'm keeping this patch very simple to Full diff: https://github.com/llvm/llvm-project/pull/149724.diff 1 Files Affected:
diff --git a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
index 2a8416d02ffba..6e57b99c3233f 100644
--- a/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemProfUse.cpp
@@ -429,6 +429,63 @@ handleAllocSite(Instruction &I, CallBase *CI,
}
}
+// Helper struct for maintaining refs to callsite data. As an alternative we
+// could store a pointer to the CallSiteInfo struct but we also need the frame
+// index. Using ArrayRefs instead makes it a little easier to read.
+struct CallSiteEntry {
+ // Subset of frames for the corresponding CallSiteInfo.
+ ArrayRef<Frame> Frames;
+ // Potential targets for indirect calls.
+ ArrayRef<GlobalValue::GUID> CalleeGuids;
+
+ // Only compare Frame contents.
+ // Use pointer-based equality instead of ArrayRef's operator== which does
+ // element-wise comparison. We want to check if it's the same slice of the
+ // underlying array, not just equivalent content.
+ bool operator==(const CallSiteEntry &Other) const {
+ return Frames.data() == Other.Frames.data() &&
+ Frames.size() == Other.Frames.size();
+ }
+};
+
+struct CallSiteEntryHash {
+ size_t operator()(const CallSiteEntry &Entry) const {
+ return computeFullStackId(Entry.Frames);
+ }
+};
+
+static void handleCallSite(
+ Instruction &I, const Function *CalledFunction,
+ ArrayRef<uint64_t> InlinedCallStack,
+ const std::unordered_set<CallSiteEntry, CallSiteEntryHash> &CallSiteEntries,
+ Module &M, std::set<std::vector<uint64_t>> &MatchedCallSites) {
+ auto &Ctx = M.getContext();
+ for (const auto &CallSiteEntry : CallSiteEntries) {
+ // If we found and thus matched all frames on the call, create and
+ // attach call stack metadata.
+ if (stackFrameIncludesInlinedCallStack(CallSiteEntry.Frames,
+ InlinedCallStack)) {
+ NumOfMemProfMatchedCallSites++;
+ addCallsiteMetadata(I, InlinedCallStack, Ctx);
+
+ // Try to attach indirect call metadata if possible.
+ if (!CalledFunction)
+ addVPMetadata(M, I, CallSiteEntry.CalleeGuids);
+
+ // Only need to find one with a matching call stack and add a single
+ // callsite metadata.
+
+ // Accumulate call site matching information upon request.
+ if (ClPrintMemProfMatchInfo) {
+ std::vector<uint64_t> CallStack;
+ append_range(CallStack, InlinedCallStack);
+ MatchedCallSites.insert(std::move(CallStack));
+ }
+ break;
+ }
+ }
+}
+
static void readMemprof(Module &M, Function &F,
IndexedInstrProfReader *MemProfReader,
const TargetLibraryInfo &TLI,
@@ -499,31 +556,6 @@ static void readMemprof(Module &M, Function &F,
// (allocation info and the callsites).
std::map<uint64_t, std::set<const AllocationInfo *>> LocHashToAllocInfo;
- // Helper struct for maintaining refs to callsite data. As an alternative we
- // could store a pointer to the CallSiteInfo struct but we also need the frame
- // index. Using ArrayRefs instead makes it a little easier to read.
- struct CallSiteEntry {
- // Subset of frames for the corresponding CallSiteInfo.
- ArrayRef<Frame> Frames;
- // Potential targets for indirect calls.
- ArrayRef<GlobalValue::GUID> CalleeGuids;
-
- // Only compare Frame contents.
- // Use pointer-based equality instead of ArrayRef's operator== which does
- // element-wise comparison. We want to check if it's the same slice of the
- // underlying array, not just equivalent content.
- bool operator==(const CallSiteEntry &Other) const {
- return Frames.data() == Other.Frames.data() &&
- Frames.size() == Other.Frames.size();
- }
- };
-
- struct CallSiteEntryHash {
- size_t operator()(const CallSiteEntry &Entry) const {
- return computeFullStackId(Entry.Frames);
- }
- };
-
// For the callsites we need to record slices of the frame array (see comments
// below where the map entries are added) along with their CalleeGuids.
std::map<uint64_t, std::unordered_set<CallSiteEntry, CallSiteEntryHash>>
@@ -633,30 +665,8 @@ static void readMemprof(Module &M, Function &F,
// Otherwise, add callsite metadata. If we reach here then we found the
// instruction's leaf location in the callsites map and not the allocation
// map.
- for (const auto &CallSiteEntry : CallSitesIter->second) {
- // If we found and thus matched all frames on the call, create and
- // attach call stack metadata.
- if (stackFrameIncludesInlinedCallStack(CallSiteEntry.Frames,
- InlinedCallStack)) {
- NumOfMemProfMatchedCallSites++;
- addCallsiteMetadata(I, InlinedCallStack, Ctx);
-
- // Try to attach indirect call metadata if possible.
- if (!CalledFunction)
- addVPMetadata(M, I, CallSiteEntry.CalleeGuids);
-
- // Only need to find one with a matching call stack and add a single
- // callsite metadata.
-
- // Accumulate call site matching information upon request.
- if (ClPrintMemProfMatchInfo) {
- std::vector<uint64_t> CallStack;
- append_range(CallStack, InlinedCallStack);
- MatchedCallSites.insert(std::move(CallStack));
- }
- break;
- }
- }
+ handleCallSite(I, CalledFunction, InlinedCallStack, CallSitesIter->second,
+ M, MatchedCallSites);
}
}
}
|
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.
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.