summaryrefslogtreecommitdiffstats
path: root/vm.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-02-11 01:27:44 -0800
committerKaz Kylheku <kaz@kylheku.com>2021-02-11 01:27:44 -0800
commit512fa869e31d3fde5eb9422a5ed46e3fec58c94a (patch)
treec75c916943bd5a23ef22870144a41c2a3994a95b /vm.c
parent4e32c77f590b5191d488da142d3009522f0127ba (diff)
downloadtxr-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.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/vm.c b/vm.c
index f53962f3..8e7433f0 100644
--- a/vm.c
+++ b/vm.c
@@ -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); \