Jump to page: 1 2
Thread overview
[dmd-internals] What does POD imply for backends
Feb 16, 2013
Johannes Pfau
Feb 16, 2013
Walter Bright
Feb 16, 2013
Johannes Pfau
Feb 16, 2013
Walter Bright
Feb 17, 2013
Iain Buclaw
Feb 17, 2013
Iain Buclaw
Feb 18, 2013
Johannes Pfau
Feb 18, 2013
Walter Bright
Feb 18, 2013
Maxim Fomin
Feb 18, 2013
Walter Bright
Feb 16, 2013
Walter Bright
February 16, 2013
While tracking down a bug in gdc I realized that gdc does nothing special for POD/non-POD types yet. That at least caused one bug where the runtime va_arg code expected a non-POD parameter to be passed on the stack but gcc passes it in registers.

So to implement (non-)POD types correctly in GDC it would be good to know:

* Non-POD types can't be passed in registers for va_arg code. What's the reason for this?
* Can Non-PODs be passed in registers to regular, non-variadic functions?
* Can Non-PODs be returned from functions in registers?
* The spec says the backend may create bit copies as convenient. Is this true for Non-PODs as well?
* In GCC a non-POD type must always have an address (i.e it can never be in registers). Is this true for D as well?

Is there anything more the backend must handle in regard to POD/non-POD types?

-- 
Johannes Pfau

_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

February 16, 2013
A non-POD cannot be in registers because its address gets taken for constructors/destructors.

On 2/16/2013 11:36 AM, Johannes Pfau wrote:
> While tracking down a bug in gdc I realized that gdc does nothing special for POD/non-POD types yet. That at least caused one bug where the runtime va_arg code expected a non-POD parameter to be passed on the stack but gcc passes it in registers.
>
> So to implement (non-)POD types correctly in GDC it would be good to know:
>
> * Non-POD types can't be passed in registers for va_arg code. What's the reason for this?
> * Can Non-PODs be passed in registers to regular, non-variadic functions?
> * Can Non-PODs be returned from functions in registers?
> * The spec says the backend may create bit copies as convenient. Is this true for Non-PODs as well?
> * In GCC a non-POD type must always have an address (i.e it can never be in registers). Is this true for D as well?
>
> Is there anything more the backend must handle in regard to POD/non-POD types?
>

_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

February 16, 2013
Am 16.02.2013 21:06, schrieb Walter Bright:
> A non-POD cannot be in registers because its address gets taken for constructors/destructors.
>
>
But creating temporary (bit) copies on the stack is still allowed for non-PODs, right?

Wouldn't it be legal to still pass non-PODs in registers when calling functions and only copying them back to the stack if the address is needed? As we pass structs by value anyway, how could this be problematic?

-- 
Johannes Pfau

_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

February 16, 2013
Also, non-POD cannot be bit-copied, meaning it cannot be copied in and out of registers.

On 2/16/2013 12:06 PM, Walter Bright wrote:
> A non-POD cannot be in registers because its address gets taken for constructors/destructors.
>
> On 2/16/2013 11:36 AM, Johannes Pfau wrote:
>> While tracking down a bug in gdc I realized that gdc does nothing special for POD/non-POD types yet. That at least caused one bug where the runtime va_arg code expected a non-POD parameter to be passed on the stack but gcc passes it in registers.
>>
>> So to implement (non-)POD types correctly in GDC it would be good to know:
>>
>> * Non-POD types can't be passed in registers for va_arg code. What's the reason for this?
>> * Can Non-PODs be passed in registers to regular, non-variadic functions?
>> * Can Non-PODs be returned from functions in registers?
>> * The spec says the backend may create bit copies as convenient. Is this true for Non-PODs as well?
>> * In GCC a non-POD type must always have an address (i.e it can never be in registers). Is this true for D as well?
>>
>> Is there anything more the backend must handle in regard to POD/non-POD types?
>>
>
> _______________________________________________
> dmd-internals mailing list
> dmd-internals@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-internals
>
>

