[GDC] Evaluation order: Please update the dmd backend

Sarath Kodali sarath at dummy.com
Wed Apr 2 11:59:36 PDT 2014


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.

>> 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.

>
>> 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.

- Sarath


More information about the Digitalmars-d mailing list