This is an archive of the discontinued LLVM Phabricator instance.

[CSPGO] Fix lost IRPGOFlag in CSPGO instrumentation
ClosedPublic

Authored by xur on Aug 23 2021, 1:37 PM.

Details

Summary

The IRPGOFlag symbol (__llvm_profile_raw_version) is dropped when
identified as non-prevailing for either regular or thin LTO during
the mixed-LTO mode compilation. This happens in the module
where IRPGOFlag is marked as non-prevailing. This variable
is emitted in the final object from the prevailing module.

This is still problematic because we currently query this symbol to coordinate
some actions between PGOInstrumentation pass and InstrProfiling lowering
pass, like whether to do value profiling, weather to do comdat renaming.

TThis problem is bought up by YolandaCY in
https://reviews.llvm.org/D107034
YolandCY reported unresolved symbol linker errors in CSPGO instrumentation build.

D107034 proposed to set a module flag as the fix.

But I think a better way is to let LTO retain IRPGOFlag decl by adding
it to CompilerUsed list and relax the check in isIRPGOFlagSet() when
doing the InstruProfling lowering.

The test case in the patch is from D107034.

Diff Detail

Event Timeline

xur created this revision.Aug 23 2021, 1:37 PM
xur requested review of this revision.Aug 23 2021, 1:37 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 23 2021, 1:37 PM
MaskRay added a comment.EditedAug 23 2021, 3:54 PM

Thanks for the patch. llvm.compiler.used does look better to me.


This happens in the module where IRPGOFlag is mard as non-prevailing

marked

This is still problematic because we currently query this symbol to coordinate some actions B/W PGOInstrumentation and InstroProfiling lowering, like whether to do value profiling, weather to do comdat renaming.

Worth clarifying B/W.

InstruProfling

InstrProfiling


I have confirmed that

In regular LTO, the non-prevailing variable is dropped unless its linkage weak_odr/linkonce_odr && -compute-dead=0
In ThinLTO, the variable is changed to available_external linkage by thinLTOResolvePrevailingGUID then dropped by GlobleOpt:deleteIfDead in the backend.

Does it make sense to update thinlto_cspgo_gen.ll as well?

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
469

The form liked by both clang-tidy bugprone-argument-comment and clang-format: /*IsCS=*/true

1640

The form liked by both clang-tidy bugprone-argument-comment and clang-format: /*IsCS=*/true

llvm/test/Transforms/PGOProfile/lto_cspgo_gen.ll
9

Worth a comment that the two variables are intentionally non-prevailing.

27

unneeded and can be dropped

32

unneeded and can be dropped

MaskRay added inline comments.Aug 23 2021, 4:09 PM
llvm/lib/ProfileData/InstrProf.cpp
1104
llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
468–471

Add a comment like:

The variable in a comdat may be discarded by LTO. Ensure the declaration will be retained.

This raises the question: Is llvm.compiler.used allowed to reference a declaration (previously a non-prevailing definition due to comdat selection)? ISTM this should be allowed.

xur edited the summary of this revision. (Show Details)Aug 23 2021, 4:56 PM
xur marked 3 inline comments as done.Aug 23 2021, 4:58 PM

Thanks for the patch. llvm.compiler.used does look better to me.


This happens in the module where IRPGOFlag is mard as non-prevailing

marked

Fixed

This is still problematic because we currently query this symbol to coordinate some actions B/W PGOInstrumentation and InstroProfiling lowering, like whether to do value profiling, weather to do comdat renaming.

Worth clarifying B/W.

InstruProfling

InstrProfiling

Fixed


I have confirmed that

In regular LTO, the non-prevailing variable is dropped unless its linkage weak_odr/linkonce_odr && -compute-dead=0
In ThinLTO, the variable is changed to available_external linkage by thinLTOResolvePrevailingGUID then dropped by GlobleOpt:deleteIfDead in the backend.

Thanks for confirming and put the conditions here

Does it make sense to update thinlto_cspgo_gen.ll as well?

That's a good idea. I will change that test too.

xur edited the summary of this revision. (Show Details)Aug 23 2021, 4:59 PM
xur marked 3 inline comments as done.Aug 23 2021, 5:37 PM
xur added inline comments.
llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
468–471

comment added.

For the question:
At the time of appending to llvm.compiler.used, this is a definition (not a decl). I don't see any problem add it to the list.

xur updated this revision to Diff 368245.Aug 23 2021, 5:39 PM

Thanks to Fangrui for the comments/suggestions.
Integrated his reviews to the patch.

-Rong

MaskRay accepted this revision.Aug 23 2021, 5:51 PM

LGTM.

Apologies to @YolandaCY that I did make a mistake in the other patch.
("ld.lld does comdat selection but the prevailing/non-prevailing decisions do not drop non-prevailing __llvm_profile_raw_version variables from bitcode files.") is wrong.
ThinLTO and regular LTO can indeed drop the non-prevailing variables.


I assume that D108432 is still worth fixing. Breaking it could be hard, though.

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
468–471

Agreed. There is prior art: we already use llvm.compiler.used to reference potentially non-prevailing __profd_*,

llvm/test/Transforms/PGOProfile/lto_cspgo_gen.ll
15

Perhaps add the llvm.compiler.used line and explain that the declaration needs to be kept even if non-prevailing.

llvm/test/Transforms/PGOProfile/thinlto_cspgo_gen.ll
20

Perhaps add the llvm.compiler.used line and explain that the declaration needs to be kept even if non-prevailing.

This revision is now accepted and ready to land.Aug 23 2021, 5:51 PM
xur updated this revision to Diff 368253.Aug 23 2021, 6:15 PM

Added a few comments to the test cases as suggested by Fangri.

YolandaCY accepted this revision.Aug 24 2021, 6:55 AM

Thank you for the patch. I've verified the IRPGOFlag is kept now for non-prevailing modules in Chromium build. The linker error is also resolved for Windows build.

Glad to learn the usage of llvm.compiler.used, indeed a more proper fix. :)

This revision was automatically updated to reflect the committed changes.