Bug 9666 – Invalid struct passing + redundant struct copy on struct assignment

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-03-08T04:25:14Z
Last change time
2024-12-13T18:04:33Z
Assigned to
No Owner
Creator
Maxim Fomin
See also
https://issues.dlang.org/show_bug.cgi?id=24836
Moved to GitHub: dmd#18530 →

Comments

Comment #0 by maxim — 2013-03-08T04:25:14Z
For code like: module e; struct Date { //Make sure this is not a POD this(this){} short _year = 2; ubyte _month = 1; ubyte _day = 1; } void setDate(Date d) { Date x; x = d; } void main() { Date d; setDate(d); } dmd generates two copies, first - when passing argument "d" to setDate(), and second - when assigning parameter "d" to x. The latter is redundant. #dmd main.d -v -release .... function e.setDate Date x = _D1e4Date6__initZ; x.opAssign((Date __cpcttmp6 = __cpcttmp6.__cpctor(d); , __cpcttmp6)) function D main Date d = _D1e4Date6__initZ; setDate((Date __cpcttmp7 = __cpcttmp7.__cpctor(d);, __cpcttmp7)) .... This frontend pseudo-code survives CT and is present in object file as a call to __cpctor inside setDate() asm output. Originally this comes from dmd-internal discussion where it was found that there is another dmd bug - it passes nonPOD struct in register. So, there are two issues here. Link: http://forum.dlang.org/thread/[email protected]
Comment #1 by k.hara.pg — 2013-03-08T05:00:03Z
(In reply to comment #0) > dmd generates two copies, first - when passing argument "d" to setDate(), and > second - when assigning parameter "d" to x. The latter is redundant. > > #dmd main.d -v -release > .... > function e.setDate > Date x = _D1e4Date6__initZ; > x.opAssign((Date __cpcttmp6 = __cpcttmp6.__cpctor(d); , __cpcttmp6)) > function D main > Date d = _D1e4Date6__initZ; > setDate((Date __cpcttmp7 = __cpcttmp7.__cpctor(d);, __cpcttmp7)) > .... > > This frontend pseudo-code survives CT and is present in object file as a call > to __cpctor inside setDate() asm output. This is correct behavior. Date has user defined postblit, so its assignment operator is implicitly generated as opAssign. And, it is implemented by copy-and-swap method. struct Date { this(this) { ... } ref Date opAssign(Date rhs) { swap(this, rhs); } } void setDate(Date d) { Date x; //x = d; // is lowered to: x.opAssign(d); // d is copied. // and then it is swapped with x in Date.opAssign. } The copy in setDate is essentially necessary. It may be removed with _smart optimizer_, but today's dmd doesn't do it enough. So I think this is an enhancement that requests more optimization.
Comment #2 by bugzilla — 2020-08-09T08:58:58Z
I agree it's an optimization possibility, not a bug.
Comment #3 by robert.schadek — 2024-12-13T18:04:33Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18530 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB