This is an archive of the discontinued LLVM Phabricator instance.

[ProfileData] Read and symbolize raw memprof profiles.
ClosedPublic

Authored by snehasish on Jan 6 2022, 5:44 PM.

Details

Summary

This change extends the RawMemProfReader to read all the sections of the
raw profile and symbolize the virtual addresses recorded as part of the
callstack for each allocation. For now the symbolization is used to
display the contents of the profile with llvm-profdata.

Diff Detail

Event Timeline

snehasish created this revision.Jan 6 2022, 5:44 PM
snehasish requested review of this revision.Jan 6 2022, 5:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 6 2022, 5:44 PM
snehasish updated this revision to Diff 398244.Jan 7 2022, 2:39 PM

Rebase on parent changes.

tejohnson added inline comments.Jan 10 2022, 10:41 AM
llvm/include/llvm/ProfileData/MemProf.h
28

Can you elaborate on this and what will change?

llvm/include/llvm/ProfileData/RawMemProfReader.h
82

Where is this defined/called?

97

Suggest comment on what is the map key (the uint64_t).

101

Nit: there are a bunch of locals also named "Next" in various methods. For clarity suggest renaming this to something more unique.

llvm/lib/ProfileData/RawMemProfReader.cpp
183

Why IsText = true for the raw file? Not sure of the implications.

328

What is the implication of "UndefSection"?

llvm/test/tools/llvm-profdata/memprof-basic.test
34

I assume basic.memprofexe == rawprofile.out from above?

llvm/test/tools/llvm-profdata/memprof-multi.test
36

multi.memprofexe == rawprofile.out?

davidxl added inline comments.Jan 10 2022, 3:53 PM
llvm/include/llvm/ProfileData/MemProf.h
43

To handle deep stacks, perhaps make one line per frame (with indentation to show level)?

51

This TODO needs more explanation.

llvm/include/llvm/ProfileData/RawMemProfReader.h
33

Document key and value in the map?

llvm/lib/ProfileData/RawMemProfReader.cpp
92

document the method.

llvm/test/tools/llvm-profdata/memprof-basic.test
47

Is this line correct? where is the source file to validate?

65

unit of the time?

68

is cpuid this big?

snehasish updated this revision to Diff 399798.Jan 13 2022, 2:43 PM

Rebase on changes, update the YAML output from snake case to LLVM variable naming style.

snehasish updated this revision to Diff 399824.Jan 13 2022, 4:14 PM
snehasish marked 5 inline comments as done.

Address comments.

PTAL, thanks!

llvm/include/llvm/ProfileData/MemProf.h
28

I shared D117256 which has the implementation referred to in this TODO. I've added a wrapper around the MemInfoBlock. This wrapper makes it easy to read a prior version of a MemInfoBlock from binary data when the schema is provided. It allows us to specify on a per field basis what to write to (or read from) an indexed profile. PTAL, thanks!

43

That's a neat idea, I found out that YAML supports flow style (like JSON) so I can put Function, LineOffset, Column and Inline on the same line. I've put in a TODO for now since the YAML format is only used in tests (max stack depth = 3) and I don't have a unittest to verify the validity of the YAML we generate.

51

In D117256 I replaced this print with a call to the printYAML method of the MemInfoBlock wrapper (PortableMemInfoBlock). There I used a macro based generation of code for what fields need to be printed out. Let me know if you want me to clarify further or any other changes in this patch.

llvm/include/llvm/ProfileData/RawMemProfReader.h
82

Removed, leftover from code I deleted.

101

Good idea, renamed to Iter (and renamed a local which was Iter to I).

llvm/lib/ProfileData/RawMemProfReader.cpp
183

Good catch, this param controls whether line endings are detected when the file is read [1]. Since we are working with binary files it doesn't seem to have any impact though. Updated to remove the param to default to false.

[1] https://github.com/llvm/llvm-project/blob/345223a7be3c3c93a10f8453d96287a3a03b6754/llvm/lib/Support/MemoryBuffer.cpp#L254

328

It instructs the lookup to use absolute addresses. I believe the line table lookup happens here [1]. I also noticed that the default constructor for SectionedAddress sets it to UndefSection by default so I removed the second param here.

[1] https://github.com/llvm/llvm-project/blob/ee02cf0797712bb3a4b0686f185794fcb0fd3d9e/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp#L1248

llvm/test/tools/llvm-profdata/memprof-basic.test
34

