aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/InstrProfReader.cpp
AgeCommit message (Collapse)AuthorFilesLines
11 days[Support] Deprecate one form of support::endian::byte_swap (NFC) (#161045)Kazu Hirata1-5/+5
This is a follow-up to #156140 and #160979, which deprecated one form of write and read, respectively. We have two forms of byte_swap: template <typename value_type> [[nodiscard]] inline value_type byte_swap(value_type value, endianness endian) template <typename value_type, endianness endian> [[nodiscard]] inline value_type byte_swap(value_type value) The difference is that endian is a function parameter in the former but a template parameter in the latter. This patch streamlines the code by migrating the use of the latter to the former while deprecating the latter because the latter is just forwarded to the former.
12 days[Support] Deprecate one form of support::endian::read (NFC) (#160979)Kazu Hirata1-4/+4
This is a follow-up to #156140, which deprecated one form of write. We have two forms of read: template <typename value_type, std::size_t alignment> [[nodiscard]] inline value_type read(const void *memory, endianness endian) template <typename value_type, endianness endian, std::size_t alignment> [[nodiscard]] inline value_type read(const void *memory) The difference is that endian is a function parameter in the former but a template parameter in the latter. This patch streamlines the code by migrating the use of the latter to the former while deprecating the latter.
2025-07-24[ProfileData] Remove an unnecessary cast (NFC) (#150472)Kazu Hirata1-1/+1
getBufferEnd() already returns const char *.
2025-06-24[InstrProf] Factor out getRecord() and use NamedInstrProfRecord (#145417)Ellis Hoag1-3/+3
Factor out code in `populateCounters()` and `populateCoverage()` used to grab the record into `PGOUseFunc::getRecord()` to reduce code duplication. And return `NamedInstrProfRecord` in `getInstrProfRecord()` to avoid an unnecessary cast. No functional change is intented.
2025-05-24Re-apply "[StaticDataLayout][PGO]Implement reader and writer change for data ↵Mingming Liu1-0/+14
access profiles" (#141275) Re-apply https://github.com/llvm/llvm-project/pull/139997 after fixing the use-of-uninitialized-memory error (https://lab.llvm.org/buildbot/#/builders/94/builds/7373). Tested: The error is reproduced with https://github.com/llvm/llvm-zorg/blob/main/zorg/buildbot/builders/sanitizers/buildbot_bootstrap_msan.sh without the fix, and test pass with the fix. **Original commit message:** https://github.com/llvm/llvm-project/pull/138170 introduces classes to operate on data access profiles. This change supports the read and write of `DataAccessProfData` in indexed format of MemProf (v4) as well as its the text (yaml) format. For indexed format: * InstrProfWriter owns (by `std::unique_ptr<DataAccessProfData>`) the data access profiles, and gives a non-owned copy when it calls `writeMemProf`. * MemProf v4 header has a new `uint64_t` to record the byte offset of data access profiles. This `uint64_t` field is zero if data access profile is not set (nullptr). * MemProfReader reads the offset from v4 header and de-serializes in-memory bytes into class `DataAccessProfData`. For textual format: * MemProfYAML.h adds the mapping for DAP class, and make DAP optional for both read and write. 099a0fa (by @snehasish) introduces v4 which contains CalleeGuids in CallSiteInfo, and this change changes the v4 format in place with data access profiles. The current plan is to bump the version and enable v4 profiles with both features, assuming waiting for this change won't delay the callsite change too long. --------- Co-authored-by: Kazu Hirata <kazu@google.com>
2025-05-22Revert "[StaticDataLayout][PGO]Implement reader and writer change for data ↵Mingming Liu1-14/+0
access profiles" (#141157) Reverts llvm/llvm-project#139997 Sanitizer failures (https://lab.llvm.org/buildbot/#/builders/94/builds/7373) Will fix forward later.
2025-05-22[StaticDataLayout][PGO]Implement reader and writer change for data access ↵Mingming Liu1-0/+14
profiles (#139997) https://github.com/llvm/llvm-project/pull/138170 introduces classes to operate on data access profiles. This change supports the read and write of `DataAccessProfData` in indexed format of MemProf (v4) as well as its the text (yaml) format. For indexed format: * InstrProfWriter owns (by `std::unique_ptr<DataAccessProfData>`) the data access profiles, and gives a non-owned copy when it calls `writeMemProf`. * MemProf v4 header has a new `uint64_t` to record the byte offset of data access profiles. This `uint64_t` field is zero if data access profile is not set (nullptr). * MemProfReader reads the offset from v4 header and de-serializes in-memory bytes into class `DataAccessProfData`. For textual format: * MemProfYAML.h adds the mapping for DAP class, and make DAP optional for both read and write. 099a0fa (by @snehasish) introduces v4 which contains CalleeGuids in CallSiteInfo, and this change changes the v4 format in place with data access profiles. The current plan is to bump the version and enable v4 profiles with both features, assuming waiting for this change won't delay the callsite change too long. --------- Co-authored-by: Kazu Hirata <kazu@google.com>
2025-05-20Revert "[llvm][NFC] Use `llvm::sort()`" (#140668)Iris Shi1-1/+1
2025-05-19[NFC][MemProf] Move Radix tree methods to their own header and cpp. (#140501)Snehasish Kumar1-1/+2
Part of a larger refactoring with the following goals 1. Reduce the size of MemProf.h 2. Avoid including ModuleSummaryIndex just for a couple of types
2025-05-17[llvm][NFC] Use `llvm::sort()` (#140335)Iris Shi1-1/+1
2025-05-01[MemProf] Add v4 which contains CalleeGuids to CallSiteInfo. (#137394)Snehasish Kumar1-12/+9
This patch adds CalleeGuids to the serialized format and increments the version number to 4. The unit tests are updated to include a new test for v4 and the YAML format is also updated to be able to roundtrip the v4 format.
2025-04-23[memprof] Move IndexedMemProfReader::deserialize to IndexedemProfData.cpp ↵Kazu Hirata1-123/+0
(NFC) (#137089) This patch moves IndexedMemProfReader::deserialize and its subroutines to IndexedMemProfData.cpp, building on: commit 9a8f90dba3f8c25cbb3525a482053d3abcd3fddc Author: Kazu Hirata <kazu@google.com> Date: Wed Apr 23 15:39:45 2025 -0700 The intent is as follows: - Reduce the size of InstrProfReader.cpp. - Move the subroutines to a separate file because they don't interact with anything else in InstrProfReader.cpp.
2025-04-16[llvm] Use llvm::append_range (NFC) (#135931)Kazu Hirata1-1/+1
2024-12-07[memprof] Add YAML read/write support to llvm-profdata (#118915)Kazu Hirata1-0/+16
This patch adds YAML read/write support to llvm-profdata. The primary intent is to accommodate MemProf profiles in test cases, thereby avoiding the binary format. The read support is via llvm-profdata merge. This is useful when we want to verify that the compiler does the right thing on a given .ll file and a MemProf profile in a test case. In the test case, we would convert the MemProf profile in YAML to an indexed profile and invoke the compiler on the .ll file along with the indexed profile. The write support is via llvm-profdata show --memory. This is useful when we wish to convert an indexed MemProf profile to YAML while writing tests. We would compile a test case in C++, run it for an indexed MemProf profile, and then convert it to the text format.
2024-12-04[PGO] Add option to always instrumenting loop entries (#116789)ronryvchin1-0/+5
This patch extends the PGO infrastructure with an option to prefer the instrumentation of loop entry blocks. This option is a generalization of https://github.com/llvm/llvm-project/commit/19fb5b467bb97f95eace1f3637d2d1041cebd3ce, and helps to cover cases where the loop exit is never executed. An example where this can occur are event handling loops. Note that change does NOT change the default behavior.
2024-11-22[memprof] Fix builds under EXPENSIVE_CHECKSKazu Hirata1-12/+0
memprof::Version1 has been removed, so the whole block of code is dead.
2024-11-22[memprof] Remove MemProf format Version 1 (#117357)Kazu Hirata1-30/+4
This patch removes MemProf format Version 1 now that Version 2 and 3 are working well.
2024-11-19[ProfileData] Remove unused includes (NFC) (#116751)Kazu Hirata1-1/+0
Identified with misc-include-cleaner.
2024-11-15[memprof] Remove MemProf format Version 0 (#116442)Kazu Hirata1-18/+5
This patch removes MemProf format Version 0 now that version 2 and 3 seem to be working well. I'm not touching version 1 for now because some tests still rely on version 1. Note that Version 0 is identical to Version 1 except that the MemProf section of the indexed format has a MemProf version field.
2024-11-15[memprof] Speed up caller-callee pair extraction (Part 2) (#116441)Kazu Hirata1-1/+2
This patch further speeds up the extraction of caller-callee pairs from the profile. Recall that we reconstruct a call stack by traversing the radix tree from one of its leaf nodes toward a root. The implication is that when we decode many different call stacks, we end up visiting nodes near the root(s) repeatedly. That in turn adds many duplicates to our data structure: DenseMap<uint64_t, SmallVector<CallEdgeTy, 0>> Calls; only to be deduplicated later with sort+unique for each vector. This patch makes the extraction process more efficient by keeping track of indices of the radix tree array we've visited so far and terminating traversal as soon as we encounter an element previously visited. Note that even with this improvement, we still add at least one caller-callee pair to the data structure above for each call stack because we do need to add a caller-callee pair for the leaf node with the callee GUID being 0. Without this patch, it takes 4 seconds to extract caller-callee pairs from a large MemProf profile. This patch shortenes that down to 900ms.
2024-11-15[memprof] Use llvm::function_ref instead of std::function (#116306)Kazu Hirata1-1/+2
We've seen bugs where we lost track of error states stored in the functor because we passed the functor by value (that is, std::function) as opposed to reference (llvm::function_ref). This patch fixes a couple of places we pass functors by value. While we are at it, this patch adds curly braces around a "for" loop spanning multiple lines.
2024-11-14[memprof] Speed up caller-callee pair extraction (#116184)Kazu Hirata1-1/+18
We know that the MemProf profile has a lot of duplicate call stacks. Extracting caller-callee pairs from a call stack we've seen before is a wasteful effort. This patch makes the extraction more efficient by first coming up with a work list of linear call stack IDs -- the set of starting positions in the radix tree array -- and then extract caller-callee pairs from each call stack in the work list. We implement the work list as a bit vector because we expect the work list to be dense in the range [0, RadixTreeSize). Also, we want the set insertion to be cheap. Without this patch, it takes 25 seconds to extract caller-callee pairs from a large MemProf profile. This patch shortenes that down to 4 seconds.
2024-11-13[memprof] Add IndexedMemProfReader::getMemProfCallerCalleePairs (#115807)Kazu Hirata1-0/+26
Undrifting the MemProf profile requires two sets of information: - caller-callee pairs from the profile - callee-callee pairs from the IR This patch adds a function to do the former. The latter has been addressed by extractCallsFromIR. Unfortunately, the current MemProf format does not directly give us the caller-callee pairs from the profile. "struct Frame" just tells us where the call site is -- Caller GUID and line/column numbers; it doesn't tell us what function a given Frame is calling. To extract caller-callee pairs, we need to scan each call stack, look at two adjacent Frames, and extract a caller-callee pair. Conceptually, we would extract caller-callee pairs with: for each MemProfRecord in the profile: for each call stack in AllocSites: extract caller-callee pairs from adjacent pairs of Frames However, this is highly inefficient. Obtaining MemProfRecord involves looking up the OnDiskHashTable, allocating several vectors on the heap, and populating fields that are irrelevant to us, such as MIB and CallSites. This patch adds an efficient way of doing the above. Specifically, we - go though all IndexedMemProfRecords, - look at each linear call stack ID - extract caller-callee pairs from each call stack The extraction is done by a new class CallerCalleePairExtractor, modified from LinearCallStackIdConverter, which reconstructs a call stack from the radix tree array. For our purposes, we skip the reconstruction and immediately populates the data structure for caller-callee pairs. The resulting caller-callee-pairs is of the type: DenseMap<uint64_t, SmallVector<CallEdgeTy, 0>> CallerCalleePairs; which can be passed directly to longestCommonSequence just like the result of extractCallsFromIR. Further performance optimizations are possible for the new functions in this patch. I'll address those in follow-up patches.
2024-09-06[InstrProf] Add debuginfod correlation support (#106606)gulfemsavrun1-11/+39
This patch adds debuginfod support into llvm-profdata to find the assosicated executable by a build id in a raw profile to correlate a profile with a provided correlation kind (debug-info or binary).
2024-07-11[ProfileData] Take ArrayRef<InstrProfValueData> in addValueData (NFC) (#97363)Kazu Hirata1-2/+2
This patch fixes another place in ProfileData where we have a pointer to an array of InstrProfValueData and its length separately. addValueData is a bit unique in that it remaps incoming values in place before adding them to ValueSites. AFAICT, no caller of addValueData uses updated incoming values. With this patch, we add value data to ValueSites first and then remaps values there. This way, we can take ArrayRef<InstrProfValueData> as a parameter.
2024-07-09[NFC] Coding style: drop `k` in `kGlobalIdentifierDelimiter` (#98230)Mircea Trofin1-1/+1
2024-06-25Revert "[llvm] Use llvm::sort (NFC) (#96434)"Kazu Hirata1-1/+1
This reverts commit 05d167fc201b4f2e96108be0d682f6800a70c23d. Reverting the patch fixes the following under EXPENSIVE_CHECKS: LLVM :: CodeGen/AMDGPU/sched-group-barrier-pipeline-solver.mir LLVM :: CodeGen/AMDGPU/sched-group-barrier-pre-RA.mir LLVM :: CodeGen/PowerPC/aix-xcoff-used-with-stringpool.ll LLVM :: CodeGen/PowerPC/merge-string-used-by-metadata.mir LLVM :: CodeGen/PowerPC/mergeable-string-pool-large.ll LLVM :: CodeGen/PowerPC/mergeable-string-pool-pass-only.mir LLVM :: CodeGen/PowerPC/mergeable-string-pool.ll
2024-06-23[llvm] Use llvm::sort (NFC) (#96434)Kazu Hirata1-1/+1
2024-06-09[ProfileData] Refactor BinaryIdsStart and BinaryIdsSize (NFC) (#94922)Kazu Hirata1-11/+13
BinaryIdsStart and BinaryIdsSize in IndexedInstrProfReader are always used together, so this patch packages them into an ArrayRef<uint8_t>. For now, readBinaryIdsInternal immediately unpacks ArrayRef into its constituents to avoid touching the rest of readBinaryIdsInternal.
2024-06-09[ProfileData] Refactor VTableNamePtr and CompressedVTableNamesLen (NFC) (#94859)Kazu Hirata1-4/+5
VTableNamePtr and CompressedVTableNamesLen are always used together to create a StringRef in getSymtab. We can create the StringRef ahead of time in readHeader. This way, IndexedInstrProfReader becomes a tiny bit simpler with fewer member variables. Also, StringRef default-constructs itself with its Data and Length set to nullptr and 0, respectively, which is exactly what we need.
2024-06-09[ProfileData] Use ArrayRef instead of const std::vector<T> & (NFC) (#94878)Kazu Hirata1-4/+3
2024-06-08[ProfileData] Simplify calls to readNext in readBinaryIdsInternal (NFC) (#94862)Kazu Hirata1-6/+1
readNext has two variants: - readNext<uint64_t, endian>(ptr) - readNext<uint64_t>(ptr, endian) This patch uses the latter to simplify readBinaryIdsInternal. Both forms default to unaligned.
2024-06-08[ProfileData] Use a range-based for loop (NFC) (#94856)Kazu Hirata1-4/+4
While I am at it, this patch adds const to a couple of places.
2024-06-07[memprof] Clean up IndexedMemProfReader (NFC) (#94710)Kazu Hirata1-7/+5
Parameter "Version" is confusing in deserializeV012 and deserializeV3 because we also have member variable "Version". Fortunately, parameter "Version" and member variable "Version" always have the same value because IndexedMemProfReader::deserialize initializes the member variable and passes it to deserializeV012 and deserializeV3. This patch removes the parameter.
2024-06-02[memprof] Use const ref for IndexedRecord (#94114)Kazu Hirata1-1/+1
The type of *Iter here is "const IndexedMemProfRecord &" as defined in RecordLookupTrait. Assigning *Iter to a variable of type "const IndexedMemProfRecord &" avoids a copy, reducing the cycle and instruction counts by 1.8% and 0.2%, respectively, with "llvm-profdata show" modified to deserialize all MemProfRecords. Note that RecordLookupTrait has an internal copy of IndexedMemProfRecord, so we don't have to worry about a dangling reference to a temporary.
2024-05-30[memprof] Use linear IDs for Frames and call stacks (#93740)Kazu Hirata1-17/+19
With this patch, we stop using on-disk hash tables for Frames and call stacks. Instead, we'll write out all the Frames as a flat array while maintaining mappings from FrameIds to the indexes into the array. Then we serialize call stacks in terms of those indexes. Likewise, we'll write out all the call stacks as another flat array while maintaining mappings from CallStackIds to the indexes into the call stack array. One minor difference from Frames is that the indexes into the call stack array are not contiguous because call stacks are variable-length objects. Then we serialize IndexedMemProfRecords in terms of the indexes into the call stack array. Now, we describe each call stack with 32-bit indexes into the Frame array (as opposed to the 64-bit FrameIds in Version 2). The use of the smaller type cuts down the profile file size by about 40% relative to Version 2. The departure from the on-disk hash tables contributes a little bit to the savings, too. For now, IndexedMemProfRecords refer to call stacks with 64-bit indexes into the call stack array. As a follow-up, I'll change that to uint32_t, including necessary updates to RecordWriterTrait.
2024-05-29[memprof] Reorder MemProf sections in profile (#93640)Kazu Hirata1-29/+95
This patch teaches the V3 format to serialize Frames, call stacks, and IndexedMemProfRecords, in that order. I'm planning to use linear IDs for Frames. That is, Frames will be numbered 0, 1, 2, and so on in the order we serialize them. In turn, we will seialize the call stacks in terms of those linear IDs. Likewise, I'm planning to use linear IDs for call stacks and then serialize IndexedMemProfRecords in terms of those linear IDs for call stacks. With the new order, we can successively free data structures as we serialize them. That is, once we serialize Frames, we can free the Frames' data proper and just retain mappings from FrameIds to linear IDs. A similar story applies to call stacks.
2024-05-29[nfc][InstrFDO] Add Header::getIndexedProfileVersion and use it to decide ↵Mingming Liu1-4/+4
profile version. (#93613) This is a split of https://github.com/llvm/llvm-project/pull/93346 as discussed.
2024-05-28[memprof] Add MemProf format Version 3 (#93608)Kazu Hirata1-1/+3
This patch adds Version 3 for development purposes. For now, this patch adds V3 as a copy of V2. For the most part, this patch adds "case Version3:" wherever "case Version2:" appears. One exception is writeMemProfV3, which is copied from writeMemProfV2 but updated to write out memprof::Version3 to the MemProf header. We'll incrementally modify writeMemProfV3 in subsequent patches.
2024-05-23[memprof] Refactor getMemProfRecord (NFC) (#93138)Kazu Hirata1-33/+67
This patch refactors getMemProfRecord for readability while adding consistency checks. - This patch adds a switch statement on the MemProf version just like most places dealing with MemProf serialization/deserialization. - This patch adds asserts to ensure that the exact set of data structures are available while ones we do not use are not present. That is, getMemProfRecord no longer determines the version based on the availability of MemProfCallStackTable.
2024-05-21[nfc][InstrProfReader]Store header fields in native endianness (#92947)Mingming Liu1-33/+17
- Use `Header.Version` directly and remove Header::formatVersion --------- Co-authored-by: Kazu Hirata <kazu@google.com>
2024-04-28Repply [memprof] Introduce FrameIdConverter and CallStackIdConverter (#90307)Kazu Hirata1-39/+23
Currently, we convert FrameId to Frame and CallStackId to a call stack at several places. This patch unifies those into function objects -- FrameIdConverter and CallStackIdConverter. The existing implementation of CallStackIdConverter, being removed in this patch, handles both FrameId and CallStackId conversions. This patch splits it into two phases for flexibility (but make them composable) because some places only require the FrameId conversion. This iteration fixes a problem uncovered with ubsan, where we were dereferencing an uninitialized std::unique_ptr.
2024-04-27Revert "[memprof] Introduce FrameIdConverter and CallStackIdConverter" (#90318)Vitaly Buka1-13/+31
Reverts llvm/llvm-project#90307 Breaks bots https://lab.llvm.org/buildbot/#/builders/5/builds/42943
2024-04-26[memprof] Introduce FrameIdConverter and CallStackIdConverter (#90307)Kazu Hirata1-31/+13
Currently, we convert FrameId to Frame and CallStackId to a call stack at several places. This patch unifies those into function objects -- FrameIdConverter and CallStackIdConverter. The existing implementation of CallStackIdConverter, being removed in this patch, handles both FrameId and CallStackId conversions. This patch splits it into two phases for flexibility (but make them composable) because some places only require the FrameId conversion.
2024-04-19[memprof] Drop the trait parameter (NFC) (#89461)Kazu Hirata1-2/+2
OnDiskIterableChainedHashTable::Create can default-contruct a trait object for us. We don't need to construct one on our own unless we need to customize something (like a version number).
2024-04-18[memprof] Introduce IndexedMemProfReader (NFC) (#89331)Kazu Hirata1-90/+96
Without this patch, a lot of details about the deserilization of the MemProf data are exposed in IndexedInstrProfReader -- four MemProf-related variables in IndexedInstrProfReader plus 90+ lines of deserilization code within IndexedInstrProfReader::readHeader. This patch encapsulates them into a separate class, exposing only three methods, namely the default constructor, deserialize, and getMemProfRecord.
2024-04-18[memprof] Add Version2 of the indexed MemProf format (#89100)Kazu Hirata1-7/+59
This patch adds Version2 of the indexed MemProf format. The new format comes with a hash table from CallStackId to actual call stacks llvm::SmallVector<FrameId>. The rest of the format refers to call stacks with CallStackId. This "values + references" model effectively deduplicates call stacks. Without this patch, a large indexed memprof file of mine shrinks from 4.4GB to 1.6GB, a 64% reduction. This patch does not make Version2 generally available yet as I am planning to make a few more changes to the format.
2024-04-16[llvm] Drop unaligned from calls to readNext (NFC) (#88841)Kazu Hirata1-34/+19
Now readNext defaults to unaligned accesses. This patch drops unaligned to improve readability.
2024-04-11[memprof] Use std::optional (NFC) (#88366)Kazu Hirata1-5/+4
2024-04-03[memprof] Add Version2 of IndexedMemProfRecord serialization (#87455)Kazu Hirata1-1/+1
I'm currently developing a new version of the indexed memprof format where we deduplicate call stacks in IndexedAllocationInfo::CallStack and IndexedMemProfRecord::CallSites. We refer to call stacks with integer IDs, namely CallStackId, just as we refer to Frame with FrameId. The deduplication will cut down the profile file size by 80% in a large memprof file of mine. As a step toward the goal, this patch teaches IndexedMemProfRecord::{serialize,deserialize} to speak Version2. A subsequent patch will add Version2 support to llvm-profdata. The essense of the patch is to replace the serialization of a call stack, a vector of FrameIDs, with that of a CallStackId. That is: const IndexedAllocationInfo &N = ...; ... LE.write<uint64_t>(N.CallStack.size()); for (const FrameId &Id : N.CallStack) LE.write<FrameId>(Id); becomes: LE.write<CallStackId>(N.CSId);