> If the copy is made by the callee, then the callee can avoid a copy if it can guarantee that the caller's version of the object isn't changed before the callee uses it, and at most one copy is made.
So the callee has to know what every caller of it will ever do? That's ... an ABI. The whole point is that functions can exist in a vacuum without knowledge of who they will be called by.
To be clear, I think it would be really cool if compilers could generate ad-hoc calling conventions using lto to optimize spillage, but that's not really useful as an ABI.
> would be interesting to analyze a bunch of real-world code and see A) how often would my version create a copy, B) how often does the MS/ARM/RISC-5 version have to make a copy, C) how often would your version make a copy, and D) how often would your version require two copies.
> Would also be interesting to see an analysis of code bloat due to copying parameters
The ABI I had in mind was similar to the AArch64 ABI:
>If the argument type is a Composite Type that is larger than 16 bytes, then the argument is copied to memory allocated by the caller and the argument is replaced by a pointer to the copy.
But with a slight modification to put the copy in the callee:
>If the argument type is a Composite Type that is larger than 16 bytes, then argument is replaced by a pointer to the copy. The callee copies the pointed-to object into memory allocated by the callee.
This immediately has the advantage of less binary bloats, because the amount of parameter copying instructions in the binary will become O(number of functions) rather than O(number of function calls). (As an aside: That can probably be a huge advantage for C++ with its large, inlined copy constructors.)
When the copy is made in the callee, we can start identifying cases where a copy isn't necessary, or cases where only certain parts of the struct has to be copied. It would have to be fairly conservative though, since unlike with your ABI, there would be no guarantee made by the caller that there are no other references to the parameter.
I think my version is a clear and obvious improvement over the status quo, with decreased binary sizes and as good or better performance. Your version is more risky where the worst case is two copies per large parameter but, your version will probably achieve zero copies in way more cases than my version. "Low risk / medium reward" versus "medium risk / probably high reward".
---
Anyways, I might end up writing a blog post on this stuff. If I do, it will refer to your blog post. How should I refer to you? Moonchild or elronnd or something else?
So the callee has to know what every caller of it will ever do? That's ... an ABI. The whole point is that functions can exist in a vacuum without knowledge of who they will be called by.
To be clear, I think it would be really cool if compilers could generate ad-hoc calling conventions using lto to optimize spillage, but that's not really useful as an ABI.
> would be interesting to analyze a bunch of real-world code and see A) how often would my version create a copy, B) how often does the MS/ARM/RISC-5 version have to make a copy, C) how often would your version make a copy, and D) how often would your version require two copies.
> Would also be interesting to see an analysis of code bloat due to copying parameters
I agree!