diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-03-29 07:03:52 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-03-29 07:03:52 -0700 |
commit | 5a332d3f4391edc17222c02975583c95cde4727e (patch) | |
tree | 9771cde0106c3a7d5c3209194ff51c4b8cddad13 | |
parent | fb2b2f38a417776cdf2c6623a63e268e9ce7fe3e (diff) | |
download | txr-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.tl | 17 |
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])))) |