-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Allow loading LLVM plugins with both legacy and new pass manager #91125
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @matthewjasper (or someone else) soon. Please see the contribution instructions for more information. |
How is this different from the flag introduced by #86267? |
The main difference is using the new LLVM pass manager registration, which is not possible with the current flag. The flag The proposed flag would allow loading only libraries which use the new LLVM pass manager format, which means those exposing the symbol |
Could the already existing flag be made to work for both oldPM and newPM plugins? |
The only issue would be when the option isn't specified and the arch is
For this specific case, the user of the llvm-plugins would have to know the new PM plugins are not usable because of the exception.
So basically, to use the new PM plugins we'd have to actively set Would this solution seem acceptable ? |
Making it conditional on a flag seems reasonable (oldPM is going away shortly anyway), though I was kind of hoping that |
With 0ce67ab389746cd4e135ed15b3c2eb7c32c0d064 and 0ce67ab389746cd4e135ed15b3c2eb7c32c0d064, now we only load new PM plugins from These changes should address current @bjorn3 and @nagisa feedback. |
Ok(_) => debug!("LLVM plugin loaded succesfully {} ({})", path.display(), plugin), | ||
Err(e) => bug!("couldn't load plugin: {}", e), | ||
let use_new_llvm_pm_plugin_register = | ||
sess.opts.debugging_opts.new_llvm_pass_manager.unwrap_or(false); |
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.
If new_llvm_pass_manager
returns None
, the new pass manager is used when the llvm version is at least 13 and the target is not s390x. See
rust/compiler/rustc_codegen_llvm/src/back/write.rs
Lines 397 to 410 in 8b09ba6
pub(crate) fn should_use_new_llvm_pass_manager( | |
cgcx: &CodegenContext<LlvmCodegenBackend>, | |
config: &ModuleConfig, | |
) -> bool { | |
// The new pass manager is enabled by default for LLVM >= 13. | |
// This matches Clang, which also enables it since Clang 13. | |
// FIXME: There are some perf issues with the new pass manager | |
// when targeting s390x, so it is temporarily disabled for that | |
// arch, see https://github.com/rust-lang/rust/issues/89609 | |
config | |
.new_llvm_pass_manager | |
.unwrap_or_else(|| cgcx.target_arch != "s390x" && llvm_util::get_version() >= (13, 0, 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.
Yes that's what i was mentioning at the end of #91125 (comment).
What i'm proposing is to condition the new PM plugin loading only on the explicit new_llvm_pass_manager=yes
and not the actual usage of the new PM later. Since there are exceptions and a default value hardcoded, we can't trust the option to reflect reality.
If we do want to condition on the actual usage of the new PM then i see two potential issues:
- current users of
llvm-plugins
when updating to a llvm13 based rust will trigger PassPlugin::Load on their legacy plugins since the new PM is enabled by default. They will need to explicitly setnew_llvm_pass_manager=false
- i'm not sure how to use
should_use_new_llvm_pass_manager
in llvm_util.rs, maybe just move it to llvm_util.rs to make it more widely available ?
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.
@bjorn3 do you think the current code is acceptable regarding the explicit usage of new_llvm_pass_manager
or i should
propose the alternative described in my last reply ?
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.
Sorry for the late reply. Missed your previous comment.
current users of llvm-plugins when updating to a llvm13 based rust will trigger PassPlugin::Load on their legacy plugins since the new PM is enabled by default. They will need to explicitly set new_llvm_pass_manager=false
At least in that case you will get an error message rather than silently ignoring it, right?
i'm not sure how to use should_use_new_llvm_pass_manager in llvm_util.rs, maybe just move it to llvm_util.rs to make it more widely available ?
Makes sense I think.
do you think the current code is acceptable regarding the explicit usage of new_llvm_pass_manager or i should
propose the alternative described in my last reply ?
I think using should_use_new_llvm_pass_manager
is better. I don't strongly object to the current code though.
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.
Sorry for the late reply. Missed your previous comment.
No problem, i should have pinged you earlier but i was busy on other tasks anyway.
current users of llvm-plugins when updating to a llvm13 based rust will trigger PassPlugin::Load on their legacy plugins since the new PM is enabled by default. They will need to explicitly set new_llvm_pass_manager=false
At least in that case you will get an error message rather than silently ignoring it, right?
Indeed, in that case cargo build
fails with an error and i can see original LLVM error message directly in cargo non verbose logs like this: Plugin entry point not found in '/tmp/libLLVMPlugin.so'. Is this a legacy plugin?
i'm not sure how to use should_use_new_llvm_pass_manager in llvm_util.rs, maybe just move it to llvm_util.rs to make it more widely available ?
Makes sense I think.
Ok let's try it.
do you think the current code is acceptable regarding the explicit usage of new_llvm_pass_manager or i should
propose the alternative described in my last reply ?I think using
should_use_new_llvm_pass_manager
is better. I don't strongly object to the current code though.
Ok thank you for your feedback, i'll try doing it this way and see how that goes.
☔ The latest upstream changes (presumably #90716) made this pull request unmergeable. Please resolve the merge conflicts. |
6e703ce
to
75d1208
Compare
Resolved conflicts with #90716, re-tested with upstream, and updated the PR title to reflect more what is now being proposed. |
Please click the “ready for review” button once you think its good to go. |
@bors r+ |
📌 Commit f431df0 has been approved by |
☀️ Test successful - checks-actions |
Finished benchmarking commit (1b3a5f2): comparison url. Summary: This benchmark run did not return any relevant changes. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression |
Opening a draft PR to get feedback and start discussion on this feature. There is already a codegen option
passes
which allow giving a list of LLVM pass names, however we currently can't use a LLVM pass plugin (as described here : https://llvm.org/docs/WritingAnLLVMPass.html), the only available passes are the LLVM built-in ones.The proposed modification would be to add another codegen option
pass-plugins
, which can be set with a list of paths to shared library files. These libraries are loaded using the LLVM functionPassPlugin::Load
, which calls the expected symbollvmGetPassPluginInfo
, and register the pipeline parsing and optimization callbacks.An example usage with a single plugin and 3 passes would look like this in the
.cargo/config
:This would give the same functionality as the opt LLVM tool directly integrated in rust build system.
Additionally, we can also not specify the
passes
option, and use a plugin which inserts passes in the optimization pipeline, as one could do using clang.