Next: compiler lifting examples, Previous: compiler lifting combinators, Up: compiler lifting [Index]
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: compiler lifting examples, Previous: compiler lifting combinators, Up: compiler lifting [Index]