Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

>I was interested because I've started adopting the single assignment style in my own code

What benefit have you seen from doing this? Genuinely curious.



It does have some positive consequences for optimization. For example, if you "recycle" local variables by using them again for different purposes, you might think you're saving stack space by sharing the space. You're not. Optimizers are pretty good at storing multiple variables in the same stack slot when their usages (i.e. "live ranges") are disjoint.

On the other hand, if you write:

    int i = value;
    ... use i ...
    ... lots of code ...
    i = another value;
    ... use i ...
the optimizer may not be smart enough to split this into two distinct variables, unless it does the SSA optimization. Hence, you'll lose the optimization where in [... lots of code ...] i will not be occupying a register.

But just for code comprehension, it is better to use different variables for disjoint uses. A related point is to "shrink wrap" a variable into the smallest scope you can. The less you have to look over the rest of the function for uses, the better.

And lastly,

    int x = value;
    if (condition) x = another;
is just better written as:

    const int x = condition ? value : another;
It reads better, and it enables x to be const, which is always better.


> Optimizers are pretty good at storing multiple variables in the same stack slot when their usages (i.e. "live ranges") are disjoint.

Exactly. Also the true lifetime of the variable might be way longer than what the programmer thinks due to compiler reordering the code to help CPU with dependency chain latency. (I've also seen plenty of cases where CPU out-of-order engine apparently completely fails, but (Intel) compiler saves the day.)

> int x = value;

> if (condition) x = another;

> is just better written as:

> const int x = condition ? value : another;

> It reads better, and it enables x to be const, which is always better.

While const sure is safer, the generated code should be same in both cases.

In this case I agree with you. But not if the ternary operator has any more complexity, because it quickly becomes hard to read. In my experience complicated ternary operators are rather bug prone, especially with large teams.

That said, I guess you agree with me your benchmark being "reads better". :-)


Are there production compilers who don't do SSA nowadays?


Go apparently didn't do SSA until 1.7. Then again it's not exactly an optimising compiler.

It's also somewhat common for functional language implementations to use CPS rather than SSA e.g. ghc does CPS conversion rather than SSA, and apparently didn't even used to do that: https://stackoverflow.com/a/8031177/8182118



It actually is not. The compiler has no problems turning your imperative code into SSA on its own, and PHI functions are no problem for optimizers.

I guess it's just for readability and easier reasoning about the code.


Your claim is that not having to do something is not easier than doing it? Ok.


The point is that there's absolutely no difference for a compiler that uses SSA form. So it's not like it has to do something extra.


Any MFA code is trivially converted to SSA and that's pretty much the first thing your compiler will do.

So doing SSA by hand makes no real difference to the compiler unless your compiler is so trivial it doesn't start by converting its input to SSA.


You're not the OP of the comment, who is a compiler writer (C, C++, D). I hope he'll weigh in with his rationale.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: