`in` parameters made useful
thomas.bockman at gmail.com
Tue Aug 4 23:18:56 UTC 2020
First off, this is a great change and I am excited to be able to
use it in my own projects. Thanks for championing this.
On Friday, 31 July 2020 at 21:49:25 UTC, Mathias LANG wrote:
> B) It makes `in` take the effect of `ref` when it makes sense.
> It always pass something by `ref` if the type has elaborate
> construction / destruction (postblit, copy constructor,
> destructors). If the type doesn't have any of those it is only
> passed by `ref` if it cannot be passed in register. Some types
> (dynamic arrays, probably AA in the future) are not affected to
> allow for covariance (more on that later). The heuristics there
> still need some small improvements, e.g. w.r.t. floating points
> (currently the heuristic is based on size, and not asking the
> backend) and small struct slicing, but that should not affect
This optimization should be implemented by querying the backend,
not calculated from scratch in the frontend, which is redundant
and error-prone; the rules in the current PR are not accurate.
The correct rules are complex, platform-dependent, and depend on
the types of each function's full parameter list as a whole, not
just each parameter individually. I haven't found anywhere that
documents them, but by experimentation with LDC I have discovered
1) The size limit for most types to be passed in registers in
x86_64 is twice as large as the PR's threshold, at least on LDC.
(Array slices are passed by register because of their size and
member types, and do not need to be special-cased. A custom
slice-like struct with a pointer and a size member will be passed
by register, too.)
2) I say *most* types because there are exceptions; __vector
types, and *sometimes* structs that transitively contain only a
single __vector member (like 3d homogenous coordinates in
graphics programming) are also passed via register, although they
may be 8 times the size of a general purpose register when using
AVX2 in a 32-bit program, and probably even larger on some other
3) There are limits to how many arguments can be passed via
registers. I say "limits", plural, because different data types
may consume different types of registers; for example on x86,
`int` uses general purpose registers, whereas `float` uses SIMD
registers. These limits are architecture-dependent.
More information about the Digitalmars-d