[GDC] Evaluation order: Please update the dmd backend

Iain Buclaw ibuclaw at gdcproject.org
Wed Apr 2 12:32:00 PDT 2014


On 2 Apr 2014 21:00, "Sarath Kodali" <sarath at dummy.com> wrote:
>
> On Wednesday, 2 April 2014 at 14:43:44 UTC, Iain Buclaw wrote:
>>>
>>>
>>>
>>> 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.
>>
>>
> I started my career, 19 years back, as a C compiler developer. So I know
what is evaluation order and argument passing order. And more importantly,
the discussion is about the *evaluation order* of "a()[] = b()[] + c()[]"
and not about what I understand or don't! So if you have any valid points
that says why this expression should be evaluated in LTR order (i.e. first
a then b and then c) let us discuss that.
> You can write a small code that evaluates "a()[] = b()[] + c()[]" before
and after the proposed modifications and check whether the evaluation order
is same w.r.t dmd. DMD v2.64 evaluates first b, then c and then a. This
behaviour conforms to the D spec.
>

Array ops follow a different behaviour to what is what normally expected.
In a() = b() + c(), the order is abc, not bca.

The fact that the current behaviour is written in the spec is not a good
reason to keep it.

>>> 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?
>>
>
> Let me take an example to explain what I'm trying to say.
>
> extern (C) int foo(int a, int b);
>
> void main(void)
> {
>     foo(a(), b());
> }
>
> With RTL function argument evaluation order and with push instructions,
the above code gets compiled by dmd as (only relevant asm code shown) (on
x86)
>
> main:
>    call b
>    push %eax
>    call a
>    push %eax
>    call foo
>
> Now if the evaluation order of function args is changed to LTR, the new
asm code would be
>
> main:
>     call a
>     mov %eax, %esi
>     call b
>     push %eax
>     push %esi
>     call foo
>
> Notice the additional mov instruction to save the return value of a() in
a temporary.  This is the impact that I'm talking about. Now if dmd backend
uses mov instructions to push args on to the stack instead of push, then
there will not be a need for temporary. But the code size will increase as
push is only 1 byte where as mov %eax offset(%esp) is 3 to 4 bytes long.
>
> Asm code with LTR func args evaluation order for extern(C) foo with mov
instrs
> main:
>      call a
>      mov %eax, (%esp)
>      call b
>      mov %eax, 0x4(%esp)
>      call foo
>
> Notice that the args are still pushed in RTL order.
>

Your point?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20140402/19818b46/attachment.html>


More information about the Digitalmars-d mailing list