I got the following email from a friend today:
I was noodling some source code transforms the other day, and I remembered about flowlang. As I was reviewing it, I wondered: what's the difference between flowlang and Static Single Assignment form for general languages? http://en.wikipedia.org/wiki/Static_single_assignment_form They seem identical, but I'm probably missing something...
Here's my response:
Good question. SSA form is similar, but it makes only a weak assumption about disambiguation of variables and values, whereas Flow makes a strong (even guarantee-able) assumption about the same.
Basically, in a multithreaded environment, SSA form makes no guarantees that the rug won't be pulled out from under you, i.e. that you know at compiletime what specific value any given variable in the SSA expression refers to. In my opinion, this almost completely demolishes the usefulness of SSA form, because you are reasoning about assumed data dependencies that may, at runtime, turn out to be completely wrong.
SSA is the right way to think, and the nice thing is that all algorithms that have been developed for optimization of code in SSA form can be directly applied to Flow -- the difference is that Flow will always do the right thing at runtime.
It is impossible in the general case to generate SSA form that reflects the runtime data dependencies (rather than the static best-guess approximation of runtime data dependencies) for any general-purpose imperative programming language.
I was noodling some source code transforms the other day, and I remembered about flowlang. As I was reviewing it, I wondered: what's the difference between flowlang and Static Single Assignment form for general languages? http://en.wikipedia.org/wiki/Static_single_assignment_form They seem identical, but I'm probably missing something...
Here's my response:
Good question. SSA form is similar, but it makes only a weak assumption about disambiguation of variables and values, whereas Flow makes a strong (even guarantee-able) assumption about the same.
Basically, in a multithreaded environment, SSA form makes no guarantees that the rug won't be pulled out from under you, i.e. that you know at compiletime what specific value any given variable in the SSA expression refers to. In my opinion, this almost completely demolishes the usefulness of SSA form, because you are reasoning about assumed data dependencies that may, at runtime, turn out to be completely wrong.
SSA is the right way to think, and the nice thing is that all algorithms that have been developed for optimization of code in SSA form can be directly applied to Flow -- the difference is that Flow will always do the right thing at runtime.
It is impossible in the general case to generate SSA form that reflects the runtime data dependencies (rather than the static best-guess approximation of runtime data dependencies) for any general-purpose imperative programming language.
Perfectly determining runtime data dependencies without actually running the program is uncomputable for imperative languages, and even if you run the program, you only get one of a possibly large or infinite number of data dependency graphs, depending on how many race conditions might be present in your code.