News for hackers. Stuff that matters.
Re:Deep C (2011) by jstimpfle on Sunday October 22, 2017 @12:08PM (#15527437)
There are some places where only the programmer can know that the undefined case doesn't happen (like integer overflow). But yeah, what purpose does it serve that the order of side effects in "a() +b()" is unspecified? I assume that's for historical reasons.
Re:Deep C (2011) by tom_mellior on Sunday October 22, 2017 @12:35PM (#15527576)
A fixed evaluation order may be (very slightly) less efficient than if the compiler is allowed to reorder. Consider evaluating "x + f()" when x is global and the compiler can't prove that x cannot change during execution of f. If the order of evaluation is fixed from left to right, then it must do the following:

1. load x into a register

2. spill the register holding x to the stack

3. call f

4. reload the "local" version of x from the stack

5. add

On the other hand, if the order of evaluation can be chosen by the compiler, it can do this:

1. call f

2. load x into a register

3. add

(Details depend on whether the caller or the callee saves x, but you get the idea.)

Re:Deep C (2011) by cwzwarich on Sunday October 22, 2017 @09:41PM (#15530090)
In practice, all competitive optimizing compilers are SSA-based, and thus they fix an order of evaluation early in the compilation process. I always wondered how much performance could be gained by actually delaying decisions about evaluation order.
Re:Deep C (2011) by tom_mellior on Monday October 23, 2017 @07:51AM (#15532434)
Not sure if you're tyring to suggest that SSA-based compilers cannot do this reordering. For my example above, GCC reorders as I sketched, while Clang keeps the program order: https://godbolt.org/g/8KDvFo

I think this is done early, during lowering to a "mid-end" intermediate representation (whether SSA or not). This is the best time to do it, since the legality of this reordering is a property of the source language, which you want to forget about in the mid-end. On the other hand, in this particular example (function call vs. global variable access), I don't think there is any reason to delay this; doing the call first should never be worse than loading the global first.

As for deciding other things later, instruction scheduling and global code motion can reorder a lot of things, though calls and memory accesses block many movements.