[rustc_public] Enhance PassMode API#159359
Conversation
Replace the opaque representation of `PassMode::Cast` with a structured `CastTarget` type that exposes the register layout used by the platform ABI. Add `Uniform`, `Reg`, and `RegKind` types so tools can inspect how arguments are mapped to registers. Add `CastTarget::size()` and `Uniform::reg_count()` helpers. Add a test covering cast on args, returns, mixed register kinds, multiple arguments, and register exhaustion causing stack spill.
Expose argument ABI attributes through a structured type instead of opaque debug strings. ArgAttributes provides accessors for the extension mode (zero/sign-extend) and pointee alignment, which are needed by tools doing their own code generation. This removes all uses of Opaque from the abi module.
|
r? @makai410 rustbot has assigned @makai410. Use Why was this reviewer chosen?The reviewer was selected based on:
|
There was a problem hiding this comment.
This file has incorrect statements such as
/// The `abi` defines how this data is passed between functions.
pub abi: ValueAbi,
See #132246 for more on why this is wrong.
I would honestly rather you not "enhance" anything here and set almost this entire file on fire here because it's just going to make me actually rewriting this harder. We could make more accurate information available in the future, but it's unclear why anyone would benefit from the current information because they lack the full context to interpret it.
There was a problem hiding this comment.
I appreciate the context. Having to reverse engineer the compiler is not an easy task, so please do point out any inaccuracies. Most of the comments here I wrote based on the comments from rustc_target and from analyzing the generated FnAbi for different function signatures.
There was a problem hiding this comment.
I dearly sympathize because my task of figuring out what the hell is going on involves reverse-engineering LLVM. 🙃
At some point I just sort of started assuming everything I am reading is probably wrong, unfortunately.
There was a problem hiding this comment.
My question here is mostly: What question is someone trying to answer that they think this information would be of use to them? If they're trying to do a basic ABI equality check then smuggling the data around opaquely with mostly no transformation and exposing a PartialEq impl that interrogates the innards seems more useful.
There was a problem hiding this comment.
To elaborate: The rustc_target and rustc_abi crates were mostly written ages ago by people who are not easy to ask questions of anymore, in a single-backend context, where x86-64 was our only tier 1 target. It was then incrementally edited, including by people such as myself, in ways that were "good enough", and our unclear understandings documented as truth because no one was around anymore who completely knew exactly what was going on and we could usefully discuss things with. "cg_ssa" (rustc_codegen_ssa) was introduced as an incomplete abstraction layer over LLVMIR, and to the extent it has abstracted anything, it has made everything in rustc_abi and rustc_target wronger.
That is why asking questions about things below FnAbi is probably not a good idea, unless it's about a fundamental like Size or Align. Obviously those have to be correct. And we've... tried to make LayoutData... vaguely intelligible.
There was a problem hiding this comment.
So, if anyone wants to build a codegen backend, they should be focusing on using cg_ssa. That doesn't allow multi-version stability, but there is a reason I am saying it. If it is insufficient or problematic, it should be improved until it serves the need.
Analysis alone, however, is indeed the intended use-case of things here.
In either case, if they want a precise answer that doesn't depend on LLVM that can reason about things like "generating correct call sequences", they're Kinda Screwed Right Now. They would need to also implement the exact logic, essentially, that LLVM does, in order to get a consistently correct answer, because of how we kinda only model "ABI modulo LLVM".
There was a problem hiding this comment.
Hmm. It might be sufficient if they want only a purely abstract matching of Rust's function ABI to a C signature? That might be wrong but it should be correct-enough.
There was a problem hiding this comment.
In the Rust ABI there are things that can't be represented as a valid C signature. For example there are cases where we use more return registers than the platform C ABI allows, but LLVM supports representing it anyway.
There was a problem hiding this comment.
Thanks for the context. To summarize where I think we are: this PR adds information that is currently missing from rustc_public — the structure of PassMode::Cast, argument attributes, and corrected documentation. The data itself is not incorrect; it accurately reflects the compiler's calling convention decisions.
Users may still need to do further processing depending on their use case (as cg_ssa does today), and the Rust ABI can produce things that don't map cleanly to a C signature. The data shouldn't be taken at face value as "this is exactly what happens on the wire" — but it is the correct input for tools that need to reason about argument layout and pass modes.
There was a problem hiding this comment.
The use case is tools that build their own backends or analyzers on top of MIR and need to generate compatible call sequences or how the code interacts via FFI without depending on LLVM.
Do these need to be compatible with the Rust ABI that the LLVM backend happens to use or is it only about C FFI and can they chose to use an arbitrary ABI for extern "Rust"?
|
What is the purpose of the information here? It honestly is mostly not information that can be used correctly by people who aren't willing to just look directly at the LLVMIR and emitted assembly, which will actually tell them what is going on. |
|
Like, all of the annotations that we emit do not have a precise relationship with what LLVM does, because LLVM... interprets... various IR patterns differently, often in a way that depends on which machine backend you are using, specifics of the exact target in question, and even the position of the argument (well before you run out of registers, mind!). That is, to put it simply: |
This comment has been minimized.
This comment has been minimized.
59b3ad1 to
ae8aeeb
Compare
BREAKING CHANGE: `ValueAbi` is renamed to `ValueRepr` and the `LayoutShape::abi` field is renamed to `LayoutShape::value_repr`. The old name was misleading: this type does not describe how values are passed in function calls (that is `PassMode`), it is a hint for how backends should represent values (as scalars, vectors, or aggregates). This aligns with the internal rename from `Abi` to `BackendRepr`. Also fixes several doc comments that incorrectly claimed layout fields define calling behavior.
ae8aeeb to
f340101
Compare
This change is split into two different commits: