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


17.20.4 Optimisation of combinator calls

If a Scheme function is a combinator it does not need to capture the current value of any binding; this means we can adopt two opposite strategies of implementation:

this compiler pass, as implemented by Vicare, assumes that delaying the creation of combinator closure objects is advantageous. As example, the core language expression:

(let ((f (lambda () '1)))
   ((primitive list) (f) (f)))

is transformed into:

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

where multiple closure-maker structs are introduced for the same function.

The fact that we introduce multiple closure-maker structs to create closure objects with the same clambda implementation, takes advantage of the R6RS statement that we cannot assume Scheme functions are eq? to themselves:

(define (func) ?body)
(eq? func func) ⇒ unspecified

for example, the following core language form:

(let ((a (lambda () '1)))
  ((primitive eq?) a a))

is transformed into:

(codes
  ((lambda (label: asmlabel:a:clambda) () (constant 1)))
  (funcall (primref eq?)
    (closure-maker (code-loc asmlabel:a:clambda) no-freevars)
    (closure-maker (code-loc asmlabel:a:clambda) no-freevars)))

further transformations of the code might recognise the operands of eq? as being references to the same function, but in more complex cases this may not happen.


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