* module/language/cps/slot-allocation.scm ($allocation): Refactor
internal format of allocations. Instead of an allocation being a hash
table of small $allocation objects, it is an $allocation object that
contains packed vectors.
(find-first-trailing-zero): Rework to not need a maximum.
(lookup-maybe-slot): New interface.
(lookup-slot): Raise an error if a var has no slot.
(lookup-call-allocation): New helper.
(lookup-constant-value, lookup-maybe-constant-value):
(lookup-call-proc-slot, lookup-parallel-moves): Adapt to $allocation
change
(allocate-slots): Rewrite so that instead of being recursive, it
traverses the blocks in CFA order. Also, procedure call frames are
now allocated with respect to the live set after using arguments (and
killing any dead-after-use vars); this should make call frames more
compact but it does necessitate a parallel move solution. Therefore
parallel moves are recorded for all calls, for arguments; also if the
continuation is a $ktrunc, the continuation gets parallel moves for
the results.
This rewrite is in preparation to allocating call args directly in the
appropriate slots, where possible.
* module/language/cps/compile-rtl.scm (compile-fun): Adapt to slot
allocation changes, using lookup-maybe-slot where appropriate,
performing parallel moves when calling functions, and expecting return
moves to be associated with $ktrunc continuations.
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump.
* libguile/objcodes.c (process_dynamic_segment): Expect the minor
version to be present and, while we are still banging on the VM,
exactly equal to SCM_OBJCODE_MINOR_VERSION.
* libguile/vm-engine.c: Renumber ops. Remove the general make-vector.
Rename constant-FOO to FOO/immediate. Remove struct-ref and
struct-set!, replace with struct-ref/immediate and
struct-set!/immediate.
* module/Makefile.am:
* module/language/cps/specialize-primcalls.scm: New pass, inlines FOO to
FOO/immediate -- e.g. vector-ref to vector-ref/immediate.
* module/language/cps/arities.scm: Remove struct-set! case, now that
there is no struct-set! opcode.
* module/language/cps/compile-rtl.scm (compile-fun): Remove dispatch to
constant-FOO versus FOO here -- that decision is made by
specialize-primcalls.
(optimize): Add specialize-primcalls pass.
* module/language/cps/dfg.scm (constant-needs-allocation?): Adapt to
name changes.
* module/language/tree-il/primitives.scm (*interesting-primitive-names*):
(*primitive-constructors*): Add allocate-struct.
* module/system/vm/assembler.scm (*bytecode-major-version*):
(*bytecode-minor-version*, link-dynamic-section): Write minor version
into resulting image.
* module/language/cps.scm ($continue, $cont): Put source information on
the $continue, not on the $cont. Otherwise it is difficult for CPS
conversion to preserve source information.
($fun): Add a src member to $fun. Otherwise we might miss the source
info for the start of the function.
* .dir-locals.el:
* module/language/cps/arities.scm:
* module/language/cps/closure-conversion.scm:
* module/language/cps/compile-rtl.scm:
* module/language/cps/constructors.scm:
* module/language/cps/contification.scm:
* module/language/cps/dfg.scm:
* module/language/cps/elide-values.scm:
* module/language/cps/reify-primitives.scm:
* module/language/cps/slot-allocation.scm:
* module/language/cps/verify.scm:
* module/language/tree-il/compile-cps.scm: Update the whole CPS world
for this change.
* module/language/cps/compile-rtl.scm (compile-fun): Rewrite to visit
conts in reverse-post-order, which is a topological sort on the basic
blocks.
* module/language/cps/slot-allocation.scm (allocate-slots): Expect a DFG
as an argument.
* libguile/vm-engine.c (define!): Rename from define.
* module/language/cps/arities.scm (fix-clause-arities): If a prim
aliases an RTL instruction with a different name and we reify a
primcall, reify the instruction name.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Update
emit-define! for new name.
* module/language/cps/primitives.scm (*rtl-instruction-aliases*): Add
bytevector native accessors.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add emitters
for bytevector ops. Add br-if-bytevector emitter.
* module/language/cps/primitives.scm (*branching-primcall-arities*):
Mark bytevector? as a branching primitive.
* module/system/vm/assembler.scm (br-if-bytevector): New instruction
* module/system/vm/disassembler.scm (code-annotation): Add support for
bytevector?.
* module/language/cps.scm ($prompt): Add a "pop" field, indicating the
continuation at which this prompt is popped. The body of the prompt
is dominated by the prompt, and post-dominated by the pop. Adapt all
builders and users.
* module/language/cps/closure-conversion.scm:
* module/language/cps/compile-rtl.scm:
* module/language/cps/slot-allocation.scm:
* module/language/cps/verify.scm:
* module/language/tree-il/compile-cps.scm: Adapt.
* module/language/cps/dfg.scm (visit-fun): Add an arc from the pop to
the handler, to keep handler variables alive through the prompt body.
* libguile/Makefile.am:
* libguile/vm-builtins.h: New header, declaring stubs needed by the
compiler like values, apply, and abort-to-prompt.
* libguile/vm.c: Adapt the apply and values stubs to conform to a
standard interface. Add an abort-to-prompt stub. Add call/cc and
call-with-values stubs.
(scm_vm_builtin_ref): New helper, for the builtin-ref opcode.
(scm_vm_builtin_name_to_index)
(scm_vm_builtin_index_to_name): New helpers, for the compiler and
disassembler, respectively.
(scm_init_vm_builtins, scm_bootstrap_vm): Allow the compiler helpers
to be loaded later into a module.
* module/language/rtl.scm: Export builtin-index->name and
builtin-name->index.
* libguile/vm-engine.c (RETURN_VALUE_LIST): Update to use new names of
"apply" and "values".
(tail-call/shuffle): New opcode.
(abort): Update to be a tail VM op, and reorder and renumber other
ops.
(builtin-ref): New opcode.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_call_with_current_continuation):
Move this to vm.[ch], implemented as a builtin.
* module/language/tree-il/compile-cps.scm (convert): Convert to
'abort-to-prompt calls, possibly with 'apply, effectively undoing the
tree-il transformation.
* module/language/cps/reify-primitives.scm (builtin-ref): New helper.
(reify-primitives): Convert builtin primitives to builtin-ref.
* module/language/cps/dfg.scm (constant-needs-allocation?):
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add support
for compiling builtin-ref.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for builtin-ref.
* module/Makefile.am:
* module/language/cps/elide-values.scm (elide-values): New pass.
* module/language/cps/compile-rtl.scm (optimize): Call the new pass.
* libguile/vm-engine.c (rtl_vm_engine): Add make-vector and
constant-make-vector instructions and renumber.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Emit
constant-make-vector and make-vector as appropriate.
* module/language/cps/dfg.scm (constant-needs-allocation?): In some
cases, make-vector doesn't need to allocate its index.
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*, *primitive-constructors*): Add
make-vector.
* libguile/vm-engine.c (rtl_vm_engine): Add constant-vector-set!
instruction and renumber.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Emit
constant-vector-ref and constant-vector-set! as appropriate.
* module/language/cps/dfg.scm (constant-needs-allocation?): In some
cases, vector-ref and vector-set! don't need to allocate their index.
* libguile/vm-engine (box-ref, box-set!): Instead of aborting if a box
isn't a var, call out to vm_error_not_a_variable. This makes these
instructions equivalent to variable-ref/variable-set!.
(vector-set!): Rename from vector-set.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Add
variable-set! case, and adapt vector-set!.
* module/language/cps/primitives.scm (*rtl-instruction-aliases*): Add
variable-ref / variable-set! aliases to box-ref / box-set!.
* libguile/vm-engine.c (prompt): Adapt to explicitly set the saved SP so
we know how many incoming values the handler will receive, and to make
escape-only? a flag.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): $prompt
should only be found in a "seq" context, as it just pushes on a prompt
and doesn't bind any values. On the other hand it should emit
appropriate code for the handler to bind its values, so do that.
* module/language/cps/slot-allocation.scm ($cont-allocation): Add a note
that proc-slot is used by prompts as well.
(allocate-slots): Compute the allocation of a prompt handler's args.
* module/language/tree-il/compile-cps.scm (convert): Use "unwind"
instead of the nonexistent "pop-prompt".
* module/system/vm/disassembler.scm (code-annotation): Adapt to change
in prompt VM op.
* libguile/vm-engine.c (receive-values): Add an ALLOW-EXTRA? flag in
unused bits of the third word. Without it, receive-values will check
for the exact number of incoming values.
* libguile/vm.c (vm_error_wrong_number_of_values): New error case.
* module/language/cps/compile-rtl.scm (emit-rtl-sequence): Adapt to add
the ALLOW-EXTRA? flag.