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