[GDC] Evaluation order: Please update the dmd backend

Iain Buclaw ibuclaw at gdcproject.org
Wed Apr 2 07:43:19 PDT 2014


On 2 April 2014 15:04, Sarath Kodali <sarath at dummy.com> wrote:
> On Wednesday, 2 April 2014 at 08:02:36 UTC, Iain Buclaw wrote:
>>
>> On 2 Apr 2014 09:52, "Sarath Kodali" <sarath at 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. :)
>
>
> Please do not get confused between operands evaluation order in an
> expression and arguments passing order to a function. Those are two
> different things. I was talking about both of them because both of them are
> involved in the evaluation of a()[] = b()[] + c()[]. To a programmer this is
> an expression that should follow expression evaluation rules. To a compiler
> implementer, this is a builtin function call whose arguments should be
> evaluated such that the expression evaluation rules are not broken.
>

Right.  But order of evaluation is Language-specific, order of pushing
arguments is Target-specific.  Both are completely indifferent from
each other, and this is what I think you are not understanding.


> If you read the last para in my first post, I was talking about argument
> pushing order *not* evaluation order for function args. The function
> argument passing order (called calling convention) is not defined by C spec,
> but by C ABI spec of any architecture. In all the C calling conventions, the
> first few arguments are passed in registers and the remaining on the stack.
> On Linux+x86, all the arguments are passed on the stack. For C, the
> arguments that are passed on the stack are in reverse order i.e RTL. Since
> the proposal was to change the argument evaluation order for extern(C)
> functions,

And the pushing order is unaffected, so why bring it up in the first place?


> I was merely pointing out that this will have an impact on the
> dmd backend because it uses pushl instructions. Notice that for extern (C)
> functions, the argument evaluation order and argument pushing order is same.
> So dmd evaluates an argument and pushes it immediately. If the evaluation
> order is opposite to that of the pushing order, then it cannot immediately
> push the argument that it has evaluated. However if it uses movl
> instructions as is done by gcc backend, then there is no issue.
>

Actually, the gcc backend does the same if the parameter passed has
not had all side effects removed from it.


More information about the Digitalmars-d mailing list