summaryrefslogtreecommitdiffstats
path: root/share
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-20 20:35:40 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-20 20:35:40 -0700
commit5782eb24f96d01fba6d2a98a6b6e9dff04042bd7 (patch)
tree763a769b3330399b36dffd92efd3b9423ace71d5 /share
parent996b7651b3a05ab9ae329467d7d9afdd696aa578 (diff)
downloadtxr-5782eb24f96d01fba6d2a98a6b6e9dff04042bd7.tar.gz
txr-5782eb24f96d01fba6d2a98a6b6e9dff04042bd7.tar.bz2
txr-5782eb24f96d01fba6d2a98a6b6e9dff04042bd7.zip
compiler: improve progn.
* share/txr/stdlib/compiler.tl (compiler comp-progn): If the suggested output register is a variable, progn should not use it for the discarded values of the leading forms, only for the last form. Writes to the variable space of the display are costly because in closures, the underlying vector of a given level has to be passed to gc_mutated. We use a new temp register for the discarded forms.
Diffstat (limited to 'share')
-rw-r--r--share/txr/stdlib/compiler.tl21
1 files changed, 15 insertions, 6 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index c63e1300..c65acb56 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -442,14 +442,23 @@
(defmeth compiler comp-progn (me oreg env args)
(let* (ffuns fvars
+ (nargs (len args))
lastfrag
+ (oreg-discard (if (eq (car oreg) t)
+ oreg
+ me.(alloc-treg)))
(code (build
- (each ((form args))
- (let ((frag me.(compile oreg env form)))
- (set lastfrag frag)
- (set fvars (uni fvars frag.fvars))
- (set ffuns (uni ffuns frag.ffuns))
- (pend frag.code))))))
+ (each ((form args)
+ (n (range 1)))
+ (let ((islast (eql n nargs)))
+ (let ((frag me.(compile (if islast oreg oreg-discard)
+ env form)))
+ (when islast
+ (set lastfrag frag))
+ (set fvars (uni fvars frag.fvars))
+ (set ffuns (uni ffuns frag.ffuns))
+ (pend frag.code)))))))
+ me.(free-treg oreg-discard)
(new (frag (if lastfrag lastfrag.oreg ^(t 0)) code fvars ffuns))))
(defmeth compiler comp-prog1 (me oreg env form)