Skip to content

PassMode carries ArgAttributes only as Opaque; can we expose a typed mirror? #132

Description

@nihalpasham

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:

  1. 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.
  2. 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?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions