Next: , Previous: , Up: compiler lifting   [Index]


17.20.6 Substitution optimisations

This compiler pass performs substitutions of binding references with the purpose of optimising their implementation. One of the possible results is to reduce the number of free variables non–combinator functions are closed upon; if all the free variables are removed: some non–combinator functions can be implemented as combinators.

Substituting references to combinators

This has already been discussed. Whenever a function is recognised to be a combinator: every reference to it is substituted with a form building and returning a new closure object; as example, the core language form:

(let ((f (lambda () '1)))
  (f))

is transformed into:

(codes
  ((lambda (label: asmlabel:f:clambda) () (constant 1)))
  (jmpcall asmlabel:f:clambda:case-0
           (closure-maker (code-loc asmlabel:f:clambda)
                          no-freevars)))

Synonym variables substitution

In the following core language expression:

(let ((a ((primitive read))))
  (let ((b a))
    b))

the binding b is a synonym for a, so it is transformed into:

(codes
  ()
  (bind ((a_0 (funcall (primref read))))
    a_0))

In the following recordised code:

(fix ((a_0 (lambda () ?body)))
  (bind ((b_0 a_0))
    (fix ((c_0 (lambda () (funcall b_0))))
      c_0)))

the returned value looks like a closure upon the binding b_0, but in truth it is known at compile–time that b_0 is an immutable binding referencing a clambda struct and also which clambda is referenced; so the function bound to c_0 is just a combinator; more: everywhere a reference to b_0 appears we can substitute it with a reference to a_0, and so we can transform the code to:

(fix ((a_0 (lambda () ?body)))
  (bind ((b_0 a_0))
    (fix ((c_0 (lambda () (funcall a_0))))
      c_0)))

NOTE While synonym binding elimination is performed by this compiler pass: it should have already been performed by the source optimiser.


Next: , Previous: , Up: compiler lifting   [Index]