Inreg firstclass structs

Hi all,

I've been discussing parameter attributes and their impact on first-class
struct parameters. Duncan and I came to the conclusion that the only attribute
that could be applied to structs currently, is the inreg attribute. However,
since there is no support anywhere for that currently (transformation passes
and backends?), it might be better to disallow the inreg attribute for struct
parameters and return values for now.

AFAICS, this would require modification to ParamAttr::typeIncompatible and the
langref.

Any objections?

Gr.

Matthijs

MO, inreg sounds like a great way to distinguish between byval structs
that should be passed/returned in memory and those that should be
passed in registers, especially in situations where the same LLVM
struct should be passed/returned in different ways depending on the
type in the source code. (For example, if I recall correctly, x86
distinguishes between returning a struct with 2 floats and a complex
float, and the obvious way to encode that distinction into the
assembly language is with inreg.)

That said, since it isn't supported, I don't have any objections to
disabling it for the moment. If I recall correctly, it already
asserts, so this would mostly be a documentation change.

-Eli

I agree. Long term, we want to be able to handle certain x86-64 ABI situations just like this.

-Chris

Hi Eli,

MO, inreg sounds like a great way to distinguish between byval structs
that should be passed/returned in memory and those that should be
passed in registers, especially in situations where the same LLVM
struct should be passed/returned in different ways depending on the
type in the source code.

The problem here is that byval applies to a pointer-to-struct and inreg only
to a first class struct (AFAICS at least). Applying inreg (and possibly also
byval) to a pointer-to-struct will mean to pass the pointer in a register,
right?

Still, this will allow for multiple ways of passing a struct:

1) Just a pointer, no attributes. This is just passing a pointer, with no
special semantics, hidden copies, etc.
2) A byval pointer. This implies that the struct is passed through (heap) memory and
that someone is supposed to be making copies of it.
3) A first class struct. I'm not sure how this is supposed to be passed, but I
can imagine it being passed in registers or on the stack (backend's choice).
4) A first class inreg struct. This leaves only a single choice: Each element
should be passed in registers.

So, having inreg on a struct actually seems to make sense, come to think of
it. I'm completely clueless about how backends implement this (and how this
relates to language ABI's. I can imagine that things like the inreg parameter
can be used by the frontend to encode a specific ABI in the IR?)

That said, since it isn't supported, I don't have any objections to
disabling it for the moment. If I recall correctly, it already
asserts, so this would mostly be a documentation change.

I'm not sure where it should assert then (easy to find out, though :-p). I
would expect this to be in ParamAttrs::typeIncompatible, but it isn't
currently.

I will see about disabling it at that spot. However, the only transformation
pass that should be concerned with the attribute (AFAICS) is argpromotion,
which should be rather trivial to update. After that, only backend support is
blocking this.

Gr.

Matthijs