digitalmars.D.learn - What can be done with copy constructors / post blits
- Johannes Pfau (15/19) Mar 01 2013 When trying to implement non-POD types for gdc some time ago I asked on
- monarch_dodra (14/43) Mar 01 2013 Unsure what "pass in register" means. As in storing the data
- Johannes Pfau (32/84) Mar 01 2013 Because of that the GCC backend complains a lot when trying to fit D
When trying to implement non-POD types for gdc some time ago I asked on the dmd mailing list what the backend is actually supposed to do for non-POD types. Walter answered that they should never be passed in registers: --------------------------Wouldn't it be legal to still pass non-PODs in registers when calling functions and only copying them back to the stack if the address is needed? As we pass structs by value anyway, how could this be problematic?No, not allowed. Consider why there are copy constructors, and what they do. -------------------------- Now that's probably because of my weak C++ background, but what can you do with copy constructors that would break if the compiler passed the non-POD type in a register to a function? Note: If I interpret this assembly properly dmd does do exactly what I proposed and what's illegal according to Walter: D: https://gist.github.com/jpf91/5064703 ASM: https://gist.github.com/jpf91/5064764
Mar 01 2013
On Friday, 1 March 2013 at 13:59:08 UTC, Johannes Pfau wrote:When trying to implement non-POD types for gdc some time ago I asked on the dmd mailing list what the backend is actually supposed to do for non-POD types. Walter answered that they should never be passed in registers: --------------------------Unsure what "pass in register" means. As in storing the data before calling the function in a register, as opposed to the stack? In C++, if you ever copy or move anything, then a CC must be called. Because of this, I'd say you can't place a non POD in a register, because that would imply CC'ing the thing just to place it in said register. In D, it is a little different, because you are allowed to move stuff in-memory without ever calling the CC. This is "D move semantics", and it works because D bans internal pointers. Because of this, I'd say you can pass by register. Maybe Walter gave you his "reflex" C++ reply, and didn't realize that D relaxed semantics changed the rules?Wouldn't it be legal to still pass non-PODs in registers when calling functions and only copying them back to the stack if the address is needed? As we pass structs by value anyway, how could this be problematic?No, not allowed. Consider why there are copy constructors, and what they do. -------------------------- Now that's probably because of my weak C++ background, but what can you do with copy constructors that would break if the compiler passed the non-POD type in a register to a function? Note: If I interpret this assembly properly dmd does do exactly what I proposed and what's illegal according to Walter: D: https://gist.github.com/jpf91/5064703 ASM: https://gist.github.com/jpf91/5064764
Mar 01 2013
Am Fri, 01 Mar 2013 15:09:11 +0100 schrieb "monarch_dodra" <monarchdodra gmail.com>:On Friday, 1 March 2013 at 13:59:08 UTC, Johannes Pfau wrote:Because of that the GCC backend complains a lot when trying to fit D Non-PODS into that C++ model: The backend refuses to create any temporaries, move anything etc. I'll probably have to ask on the GCC mailing list what to do about this, it seems there's no good solution right now. (Maybe C++11 move semantics can help)When trying to implement non-POD types for gdc some time ago I asked on the dmd mailing list what the backend is actually supposed to do for non-POD types. Walter answered that they should never be passed in registers: --------------------------Unsure what "pass in register" means. As in storing the data before calling the function in a register, as opposed to the stack? In C++, if you ever copy or move anything, then a CC must be called. Because of this, I'd say you can't place a non POD in a register, because that would imply CC'ing the thing just to place it in said register.Wouldn't it be legal to still pass non-PODs in registers when calling functions and only copying them back to the stack if the address is needed? As we pass structs by value anyway, how could this be problematic?No, not allowed. Consider why there are copy constructors, and what they do. -------------------------- Now that's probably because of my weak C++ background, but what can you do with copy constructors that would break if the compiler passed the non-POD type in a register to a function? Note: If I interpret this assembly properly dmd does do exactly what I proposed and what's illegal according to Walter: D: https://gist.github.com/jpf91/5064703 ASM: https://gist.github.com/jpf91/5064764In D, it is a little different, because you are allowed to move stuff in-memory without ever calling the CC. This is "D move semantics", and it works because D bans internal pointers. Because of this, I'd say you can pass by register.The rules in DMD are a little weird though: * For normal functions the value is passed in registers, but for varargs functions it's passed on the stack! Any idea what could be different here? (This is actually a bug in gdc right now cause gdc passes those in registers even to varargs functions) * DMD never returns a value in a register. It uses the hidden reference trick described in the SysV ABI: func(A* storage) { *storage = result_value; } instead of simply returning A by value. Any idea why this is necessary?Maybe Walter gave you his "reflex" C++ reply, and didn't realize that D relaxed semantics changed the rules?Yep, internal pointers was the only thing which I though could break, but isn't allowed in D anyway. That's what I thought, maybe I'll have to ask again. Pass in register in this case means putting the value into a specific register before calling the function, not on the stack (memory). The details are described in the SYSv x86_64 ABI. The important difference here is that a value passed on the stack has an address, a value passed in a register not. GCC has a notion of an ADRESSABLE type which is then probably not useful for gdc as it's too strict, it always prevents passing these types in registers (and produces many errors ;-).
Mar 01 2013