Jump to page: 1 2
Thread overview
[GDC] Evaluation order: Please update the dmd backend
Apr 01, 2014
Johannes Pfau
Apr 01, 2014
Daniel Murphy
Apr 01, 2014
Iain Buclaw
Apr 01, 2014
Daniel Murphy
Apr 02, 2014
Johannes Pfau
Apr 01, 2014
Sarath Kodali
Apr 01, 2014
Timon Gehr
Apr 02, 2014
Johannes Pfau
Apr 02, 2014
Sarath Kodali
Apr 02, 2014
Iain Buclaw
Apr 02, 2014
Sarath Kodali
Apr 02, 2014
Iain Buclaw
Apr 02, 2014
Sarath Kodali
Apr 02, 2014
Iain Buclaw
Apr 02, 2014
Johannes Pfau
Apr 02, 2014
Johannes Pfau
Apr 02, 2014
Sarath Kodali
Apr 02, 2014
Timon Gehr
Oct 01, 2014
Kenji Hara
April 01, 2014
I started fixing GDC bug #8 (*) which is basically that array op
evaluation order currently depends on the target architecture. Consider
this example:
a()[] = b()[] + c()[];
The order in which c,a,b are called is currently architecture specific.
As stated in that bug report by Andrei we want this to evaluate LTR, so
a() first, then b(), then c().

These operations are actually rewritten to calls to extern(C) functions. Arguments to C function should be evaluated LTR as well, but dmd currently evaluates them RTL (GDC: architecture dependent). In order to fix the array op bug in gdc we have to define the evaluation order for extern(C) function parameters.

So I've changed extern(C) functions to evaluate LTR in GDC and then had
to change the array op code, cause that assumed extern(C) function
evaluate RTL. Now I'd like to push these array op changes into dmd as we
want to keep as few gdc specific changes as possible and dmd (and ldc)
will need these changes anyway as soon as they implement extern(C)
functions as LTR. This is required by dmd issue #6620 (**) and the
language spec (***).

However, if we apply only these changes the array op order reverses for DMD as it evaluates extern(C) function arguments RTL.

So I need someone with dmd backend knowledge to fix the evaluation
order of extern(C) function parameters to be LTR.
Evaluation order of assignments should also be fixed to be LTR in the
dmd backend. Although not strictly required for the array op changes
it'd be inconsistent to have array op assignments execute LTR but
normal assignments RTL:
a()[] = b()[] + c()[]; //Array op assignment
a() = b() + c();       //Normal assignment
 |      |    |
 1      2    3

The frontend changes for dmd are here:
https://github.com/jpf91/dmd/tree/fixOrder
Frontend:
https://github.com/jpf91/dmd/commit/5d61b812977dbdc1f99100e2fbaf1f45e9d25b03
Test cases:
https://github.com/jpf91/dmd/commit/82bffe0862b272f02c27cc428b22a7dd113b4a07

Druntime changes (need to be applied at the same time as dmd changes) https://github.com/jpf91/druntime/tree/fixOrder https://github.com/jpf91/druntime/commit/f3f6f49c595d4fb25fb298e435ad1874abac516d


(*)   http://bugzilla.gdcproject.org/show_bug.cgi?id=8
(**)  https://d.puremagic.com/issues/show_bug.cgi?id=6620
(***) https://github.com/D-Programming-Language/dlang.org/pull/6
April 01, 2014
"Johannes Pfau"  wrote in message news:lhe96q$27ua$1@digitalmars.com...

> So I need someone with dmd backend knowledge to fix the evaluation
> order of extern(C) function parameters to be LTR.
> Evaluation order of assignments should also be fixed to be LTR in the
> dmd backend. Although not strictly required for the array op changes
> it'd be inconsistent to have array op assignments execute LTR but
> normal assignments RTL:
> a()[] = b()[] + c()[]; //Array op assignment
> a() = b() + c();       //Normal assignment
>  |      |    |
>  1      2    3

It shouldn't need backend changes, just a glue layer fix to evaluate all args to a temporary before the actual call expression.

Something similar to the way https://d.puremagic.com/issues/show_bug.cgi?id=8396 was done should work. 

