-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Fix linker-plugin-lto only doing thin lto #136840
base: master
Are you sure you want to change the base?
Conversation
Could not assign reviewer from: |
This PR modifies cc @jieyouxu |
I have barely any idea about LTO besides "it happens and it involves dlopening a compiler and shoving its serialized data back in it" tbh soo |
Unfortunately I have no clue either, so r? compiler |
For reference, the code that switches to thin lto when the flag is not set is here: https://github.com/llvm/llvm-project/blob/e258bca9505f35e0a22cb213a305eea9b76d11ea/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp#L4441-L4446 // By default we compile with ThinLTO if the module has a summary, but the
// client can request full LTO with a module flag.
bool IsThinLTO = true;
if (auto *MD =
mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO")))
IsThinLTO = MD->getZExtValue(); The code in clang that sets the flag, which is replicated here for Rust is here: https://github.com/llvm/llvm-project/blob/560149b5e3c891c64899e9912e29467a69dc3a4c/clang/lib/CodeGen/BackendUtil.cpp#L1150 if (!TheModule->getModuleFlag("ThinLTO") && !CodeGenOpts.UnifiedLTO)
TheModule->addModuleFlag(llvm::Module::Error, "ThinLTO", uint32_t(0)); |
// Disable ThinLTO if fat lto is requested. Otherwise lld defaults to thin lto. | ||
if sess.lto() == config::Lto::Fat { | ||
llvm::add_module_flag_u32(llmod, llvm::ModuleFlagMergeBehavior::Override, "ThinLTO", 0); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if a dependency is built with lto=true (aka lto=fat), but then the user wants to use thinLTO? I'm pretty sure the standard library is built with lto=true for example, but that shouldn't prevent thinLTO from ever working.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question, it seems to change somewhat, but still work in general. I added a test for this.
What changes: Without this change, the test passes when
lib is compiled with O0
and main with O3
and
- lib uses lto=thin and main uses lto=thin
- lib uses lto=thin and main uses lto=fat
- lib uses lto=fat and main uses lto=thin
- lib uses lto=fat and main uses lto=fat
With this change, all of these keep passing except for case 3 (lib uses lto=fat and main uses lto=thin).
When lib is compiled with O1
, O2
or O3
, case 3 passes as well.
I assume this is the important case, as the standard library is compiled with optimizations.
(And lto with O0
is kinda questionable, except maybe for nvptx and amdgpu, but they require lto=fat anyway.)
This comment has been minimized.
This comment has been minimized.
r? compiler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know little about lto, either. I think it would be much more acceptable if this PR could limit the change to amdhsa
conditions.
r? compiler
@@ -290,6 +290,11 @@ pub(crate) unsafe fn create_module<'ll>( | |||
); | |||
} | |||
|
|||
// Disable ThinLTO if fat lto is requested. Otherwise lld defaults to thin lto. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds counterintuitive. Can you explain the relationship between the user's lto
option and llvm's lto
in the comments?
And I think it needs a individual test to ensure that the previous lto=fat
option is not affected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the comment, is it clearer now?
(I want to affect the current lto=fat
option, as it currently does thin lto, which I think is not intended and a bug :))
r? codegen |
AFAIU, fat LTO + linker-plugin-lto is currently broken for all targets, as lld just does thin lto, even if the user requested fat lto. Setting the It’s just that x86 and other targets run fine with only thin lto. GPU targets (e.g. amdgpu and nvptx) currently require lto to function correctly. This may change when hardware vendors focus more on linking, but I think the performance dip makes it rather unattractive today. So, if fat LTO is not working correctly, it becomes apparent quickly on GPU targets, not so on x86. I can move the |
0d63f96
to
2d33f69
Compare
The run-make-support library was changed cc @jieyouxu |
I found a way to reproduce the same on x86 by creating an object file that does not contain function summaries. I added a test and removed all the amdhsa-specific code from this PR. Diff to last push |
This comment has been minimized.
This comment has been minimized.
2d33f69
to
d421833
Compare
When rust provides LLVM bitcode files to lld and the bitcode contains function summaries as used for thin lto, lld defaults to using thin lto. This prevents some optimizations that are only applied for fat lto. Set the `ThinLTO=0` module flag to signal lld to do fat lto. The analogous code in clang that sets this flag is here: https://github.com/llvm/llvm-project/blob/560149b5e3c891c64899e9912e29467a69dc3a4c/clang/lib/CodeGen/BackendUtil.cpp#L1150 The code in LLVM that queries the flag and defaults to thin lto if not set is here: https://github.com/llvm/llvm-project/blob/e258bca9505f35e0a22cb213a305eea9b76d11ea/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp#L4441-L4446
d421833
to
b692fa0
Compare
Try to fix the test by forcing rust-lld (diff) |
When rust provides LLVM bitcode files to lld and the bitcode contains
function summaries as used for thin lto, lld defaults to using thin lto.
This prevents some optimizations that are only applied for fat lto.
Set the
ThinLTO=0
module flag to signal lld to do fat lto.The analogous code in clang that sets this flag is here:
https://github.com/llvm/llvm-project/blob/560149b5e3c891c64899e9912e29467a69dc3a4c/clang/lib/CodeGen/BackendUtil.cpp#L1150
The code in LLVM that queries the flag and defaults to thin lto if not
set is here:
https://github.com/llvm/llvm-project/blob/e258bca9505f35e0a22cb213a305eea9b76d11ea/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp#L4441-L4446
r? @workingjubilee, as you’ve been reviewing most other amdgpu patches, not sure if there should be other reviewers for lto.