[dmd-internals] What does POD imply for backends
Johannes Pfau
johannespfau at googlemail.com
Mon Feb 18 10:29:59 PST 2013
Am 17.02.2013 22:59, schrieb Iain Buclaw:
>
> By the way Johannes, the issue is clear I think. You can't make
> temporaries with non-POD structs? This is something gdc is a bit
> zealous in doing this around a lot of the code generation. So
> addressing that would certainly fix problems around the other thread
> where you were marking the type as addressable to prevent it being
> passed in registers.
>
I probably don't have much experience with copy-ctors/postblits and that
kind of compiler stuff in general so this issue isn't as clear to me.
Indeed, basically the problem is just that GDC should not generate
"copies" of non-POD types. GDC mainly creates these temporaries to force
left to right evaluation of function arguments. But there are some cases
where I don't know how we could guarantee the right evaluation order
without making copies. And the gcc backend is very picky with not making
copies as well:
Some examples:
For this code:
---
struct Date{this(int){} ubyte a;}
Date getDate();
void setDate(Date d);
---
The frontend sometimes produces this code:
--
pod.setDate (pod.getDate ())
--
Now how can we handle this in the backend? We can't make a temporary
copy and the gcc backend doesn't compile that without a temporary value
either as it would have to make a copy for the setDate parameter on the
correct place on the stack by itself. Even worse, how can we guarantee
the correct evaluation order of the parameters if we can't evaluate them
to temporaries?
There's a comment in dmds expression.c which says "The struct value
returned from the function is transferred to the function", it seems the
value is copied/moved to a different location on the stack by the dmd
backend, which is called "transfer" by dmd, but gcc just calls it
create_tmp_var and refuses to do that with ADDRESSABLE (non-POD) types.
When copy ctors are involved, the frontend sometimes generates this:
--
pod.setDate ( (__cpcttmp6 = {._year=2, ._month=1, ._day=1}), __cpcttmp6)
--
This is the only place where we really can do something in the backend:
We can move op0 of the compound expression out of the function call and
rewrite it like this:
--
__cpcttmp6 = {._year=2, ._month=1, ._day=1},
pod.setDate ( __cpcttmp6)
--
But if there's no copy ctor involved, the frontend sometimes also
generates this:
--
pod.setDate ({._year=2, ._month=1, ._day=1});
--
Now the literal has to be copied onto the stack to call setDate and gcc
refuses to do this. We also can't make a copy of the literal on the
stack in gdc as we're not allowed to do this.
Maybe I'm being ignorant here but to me it seems as if we have to
explicitly make those copies in the frontend. For example for the third
case, gcc would accept this code:
Date __tmp1 = {._year=2, ._month=1, ._day=1}
pod.setDate (_tmp1);
--
Johannes Pfau
More information about the dmd-internals
mailing list