April 01, 2014
On 1 Apr 2014 14:45, "Daniel Murphy" <yebbliesnospam@gmail.com> wrote:
>
> "Johannes Pfau"  wrote in message news:lhe96q$27ua$1@digitalmars.com...
>
>
>> So I need someone with dmd backend knowledge to fix the evaluation
>> order of extern(C) function parameters to be LTR.
>> Evaluation order of assignments should also be fixed to be LTR in the
>> dmd backend. Although not strictly required for the array op changes
>> it'd be inconsistent to have array op assignments execute LTR but
>> normal assignments RTL:
>> a()[] = b()[] + c()[]; //Array op assignment
>> a() = b() + c();       //Normal assignment
>>  |      |    |
>>  1      2    3
>
>
> It shouldn't need backend changes, just a glue layer fix to evaluate all
args to a temporary before the actual call expression.
>
> Something similar to the way
https://d.puremagic.com/issues/show_bug.cgi?id=8396 was done should work.

So you can write the patches then? :o)


April 01, 2014
"Iain Buclaw" <ibuclaw@gdcproject.org> wrote in message news:mailman.13.1396357117.19942.digitalmars-d@puremagic.com...

> So you can write the patches then? :o)

Sure, as long as you're not in a hurry.

April 01, 2014
On Tuesday, 1 April 2014 at 11:50:51 UTC, Johannes Pfau wrote:
> I started fixing GDC bug #8 (*) which is basically that array op
> evaluation order currently depends on the target architecture. Consider
> this example:
> a()[] = b()[] + c()[];
> The order in which c,a,b are called is currently architecture specific.
> As stated in that bug report by Andrei we want this to evaluate LTR, so
> a() first, then b(), then c().
>
> These operations are actually rewritten to calls to extern(C)
> functions. Arguments to C function should be evaluated LTR as well, but
> dmd currently evaluates them RTL (GDC: architecture dependent). In order
> to fix the array op bug in gdc we have to define the evaluation order
> for extern(C) function parameters.
>
> So I've changed extern(C) functions to evaluate LTR in GDC and then had
> to change the array op code, cause that assumed extern(C) function
> evaluate RTL. Now I'd like to push these array op changes into dmd as we
> want to keep as few gdc specific changes as possible and dmd (and ldc)
> will need these changes anyway as soon as they implement extern(C)
> functions as LTR. This is required by dmd issue #6620 (**) and the
> language spec (***).
>
> However, if we apply only these changes the array op order reverses for
> DMD as it evaluates extern(C) function arguments RTL.
>
> So I need someone with dmd backend knowledge to fix the evaluation
> order of extern(C) function parameters to be LTR.
> Evaluation order of assignments should also be fixed to be LTR in the
> dmd backend. Although not strictly required for the array op changes
> it'd be inconsistent to have array op assignments execute LTR but
> normal assignments RTL:
> a()[] = b()[] + c()[]; //Array op assignment
> a() = b() + c();       //Normal assignment
>  |      |    |
>  1      2    3
>
> The frontend changes for dmd are here:
> https://github.com/jpf91/dmd/tree/fixOrder
> Frontend:
> https://github.com/jpf91/dmd/commit/5d61b812977dbdc1f99100e2fbaf1f45e9d25b03
> Test cases:
> https://github.com/jpf91/dmd/commit/82bffe0862b272f02c27cc428b22a7dd113b4a07
>
> Druntime changes (need to be applied at the same time as dmd changes)
> https://github.com/jpf91/druntime/tree/fixOrder
> https://github.com/jpf91/druntime/commit/f3f6f49c595d4fb25fb298e435ad1874abac516d
>
>
> (*)   http://bugzilla.gdcproject.org/show_bug.cgi?id=8
> (**)  https://d.puremagic.com/issues/show_bug.cgi?id=6620
> (***) https://github.com/D-Programming-Language/dlang.org/pull/6

The evaluation order of assign operators should not be LTR as they have right associativity. In "a = b = c", c has to be evaluated first, then b and then a. Similarly, in "a = b + c", "b+c" has to be evaluated first before a is evaluated. Otherwise it will be very confusing, that in some cases it is LTR and in some it is RTL.
Other binary operators like "+" have left associativity, and hence evaluation for these should be LTR as mentioned in D spec.

