summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2020-05-03 11:52:21 -0700
committerKaz Kylheku <kaz@kylheku.com>2020-05-03 11:52:21 -0700
commit799f765f3f1fe18901636c124f1ae62df46f93a8 (patch)
treebe67c4dec9db2ce6b1f987049dd049ff7037614b /share
parent898e55a66e8011140257057e4faa52f4cb74648b (diff)
downloadtxr-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.tl16
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)))