-
Notifications
You must be signed in to change notification settings - Fork 13k
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
cg_llvm: Replace most of our DIBuilder wrappers with LLVM-C API bindings #134009
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
Looks like PR CI found some functions that were new in LLVM 19, fair enough. |
Partly rolled back the use of EDIT: Also it turns out that my binding had the wrong return type anyway. |
I have also replaced the DWARF opcode functions with constants, and explained why the remaining |
07d42da
to
23c29e8
Compare
It occurred to me that this might have perf implications for debug builds. I don't expect to see any major change, but: @bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
cg_llvm: Replace most of our DIBuilder wrappers with LLVM-C API bindings Many of our `LLVMRust` wrapper functions for building debug info can be replaced with their equivalents in the LLVM-C API. This mostly implements rust-lang#134001, though it punts on some of the trickier cases noted at rust-lang#134001 (comment). --- Marking as draft for now, because I want to give myself more time to review my own changes. r? workingjubilee
I made some small style tweaks based on my own review pass, and I also altered the |
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (3e30f53): comparison URL. Overall result: no relevant changes - no action neededBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)Results (primary -0.8%, secondary 1.1%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (secondary -3.3%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 769.999s -> 769.284s (-0.09%) |
Added an explanation of why EDIT: Also subsequently did a rebase onto master; no changes. |
I also noticed that our EDIT: #134204 |
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.
Thanks! This is a significant improvement, just a few notes.
/* LowerBound */ 0i64, | ||
/* Count */ upper_bound as i64, |
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.
These have to be positive numbers, right?
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.
LLVM declares them as int64_t
, in both the C and C++ APIs. 🤷♂️
Or are you suggesting that we assert that they're non-negative?
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 am indeed suggesting that.
r=me with nit addressed and the invariant (if any) doc'd on our side |
if (Flags & LLVMDIFlagBigEndian) Result |= DIFlags::FlagLittleEndian; | ||
if (Flags & LLVMDIFlagLittleEndian) Result |= DIFlags::FlagLittleEndian; |
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.
Best kind of errors? Copypaste.
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.
oh right.
/// Mostly equivalent to `LLVMDIBuilderInsertDeclareRecordAtEnd` in LLVM 19, | ||
/// except that this works on LLVM 18 and also doesn't return a value. | ||
pub(crate) fn LLVMRustDIBuilderInsertDeclareRecordAtEnd<'ll>( |
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.
Need fixme with note to change this when minimum llvm will be 19.
I think I'll try to split off |
☔ The latest upstream changes (presumably #133990) made this pull request unmergeable. Please resolve the merge conflicts. |
if (Flags & LLVMDIFlagSingleInheritance) Result |= DIFlags::FlagSingleInheritance; | ||
if (Flags & LLVMDIFlagMultipleInheritance) Result |= DIFlags::FlagMultipleInheritance; | ||
if (Flags & LLVMDIFlagVirtualInheritance) Result |= DIFlags::FlagVirtualInheritance; |
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.
Actually, if I'm bothering to have special treatment for the LLVMDIFlagAccessibility
flags below, it makes no sense to not also do the same thing for these LLVMDIFlagPtrToMemberRep
flags as well.
(Other than the fact that Rust might never actually use these flags? But following that line of reasoning suggests perhaps not supporting conversion of them at all.)
…ilee cg_llvm: Use constants for DWARF opcodes, instead of FFI calls Split off from rust-lang#134009 to incorporate feedback from rust-lang#134009 (comment). Most of the constant values now come from gimli, which is already a compiler dependency. I noticed that `DW_OP_LLVM_fragment` is an LLVM detail that is not defined by DWARF and could hypothetically change, so I added a static assertion on the C++ side to detect that if it ever happens. r? workingjubilee
Rollup merge of rust-lang#135115 - Zalathar:dwarf-const, r=workingjubilee cg_llvm: Use constants for DWARF opcodes, instead of FFI calls Split off from rust-lang#134009 to incorporate feedback from rust-lang#134009 (comment). Most of the constant values now come from gimli, which is already a compiler dependency. I noticed that `DW_OP_LLVM_fragment` is an LLVM detail that is not defined by DWARF and could hypothetically change, so I added a static assertion on the C++ side to detect that if it ever happens. r? workingjubilee
Make our `DIFlags` match `LLVMDIFlags` in the LLVM-C API In order to be able to use a mixture of LLVM-C and C++ bindings for debuginfo, our Rust-side `DIFlags` needs to have the same layout as LLVM-C's `LLVMDIFlags`, and we also need to be able to convert it to the `DIFlags` accepted by LLVM's C++ API. Internally, LLVM converts between the two types with a simple cast. We can't necessarily rely on that always being true, and LLVM doesn't expose a conversion function, so we have two potential options: - Convert each bit/subvalue individually - Statically assert that doing a cast is actually fine As long as both types do remain the same under the hood (which seems likely), the static-assert-and-cast approach is easier and faster. If the static assertions ever start failing against some future version of LLVM, we'll have to switch over to the convert-each-subvalue approach, which is a bit more error-prone. --- Extracted from rust-lang#134009, though this PR ended up choosing the static-assert-and-cast approach over the convert-each-subvalue approach.
One of the limitations of this PR is that it has to update all of the bindings at once, to avoid a theoretical UB hazard that would occur if we equivocated LLVM-C's To sidestep that, I've filed #136326, which switches over to That should make it possible for later PRs to convert bindings incrementally. |
Replace our `LLVMRustDIBuilderRef` with LLVM-C's `LLVMDIBuilderRef` Inspired by trying to split rust-lang#134009 into smaller steps that are easier to review individually. This makes it possible to start incrementally replacing our debuginfo bindings with the ones in the LLVM-C API, all of which operate on `LLVMDIBuilderRef`. There should be no change to compiler behaviour.
Rollup merge of rust-lang#136326 - Zalathar:llvm-di-builder-ref, r=nikic Replace our `LLVMRustDIBuilderRef` with LLVM-C's `LLVMDIBuilderRef` Inspired by trying to split rust-lang#134009 into smaller steps that are easier to review individually. This makes it possible to start incrementally replacing our debuginfo bindings with the ones in the LLVM-C API, all of which operate on `LLVMDIBuilderRef`. There should be no change to compiler behaviour.
I extracted the first few binding migrations into #136375. |
…gjubilee cg_llvm: Replace some DIBuilder wrappers with LLVM-C API bindings (part 1) Part of rust-lang#134001, follow-up to rust-lang#136326, extracted from rust-lang#134009. This PR performs an arbitrary subset of the LLVM-C binding migrations from rust-lang#134009, which should make it less tedious to review. The remaining migrations can occur in one or more subsequent PRs.
Many of our
LLVMRust
wrapper functions for building debug info can be replaced with their equivalents in the LLVM-C API.This mostly implements #134001, though it punts on some of the trickier cases noted at #134001 (comment).