[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