This is an archive of the discontinued LLVM Phabricator instance.

[profile] Create only prof header when no counters
ClosedPublic

Authored by gulfem on Aug 17 2022, 6:24 PM.

Details

Summary

When we use selective instrumentation and instrument a file
that is not in the selected files list provided via -fprofile-list,
we generate an empty raw profile. This leads to empty_raw_profile
error when we try to read that profile. This patch fixes the issue by
generating a raw profile that contains only a profile header when
there are no counters and profile data.

A small reproducer for the above issue:
echo "src:other.cc" > code.list
clang++ -O2 -fprofile-instr-generate -fcoverage-mapping
-fprofile-list=code.list code.cc -o code
./code
llvm-profdata show default.profraw

Diff Detail

Event Timeline

gulfem created this revision.Aug 17 2022, 6:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 17 2022, 6:24 PM
Herald added a subscriber: Enna1. · View Herald Transcript
gulfem requested review of this revision.Aug 17 2022, 6:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 17 2022, 6:24 PM
Herald added a subscriber: Restricted Project. · View Herald Transcript

The concern I have with this solution is that if there are some users that do

LLVM_PROFILE_FILE=foo.profraw ./foo`

and then immediately try to either process foo.profraw because they assume that this file is always going to be produced, then this change is going to break them. It may also be non-trivial for them to work around it if they don't have an ability to check for the foo.profraw existence (this can be the case in infrastructure that uses declarative configuration for example). I don't know how to check whether any such users exists though so this concern may be entirely unfounded.

A potentially safer solution would be to always produce an empty profile, that is a file that has a header but no data and/or counters, by removing this check https://github.com/llvm/llvm-project/blob/e33599371eb1ab1b782735f39b3f27c19d88da41/compiler-rt/lib/profile/InstrProfilingWriter.c#L279

A small reproducer for the above issue:
echo "src:other.cc" > code.list
clang++ -O2 -fprofile-instr-generate -fcoverage-mapping
-fprofile-list=code.list code.cc -o code
./code
llvm-profdata show default.profraw

Would it be possible to turn this reproducer into a test?

gulfem updated this revision to Diff 453789.Aug 18 2022, 2:29 PM

Add a test case

The concern I have with this solution is that if there are some users that do

LLVM_PROFILE_FILE=foo.profraw ./foo`

and then immediately try to either process foo.profraw because they assume that this file is always going to be produced, then this change is going to break them. It may also be non-trivial for them to work around it if they don't have an ability to check for the foo.profraw existence (this can be the case in infrastructure that uses declarative configuration for example). I don't know how to check whether any such users exists though so this concern may be entirely unfounded.

A potentially safer solution would be to always produce an empty profile, that is a file that has a header but no data and/or counters, by removing this check https://github.com/llvm/llvm-project/blob/e33599371eb1ab1b782735f39b3f27c19d88da41/compiler-rt/lib/profile/InstrProfilingWriter.c#L279

We have two options to solve this issue:

  1. Do not generate any profile file at all, which I currently implemented.
  2. Generate a profile with header & zero data and counts, which @phosek suggested.

I think option 1 is better if there are no such users/systems that assume that a profile is generated whenever a file is instrumented.
@davidxl @vsk and @ellis, please let us know if you are aware of such a system. If there is such a user, we can go with option 2.

I prefer always having a file. It:

  • removes a behavior difference
  • gives users a hint that PGO is effective (even if all functions are skipped)
  • satisfies some build system requirement. For instance, for distributed ThinLTO we ensure that an index file always exists, even for non-extracted lazy object file
ellis added a comment.Aug 18 2022, 4:02 PM

When using the -fprofile-function-groups option we could hit the case where one of the groups has no profiled functions. In that case it would be more surprising to not find a raw profile, rather than an empty raw profile. If we do go with option 1, maybe we could emit a warning explaining why no profile was emitted. Or if we go with option 2, maybe a warning would also be good to alert the user that it's an empty profile.

https://clang.llvm.org/docs/UsersManual.html#instrument-function-groups

gulfem updated this revision to Diff 455777.Aug 25 2022, 7:57 PM

Implement option 2.

Herald added a project: Restricted Project. · View Herald TranscriptAug 25 2022, 7:57 PM
gulfem retitled this revision from [profile] Do not create a profile when no counters to [profile] Create only prof header when no counters.Aug 25 2022, 7:58 PM

Thanks for your feedback @MaskRay and @ellis, and I implemented option 2 (Generate a profile with header & zero data and counts).

When using the -fprofile-function-groups option we could hit the case where one of the groups has no profiled functions. In that case it would be more surprising to not find a raw profile, rather than an empty raw profile. If we do go with option 1, maybe we could emit a warning explaining why no profile was emitted. Or if we go with option 2, maybe a warning would also be good to alert the user that it's an empty profile.

What kind of warning do you have in mind @ellis? Are you suggesting to put some text like Empty Profile when we read a profile via llvm-profdata show (which happens to contain only a header)?

gulfem edited the summary of this revision. (Show Details)Aug 26 2022, 9:27 AM
ellis accepted this revision.Aug 27 2022, 11:39 AM

When using the -fprofile-function-groups option we could hit the case where one of the groups has no profiled functions. In that case it would be more surprising to not find a raw profile, rather than an empty raw profile. If we do go with option 1, maybe we could emit a warning explaining why no profile was emitted. Or if we go with option 2, maybe a warning would also be good to alert the user that it's an empty profile.

What kind of warning do you have in mind @ellis? Are you suggesting to put some text like Empty Profile when we read a profile via llvm-profdata show (which happens to contain only a header)?

On second thought, when the user runs llvm-profdata show they will see that zero functions are instrumented, so I'm not sure a warning there is necessary.

LGTM after resolving comments!

compiler-rt/test/profile/Posix/instrprof-empty-profile.c
6

I've have issues with using this sed command like this where it broke a test on Windows, but I think that was because my profile-list file had multiple lines. For this case, I'm not sure sed is necessary because there are no \ characters. Let's remove it to simplify the line.

9

Is this test necessary if we are going to use the raw profile in the llvm-profdata command below anyway?

11–12

I think it's simpler to use a pipe rather than creating a temporary file.

Also, it looks like this and the next FileCheck are checking the same output so we can reuse the same default prefix.

21

I think this might be the only important line to check. Do we need to check the other lines too?

compiler-rt/test/profile/Posix/instrprof-shared-empty-profile.test
9

Oh nice, thanks for handling and testing this case! (The same comments from the previous test apply here)

This revision is now accepted and ready to land.Aug 27 2022, 11:39 AM
ellis added inline comments.Aug 27 2022, 11:41 AM
compiler-rt/test/profile/Posix/instrprof-shared-empty-profile.test
30

I think you're missing the run command to produce this raw profile.

gulfem updated this revision to Diff 456470.Aug 29 2022, 3:06 PM

Addressed the feedback about the test

gulfem marked 5 inline comments as done.Aug 29 2022, 3:12 PM
gulfem added inline comments.
compiler-rt/test/profile/Posix/instrprof-empty-profile.c
21

Appreciate for all the feedback @ellis!
I prefer to check all the other lines to make sure that we have only 0s.
For this test it might not be important, but for the shared library test (instrprof-shared-empty-profile.test), I would like to verify the accurate values.

ellis added inline comments.Aug 29 2022, 3:20 PM
compiler-rt/test/profile/Posix/instrprof-empty-profile.c
21

Sounds good!

This revision was automatically updated to reflect the committed changes.