The C spec requires that the function arguments are to be pushed in RTL order.
The DMD codegen uses pushl x86 instructions for pushing args. If the frontend changes the func args evaluation order to LTR, then the backend has to be modified to use mov x86 instructions as is done by gcc codegen.

- Sarath

April 01, 2014
On 04/01/2014 08:40 PM, Sarath Kodali wrote:
> ...
>
> The evaluation order of assign operators should not be LTR as they have
> right associativity. In "a = b = c", c has to be evaluated first, then b
> and then a. Similarly, in "a = b + c", "b+c" has to be evaluated first
> before a is evaluated. Otherwise it will be very confusing, that in some
> cases it is LTR and in some it is RTL.

Note that this is after a paragraph that suggests to make evaluation in some cases LTR and in some RTL.

> Other binary operators like "+" have left associativity, and hence
> evaluation for these should be LTR as mentioned in D spec.
> ...

What's the presumed relation between associativity and evaluation order?

In particular, the ternary operator ?: is right associative. How on earth are you going to evaluate it right to left?

> The C spec requires that the function arguments are to be pushed in RTL
> order.

[citation needed]

> The DMD codegen uses pushl x86 instructions for pushing args. If the
> frontend changes the func args evaluation order to LTR, then the backend
> has to be modified  to use mov x86 instructions as is done by gcc codegen.
>
> - Sarath
>

The backend does not necessarily have to be modified to achieve this.
April 02, 2014
Am Wed, 02 Apr 2014 00:04:42 +0200
schrieb Timon Gehr <timon.gehr@gmx.ch>:

> On 04/01/2014 08:40 PM, Sarath Kodali wrote:
> > ...
> >
> > The evaluation order of assign operators should not be LTR as they have right associativity. In "a = b = c", c has to be evaluated first, then b and then a. Similarly, in "a = b + c", "b+c" has to be evaluated first before a is evaluated. Otherwise it will be very confusing, that in some cases it is LTR and in some it is RTL.
> 
> Note that this is after a paragraph that suggests to make evaluation in some cases LTR and in some RTL.
> 
> > Other binary operators like "+" have left associativity, and hence
> > evaluation for these should be LTR as mentioned in D spec.
> > ...
> 
> What's the presumed relation between associativity and evaluation order?
> 
> In particular, the ternary operator ?: is right associative. How on earth are you going to evaluate it right to left?
> 
> > The C spec requires that the function arguments are to be pushed in RTL order.
> 
> [citation needed]

The C standard explicitly doesn't define the evaluation order: http://stackoverflow.com/questions/376278/parameter-evaluation-order-before-a-function-calling-in-c/376333#376333

It's probably the platform ABI for x86 which specifies this, however this is architecture specific. For example ARM evaluates LTR.

> 
> > The DMD codegen uses pushl x86 instructions for pushing args. If the frontend changes the func args evaluation order to LTR, then the backend has to be modified  to use mov x86 instructions as is done by gcc codegen.
> >
> > - Sarath
> >
> 
> The backend does not necessarily have to be modified to achieve this.

If this point is about performance it doesn't matter anyway as parameters for extern(D) functions are already evaluated LTR and D functions are much more common than C functions.

http://dpaste.dzfl.pl/f5a5caeea8ed
April 02, 2014
Am Wed, 2 Apr 2014 00:54:40 +1100
schrieb "Daniel Murphy" <yebbliesnospam@gmail.com>:

> 
> "Iain Buclaw" <ibuclaw@gdcproject.org> wrote in message news:mailman.13.1396357117.19942.digitalmars-d@puremagic.com...
> 
> > So you can write the patches then? :o)
> 
> Sure, as long as you're not in a hurry.
> 

Thanks. There's no need to hurry ;-)
April 02, 2014
On Tuesday, 1 April 2014 at 22:04:43 UTC, Timon Gehr wrote:
> On 04/01/2014 08:40 PM, Sarath Kodali wrote:
>> ...
>>
>> The evaluation order of assign operators should not be LTR as they have
>> right associativity. In "a = b = c", c has to be evaluated first, then b
>> and then a. Similarly, in "a = b + c", "b+c" has to be evaluated first
>> before a is evaluated. Otherwise it will be very confusing, that in some
>> cases it is LTR and in some it is RTL.
>
> Note that this is after a paragraph that suggests to make evaluation in some cases LTR and in some RTL.
>

