diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-02-11 01:27:44 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-02-11 01:27:44 -0800 |
commit | 512fa869e31d3fde5eb9422a5ed46e3fec58c94a (patch) | |
tree | c75c916943bd5a23ef22870144a41c2a3994a95b /vm.c | |
parent | 4e32c77f590b5191d488da142d3009522f0127ba (diff) | |
download | txr-512fa869e31d3fde5eb9422a5ed46e3fec58c94a.tar.gz txr-512fa869e31d3fde5eb9422a5ed46e3fec58c94a.tar.bz2 txr-512fa869e31d3fde5eb9422a5ed46e3fec58c94a.zip |
compiler: frame-eliminating optimization.
This optimization identifies let blocks whose variables are
not captured by closures. The variables are relocated to
registers and the frame M N ... end reg wrapping is removed.
* parser.c (read_file_common): Load version 6 files.
We remain backwards-compatible.
* share/txr/stdlib/compiler.tl (var-spy, capture-var-spy): New
structure types.
(struct compiler): New slot, var-spies.
(with-var-spy): New macro.
(compiler (alloc-new-treg, unalloc-reg-count, push-var-spy,
pop-var-spy)): New methods.
(compiler (comp-atom, compt-setq, comp-list-setq,
comp-lisp1-value)): Inform the spies in the spy notification
stack about assignments and accesses.
(compiler eliminate-frame): New method.
(compiler comp-let): Use spies to determine which variables
from this frame are captured, and if none are, then use
eliminate-frame to rename all the variables to t-registers and
drop the frame setup/teardown.
(compiler comp-lambda): Set up a capture-var-spy which
intercepts accesses and assignments within a lambda, and
informs other spies about the captures.
(%tlo-ver%): Bump compiled file version to to (6 0), because
of some behavioral changes necessary in the VM. We might
revert this if the issues are solved differently.
* vm.c (vm_getz): Do not null out T registers.
(vm_execute_toplevel, vm_execute_closure): Use zalloca to
allocate the register part of the frame, so T registers are
initialized to nil.
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 8 |
1 files changed, 4 insertions, 4 deletions
@@ -359,7 +359,7 @@ INLINE val vm_getz(struct vm_env *dspl, unsigned ref) { unsigned lev = vm_lev(ref); val *addr = &dspl[lev].mem[vm_idx(ref)]; - return (lev == 0) ? z(*addr) : *addr; + return *addr; } INLINE val vm_sm_get(struct vm_env *dspl, unsigned ref) @@ -1124,7 +1124,7 @@ val vm_execute_toplevel(val desc) val self = lit("vm-execute-toplevel"); struct vm_desc *vd = vm_desc_struct(self, desc); struct vm vm; - val *frame = coerce(val *, alloca(sizeof *frame * vd->frsz)); + val *frame = coerce(val *, zalloca(sizeof *frame * vd->frsz)); struct vm_env *dspl = coerce(struct vm_env *, frame + vd->nreg); vm_reset(&vm, vd, dspl, 1, 0); @@ -1152,7 +1152,7 @@ val vm_execute_closure(val fun, struct args *args) struct vm_desc *vd = vm_desc_struct(self, desc); struct vm_closure *vc = coerce(struct vm_closure *, closure->co.handle); struct vm vm; - val *frame = coerce(val *, alloca(sizeof *frame * vd->frsz)); + val *frame = coerce(val *, zalloca(sizeof *frame * vd->frsz)); struct vm_env *dspl = coerce(struct vm_env *, frame + vd->nreg); val vargs = if3(variadic, args_get_rest(args, fixparam), nil); cnum ix = 0; @@ -1214,7 +1214,7 @@ val vm_execute_closure(val fun, struct args *args) struct vm_desc *vd = vm_desc_struct(self, desc); \ struct vm_closure *vc = coerce(struct vm_closure *, closure->co.handle); \ struct vm vm; \ - val *frame = coerce(val *, alloca(sizeof *frame * vd->frsz)); \ + val *frame = coerce(val *, zalloca(sizeof *frame * vd->frsz)); \ struct vm_env *dspl = coerce(struct vm_env *, frame + vd->nreg); \ vm_reset(&vm, vd, dspl, vc->nlvl - 1, vc->ip); \ vm.dspl = coerce(struct vm_env *, frame + vd->nreg); \ |