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". :-)
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
What benefit have you seen from doing this? Genuinely curious.