Also updated the multi test.

47

The callstack contains frames from the user code (provided at the top of this file), the compiler runtime interceptors and/or shared libraries. I can confirm that the line numbers are correct for all locations which are symbolized from the main binary i.e user program and compiler runtime linked in statically. Some locations below have line and column set to 0 which are from shared libs. Let me know if there is anything I can change to make this clearer.

65

The timestamp should be ms. Let me look into this a bit more.

68

It shouldn't be, this is 2^32-1 so let me check whats going on here.

tejohnson added inline comments.Jan 16 2022, 7:11 AM
llvm/lib/ProfileData/RawMemProfReader.cpp
183

I see the second param removed only for the call to getFileOrSTDIN in create(), not here in hasFormat().

llvm/test/tools/llvm-profdata/memprof-basic.test
61

Do these lines need to be updated to reflect D117256?

65

The runtime reports the lifetimes in ms

snehasish updated this revision to Diff 401406.Jan 19 2022, 2:30 PM

Update the YAML test with LLVM var style tags.
Address comments.

snehasish marked 2 inline comments as done.Jan 19 2022, 3:15 PM

PTAL, thanks!

llvm/test/tools/llvm-profdata/memprof-basic.test
68

The cpuid is unavailable since the allocation we captured occurs when memprof has not been fully initialized [1].

[1] https://github.com/llvm/llvm-project/blob/c7b71acef2685ca59830b5b59c6214b6dac474a2/compiler-rt/lib/memprof/memprof_allocator.cpp#L45

Are you planning to rebase this on top of D117256?

Are you planning to rebase this on top of D117256?

I was not planning on doing so. The changes which succeed this one evolve the MemInfoBlock data structure and aren't necessary to make this work. They are needed for the next patch which adds MemProfRecords to the indexed format. Do you see a particular advantage in having it the other way around?

tejohnson accepted this revision.Jan 20 2022, 11:07 AM

Are you planning to rebase this on top of D117256?

I was not planning on doing so. The changes which succeed this one evolve the MemInfoBlock data structure and aren't necessary to make this work. They are needed for the next patch which adds MemProfRecords to the indexed format. Do you see a particular advantage in having it the other way around?

Ah, I messed up the stack ordering of the patches. This seems fine. LGTM but please wait to see if @davidxl has any follow on comments.

This revision is now accepted and ready to land.Jan 20 2022, 11:07 AM
This revision was automatically updated to reflect the committed changes.
thakis added a subscriber: thakis.Feb 3 2022, 3:29 PM
thakis added inline comments.
llvm/lib/ProfileData/CMakeLists.txt
21

Object is already present 3 lines further down. Maybe alphabetize this list and remove the dupe :)

thakis added inline comments.Feb 3 2022, 3:40 PM
llvm/lib/ProfileData/CMakeLists.txt
25

This dependency is a problem. At the moment, Symbolize adds a dep to libcurl, and clang transitiviely depends on llvm/lib/ProfileData. So this makes clang depend on libcurl (even in statically linked builds), which is something we want to avoid. See also the discussion on D113717 (in particular, https://reviews.llvm.org/D113717#3295350).

Since this likely has no super quick fix, would you mind reverting this until that dependency can be prevented somehow?

snehasish added inline comments.Feb 3 2022, 3:54 PM
llvm/lib/ProfileData/CMakeLists.txt
21

I sorted and deduped this list but that broke the clang ppc buildbot so I reverted the change.

https://reviews.llvm.org/rG55de669660cb1523cf83c98e8c0cb133ec279383

25

I assume you mean this patch and not the sort/dedupe suggestion above. Reading through the discussion then we would have to wait for a refactoring to move the libcurl dep to llvm-symbolize instead of debuginfod. Is it possible to split debuginfod out of Symbolize so that we can unblock this patch sooner?

thakis added inline comments.Feb 3 2022, 3:59 PM
llvm/lib/ProfileData/CMakeLists.txt
25

From what I understand, that refactoring should be fairly small (make Symbolize take a default-noop "FetchSymbols" callback instead of calling Debuginfod directly, change llvm-symbolize to pass in a function that calls Debuginfod instead, remove dep from Symbolize on Debuginfod. For bonus points, tweak the cmake setup so that Debuginfod isn't linked into libllvm by default, but that's not needed for your use case here). I can't think of a much smaller change to unblock things.