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

_______________________________________________
dmd-internals mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/dmd-internals

Reply via email to