There are 2 evaluation orders that need to be considered while evaluating expressions - the evaluation order of operators and the the evaluation order of operands of an operator. The evaluation order of operators is well defined and is done according to its precedence and associativity. However the evaluation order of operands for some of the binary operators is not defined. D left it undefined for assign operator. So in "a=b", the compiler can choose to evaluate a first and then b. However in "a=b=c", "b=c" has to be evaluated first due to right associativity of '=' operator. Similarly in "a=b+c", "b+c" has to be evaluated first due to higher precedence of + operator over = operator.  In both these cases, the right operand of = operator is evaluated first and then the left operand. So it naturally follows that even in the unspecified case (a=b), the right operand should be evaluated first so that it is consistent with other cases of = operator. All this means, the evaluation order of operands also should be according to the associativity of its operator. You can test this with other right or left associative binary operators.


>> Other binary operators like "+" have left associativity, and hence
>> evaluation for these should be LTR as mentioned in D spec.
>> ...
>
> What's the presumed relation between associativity and evaluation order?
>
> In particular, the ternary operator ?: is right associative. How on earth are you going to evaluate it right to left?
>
>> The C spec requires that the function arguments are to be pushed in RTL
>> order.
>
> [citation needed]
>

You can get that info from any C ABI doc from Intel or AMD or some other arch.

>> The DMD codegen uses pushl x86 instructions for pushing args. If the
>> frontend changes the func args evaluation order to LTR, then the backend
>> has to be modified  to use mov x86 instructions as is done by gcc codegen.
>>
>> - Sarath
>>
>
> The backend does not necessarily have to be modified to achieve this.

Can you please explain how you are going to do that without modifying the backend?

- Sarath
April 02, 2014
On 2 Apr 2014 09:52, "Sarath Kodali" <sarath@dummy.com> wrote:
>
> On Tuesday, 1 April 2014 at 22:04:43 UTC, Timon Gehr wrote:
>>
>> On 04/01/2014 08:40 PM, Sarath Kodali wrote:
>>>
>>> ...
>>>
>>> The evaluation order of assign operators should not be LTR as they have right associativity. In "a = b = c", c has to be evaluated first, then b and then a. Similarly, in "a = b + c", "b+c" has to be evaluated first before a is evaluated. Otherwise it will be very confusing, that in some cases it is LTR and in some it is RTL.
>>
>>
>> Note that this is after a paragraph that suggests to make evaluation in
some cases LTR and in some RTL.
>>
>
> There are 2 evaluation orders that need to be considered while evaluating
expressions - the evaluation order of operators and the the evaluation order of operands of an operator. The evaluation order of operators is well defined and is done according to its precedence and associativity. However the evaluation order of operands for some of the binary operators is not defined. D left it undefined for assign operator. So in "a=b", the compiler can choose to evaluate a first and then b. However in "a=b=c", "b=c" has to be evaluated first due to right associativity of '=' operator. Similarly in "a=b+c", "b+c" has to be evaluated first due to higher precedence of + operator over = operator.  In both these cases, the right operand of = operator is evaluated first and then the left operand. So it naturally follows that even in the unspecified case (a=b), the right operand should be evaluated first so that it is consistent with other cases of = operator. All this means, the evaluation order of operands also should be according to the associativity of its operator. You can test this with other right or left associative binary operators.
>
>
>
>>> Other binary operators like "+" have left associativity, and hence
>>> evaluation for these should be LTR as mentioned in D spec.
>>> ...
>>
>>
>> What's the presumed relation between associativity and evaluation order?
>>
>> In particular, the ternary operator ?: is right associative. How on
earth are you going to evaluate it right to left?
>>
>>> The C spec requires that the function arguments are to be pushed in RTL order.
>>
>>
>> [citation needed]
>>
>
> You can get that info from any C ABI doc from Intel or AMD or some other
arch.
>

That's order of pushing arguments, not order of evaluation.  Also, heavy stress on the words *Intel* and *AMD*.  That is in no way a C standard. :)


« First   ‹ Prev
1 2