This is more of a question, and if it makes sense, a proposal.
Motivation
cuda-oxide is a rustc codegen backend for NVIDIA GPUs; its GPU-side translation consumes rustc_public only. I'd like kernel parameters to carry the same LLVM parameter attributes rustc emits for the host (noalias, readonly, nonnull, align, dereferenceable).
Why: on a field-wise struct-copy kernel, adding noalias (and readonly) by hand to the emitted IR turned 4 x 32-bit loads + 4 x 32-bit stores into one 128-bit load (read-only cache path) + one 128-bit store: 1.33x faster for the streaming version, 4.89x faster for the cache-resident version.
Today I can see the pointer kind (RigidTy::Ref) and the layout, but not whether the pointee is Freeze / Unpin, so I cannot tell &u32 from &Cell<u32>. Re-deriving rustc's rules is not an option: they depend on those auto traits and the opt-level gate, and they change.
Two things I want to confirm before proposing anything:
Instance::fn_abi() returns a FnAbi whose modes are PassMode::Direct(Opaque), Pair(Opaque, Opaque) and Indirect { attrs: Opaque, .. }; the bridge wraps rustc_target::callconv::ArgAttributes with opaque(attr) (unstable/convert/stable/abi.rs:164). So the attribute flags are reachable only by parsing the Debug string.
- I don't see a way to ask whether a type is
Freeze or Unpin. Both are auto traits, so trait_impls cannot answer it either.
I see #58 listed "Expand PassMode attributes" as a task when the ABI module landed, and it was closed without it. Was that dropped for a reason, or just never picked up?
Proposal
Replace Opaque in Direct, Pair and Indirect with a typed mirror of rustc_target::callconv::ArgAttributes, reusing rustc_public's existing Size and Align:
pub struct ArgAttributes {
pub regular: ArgAttribute, // flags: NoAlias, ReadOnly, NonNull, NoFree, NoUndef,
// InReg, Writable, CapturesNone/Address/ReadOnly
pub arg_ext: ArgExtension, // None | Zext | Sext
pub pointee_size: Size,
pub pointee_align: Option<Align>,
}
Cast { cast: Opaque } can stay opaque. Before / after for fn f(a: &u32):
today PassMode::Direct(Opaque("ArgAttributes { regular: NoAlias | NonNull | ReadOnly | NoFree | NoUndef, .. }"))
after PassMode::Direct(ArgAttributes { regular: NoAlias | NonNull | ReadOnly | NoFree | NoUndef,
arg_ext: None, pointee_size: 4 bytes, pointee_align: Some(4) })
Would this make sense?
This is more of a question, and if it makes sense, a proposal.
Motivation
cuda-oxide is a rustc codegen backend for NVIDIA GPUs; its GPU-side translation consumes rustc_public only. I'd like kernel parameters to carry the same LLVM parameter attributes rustc emits for the host (
noalias,readonly,nonnull,align,dereferenceable).Why: on a field-wise struct-copy kernel, adding
noalias(andreadonly) by hand to the emitted IR turned 4 x 32-bit loads + 4 x 32-bit stores into one 128-bit load (read-only cache path) + one 128-bit store: 1.33x faster for the streaming version, 4.89x faster for the cache-resident version.Today I can see the pointer kind (
RigidTy::Ref) and the layout, but not whether the pointee isFreeze/Unpin, so I cannot tell&u32from&Cell<u32>. Re-deriving rustc's rules is not an option: they depend on those auto traits and the opt-level gate, and they change.Two things I want to confirm before proposing anything:
Instance::fn_abi()returns aFnAbiwhose modes arePassMode::Direct(Opaque),Pair(Opaque, Opaque)andIndirect { attrs: Opaque, .. }; the bridge wrapsrustc_target::callconv::ArgAttributeswithopaque(attr)(unstable/convert/stable/abi.rs:164). So the attribute flags are reachable only by parsing the Debug string.FreezeorUnpin. Both are auto traits, sotrait_implscannot answer it either.I see #58 listed "Expand PassMode attributes" as a task when the ABI module landed, and it was closed without it. Was that dropped for a reason, or just never picked up?
Proposal
Replace
OpaqueinDirect,PairandIndirectwith a typed mirror ofrustc_target::callconv::ArgAttributes, reusing rustc_public's existingSizeandAlign:Cast { cast: Opaque }can stay opaque. Before / after forfn f(a: &u32):Would this make sense?