cmp: fix inlining of local closures (2nd try)

We need to compile the function body in the same environment in which
the function was defined. However the function arguments need to be
compiled in the current argument.

Fixes #577.
This commit is contained in:
Marius Gerbershagen 2020-05-24 20:35:31 +02:00
parent a9a63b1d50
commit c7d6ddbf38

View file

@ -97,15 +97,31 @@
`(funcall ,can-inline ,@args)))
(t (c1call-global fname args))))
(defun inline-local (lambda fun args)
(declare (si::c-local))
(let ((*inline-max-depth* (1- *inline-max-depth*))
(setjmps *setjmps*)
(*cmp-env* (cmp-env-copy)))
;; To inline the function, we transform it into a let* statement.
(multiple-value-bind (bindings body)
(transform-funcall/apply-into-let* (macroexpand-lambda-block lambda)
args nil)
(multiple-value-bind (let-vars let-inits specials other-decls body)
(process-let-bindings 'LET* bindings body)
;; We have to compile the function body in the same
;; environment in which the function was defined to get
;; inlining of closures right.
(let ((*cmp-env* (cmp-env-copy (fun-cmp-env fun))))
(mapc #'push-vars let-vars)
(process-let-body 'LET* let-vars let-inits specials other-decls body setjmps))))))
(defun c1call-local (fname fun args)
(declare (si::c-local))
(let ((lambda (fun-lambda-expression fun)))
(when (and lambda
(declared-inline-p fname)
(plusp *inline-max-depth*))
(return-from c1call-local
(let ((*inline-max-depth* (1- *inline-max-depth*)))
`(funcall #',lambda ,@args)))))
(return-from c1call-local (inline-local lambda fun args))))
(let* ((forms (c1args* args))
(return-type (or (get-local-return-type fun) 'T))
(arg-types (get-local-arg-types fun)))