_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

February 16, 2013
On 2/16/2013 12:17 PM, Johannes Pfau wrote:
> Am 16.02.2013 21:06, schrieb Walter Bright:
>> A non-POD cannot be in registers because its address gets taken for constructors/destructors.
>>
>>
> But creating temporary (bit) copies on the stack is still allowed for non-PODs, right?

No.

>
> Wouldn't it be legal to still pass non-PODs in registers when calling functions and only copying them back to the stack if the address is needed? As we pass structs by value anyway, how could this be problematic?
>

No, not allowed. Consider why there are copy constructors, and what they do.
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

February 17, 2013
On Feb 16, 2013 8:27 PM, "Walter Bright" <walter@digitalmars.com> wrote:
>
>
> On 2/16/2013 12:17 PM, Johannes Pfau wrote:
>>
>> Am 16.02.2013 21:06, schrieb Walter Bright:
>>>
>>> A non-POD cannot be in registers because its address gets taken for
constructors/destructors.
>>>
>>>
>> But creating temporary (bit) copies on the stack is still allowed for
non-PODs, right?
>
>
> No.
>
>
>>
>> Wouldn't it be legal to still pass non-PODs in registers when calling
functions and only copying them back to the stack if the address is needed? As we pass structs by value anyway, how could this be problematic?
>>
>
> No, not allowed. Consider why there are copy constructors, and what they
do.

Just catching up to speed with this, would this be passed by value on the stack or by reference?  (The latter would be easier, however the former could probably be forced by adding some language hook to the backend in gdc as a temporary workaround).

Thanks,
Iain.


February 17, 2013
On Feb 17, 2013 9:50 PM, "Iain Buclaw" <ibuclaw@ubuntu.com> wrote:
>
>
> On Feb 16, 2013 8:27 PM, "Walter Bright" <walter@digitalmars.com> wrote:
> >
> >
> > On 2/16/2013 12:17 PM, Johannes Pfau wrote:
> >>
> >> Am 16.02.2013 21:06, schrieb Walter Bright:
> >>>
> >>> A non-POD cannot be in registers because its address gets taken for
constructors/destructors.
> >>>
> >>>
> >> But creating temporary (bit) copies on the stack is still allowed for
non-PODs, right?
> >
> >
> > No.
> >
> >
> >>
> >> Wouldn't it be legal to still pass non-PODs in registers when calling
functions and only copying them back to the stack if the address is needed? As we pass structs by value anyway, how could this be problematic?
> >>
> >
> > No, not allowed. Consider why there are copy constructors, and what
they do.
>
> Just catching up to speed with this, would this be passed by value on the
stack or by reference?  (The latter would be easier, however the former could probably be forced by adding some language hook to the backend in gdc as a temporary workaround).
>
> Thanks,
> Iain.

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.

Regards
Iain.


February 18, 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

_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

February 18, 2013
On 2/17/2013 1:59 PM, Iain Buclaw wrote:
>
> 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
>

Whenever you make a copy of a non-POD value, you have to (for example) build an exception handling frame to destruct it if, in the meantime, an exception is thrown. This is not only expensive, but it doesn't work if the value lives in registers.
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

February 18, 2013
2013/2/18 Walter Bright <walter@digitalmars.com>

>
> On 2/17/2013 1:59 PM, Iain Buclaw wrote:
>
>>
>> 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
>>
>>
> Whenever you make a copy of a non-POD value, you have to (for example) build an exception handling frame to destruct it if, in the meantime, an exception is thrown. This is not only expensive, but it doesn't work if the value lives in registers.
>
>
What a coincidence.  I hit today issue http://d.puremagic.com/issues/show_bug.cgi?id=8563 Are you implying that temporaries of POD structures are impossible?


« First   ‹ Prev
1 2