summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-03-29 07:03:52 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-03-29 07:03:52 -0700
commit5a332d3f4391edc17222c02975583c95cde4727e (patch)
tree9771cde0106c3a7d5c3209194ff51c4b8cddad13
parentfb2b2f38a417776cdf2c6623a63e268e9ce7fe3e (diff)
downloadtxr-5a332d3f4391edc17222c02975583c95cde4727e.tar.gz
txr-5a332d3f4391edc17222c02975583c95cde4727e.tar.bz2
txr-5a332d3f4391edc17222c02975583c95cde4727e.zip
compiler: improve register use when compiling calls.
* share/txr/stdlib/compiler.tl (compiler comp-call-impl): Instead of allocating N temporary registers for N arguments, some (or even none) of which may actually be used, we do this one argument at a time: allocate just one register, compile the argument expression, and then free the register immediately if that fragment specifies its own output location instead of the register. Otherwise keep the register and push it on a stack. This strategy lowers maximum register use. Also, since we are pushing the used registers on a stack, when we call free-tregs, they get liberated in reverse order of allocation, which keeps things tidy.
-rw-r--r--share/txr/stdlib/compiler.tl17
1 files changed, 11 insertions, 6 deletions
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index a1bae8cc..b6e9e786 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -836,13 +836,18 @@
(uni ffrag.ffuns cfrag.ffuns))))))
(defmeth compiler comp-call-impl (me oreg env opcode freg args)
- (let* ((sugg-oregs (mapcar (ret me.(alloc-treg)) args))
- (afrags (mapcar (ret me.(compile @1 env @2))
- sugg-oregs args))
- (real-oregs (mapcar .oreg afrags)))
- me.(free-tregs sugg-oregs)
+ (let* ((aoregs nil)
+ (afrags (collect-each ((arg args))
+ (let* ((aoreg me.(alloc-treg))
+ (afrag me.(compile aoreg env arg)))
+ (if (nequal afrag.oreg aoreg)
+ me.(free-treg aoreg)
+ (push aoreg aoregs))
+ afrag))))
+ me.(free-tregs aoregs)
(new (frag oreg
- ^(,*(mappend .code afrags) (,opcode ,oreg ,freg ,*real-oregs))
+ ^(,*(mappend .code afrags)
+ (,opcode ,oreg ,freg ,*(mapcar .oreg afrags)))
[reduce-left uni afrags nil .fvars]
[reduce-left uni afrags nil .ffuns]))))