diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2020-05-03 11:52:21 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2020-05-03 11:52:21 -0700 |
commit | 799f765f3f1fe18901636c124f1ae62df46f93a8 (patch) | |
tree | be67c4dec9db2ce6b1f987049dd049ff7037614b /share | |
parent | 898e55a66e8011140257057e4faa52f4cb74648b (diff) | |
download | txr-799f765f3f1fe18901636c124f1ae62df46f93a8.tar.gz txr-799f765f3f1fe18901636c124f1ae62df46f93a8.tar.bz2 txr-799f765f3f1fe18901636c124f1ae62df46f93a8.zip |
compiler: implement lambda lifting.
This is what the recent load-time changes were grooming the
compiler toward. When we compile a lambda, we can look at the
function and variable refernces it is making. If the lambda
makes no lexical function or variable references, we can lift
that lambda into load time, so that it's instantiated once and
then re-used out of a D register. Effectively, it becomes a
top-level function.
* share/txr/stdlib/compiler.tl (compiler comp-lambda-impl):
New method, formed by renaming comp-lambda.
(compiler comp-lambda): Turned not wrapper for comp-lambda
impl which compiles the lambda, and checks for the conditions
for hoisting it into load time, which is currently done by
generating the sys:load-time-lit form around it and re-compiling.
Diffstat (limited to 'share')
-rw-r--r-- | share/txr/stdlib/compiler.tl | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl index 8b8baa20..4d776296 100644 --- a/share/txr/stdlib/compiler.tl +++ b/share/txr/stdlib/compiler.tl @@ -815,7 +815,7 @@ (uni (diff bfrag.ffuns lexfuns) (if rec (diff ffuns lexfuns) ffuns)))))))) -(defmeth compiler comp-lambda (me oreg env form) +(defmeth compiler comp-lambda-impl (me oreg env form) (mac-param-bind form (op par-syntax . body) form (let* ((*load-time* nil) (pars (new (fun-param-parser par-syntax form))) @@ -913,6 +913,20 @@ (uni [reduce-left uni ifrags nil .ffuns] bfrag.ffuns))))))))) +(defmeth compiler comp-lambda (me oreg env form) + (if *load-time* + me.(comp-lambda-impl oreg env form) + (let* ((lambda-frag me.(comp-lambda-impl oreg env form)) + (ok-lift-var-pov (all lambda-frag.fvars + (lambda (sym) + (not env.(lookup-var sym))))) + (ok-lift-fun-pov (all lambda-frag.ffuns + (lambda (sym) + (not env.(lookup-fun sym)))))) + (if (and ok-lift-var-pov ok-lift-fun-pov) + me.(compile oreg env ^(sys:load-time-lit nil ,form)) + lambda-frag)))) + (defmeth compiler comp-fun (me oreg env form) (mac-param-bind form (op arg) form (let ((fbin env.(lookup-fun arg t))) |