typelead/eta

Purity to mutability rewriting

rahulmutt opened this issue · 0 comments

For low-latency applications, you cannot afford to lose time/work to the GC and destructive (mutable) updates are a must. Using basic liveness analysis (which is already done to a great extent by the occurrence analyzer), we should be able to figure out if a reference to an Eta value is not shared/saved in a thunk and in such case do the mutable update. Strictness analysis typically takes care of this, but can be limited at times.

A simple example:

data Record = Record { int :: Int }

inc :: Record -> Record
inc Record { int } = Record { int = int + 1 }

You cannot make this a mutable update in general, but suppose it's used in such a way that the input record is never used again.

let x = inc (inc (inc r)

It should compile down to a series of mutations rather than 3 allocations. This can be done provided that r is not used by any other expression. The current optimizer can eliminate the allocations as well, but only if r can be inlined to expose a Record constructor, which the "case of known constructor" optimization will eliminate it. The proposed optimization will work regardless of the structure of r, just depends on its usage.

Implementation plan:
After the simplifier does its work and before STG, we specialize a particular function into a mutable variant and replace calls to the immutable variant to the mutable variant if we determine that the inputs aren't re-used. Doing something like this will probably require modifying Core to directly support mutation.

See discussion here.