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.