* module/system/vm/assembler.scm (check-urange, check-srange): New
helpers.
(pack-u8-u24, pack-u8-s24, pack-u1-u7-u24, pack-u8-u12-u12):
(pack-u8-u8-u16, pack-u8-u8-u8-u8): Use the new helpers. Not only
makes the code nicer but also reduces register pressure.
* module/system/vm/assembler.scm (<asm>): Instead of writing words into
a list of fixed-size buffers, use a growable vector.
(expand, emit): Instead of assuming that there is enough space for
only one word, check that there is space for the entire instruction at
the beginning.
* libguile/vm-engine.c (logsub): New op.
* module/language/cps/effects-analysis.scm (logsub):
* module/language/cps/types.scm (logsub):
* module/system/vm/assembler.scm (system): Add support for the new op.
* module/language/tree-il/compile-cps.scm (canonicalize):
Rewrite (logand x (lognot y)) to (logsub x y).
* libguile/vm-engine.c (bv-s8-ref, bv-s16-ref, bv-s32-ref, bv-s64-ref):
Unbox index and return unboxed S32 value.
(bv-s8-set!, bv-s16-set!, bv-s32-set!, bv-s64-set!): Unbox index and
take unboxed S32 value.
(bv-u8-ref, bv-u16-ref, bv-u32-ref, bv-u64-ref)
(bv-s8-set!, bv-s16-set!, bv-s32-set!, bv-s64-set!): Likewise, but
with unsigned values.
(bv-f32-ref, bv-f32-set!, bv-f64-ref, bv-f64-set!): Use memcpy to
access the value so we don't have to think about alignment. GCC will
inline this to a single instruction on architectures that support
unaligned access.
* libguile/vm.c (vm_error_out_of_range_uint64)
(vm_error_out_of_range_int64): New helpers.
* module/language/cps/slot-allocation.scm (compute-var-representations):
All bytevector ref operations produce untagged values.
* module/language/cps/types.scm (define-bytevector-accessors): Update
for bytevector untagged indices and values.
* module/language/cps/utils.scm (compute-constant-values): Fix s64
case.
* module/language/tree-il/compile-cps.scm (convert): Box results of all
bytevector accesses, and unbox incoming indices and values.
* libguile/instructions.c (FOR_EACH_INSTRUCTION_WORD_TYPE): Add word
types for immediate f64 and u64 values.
(TYPE_WIDTH): Bump up by a bit, now that we have 32 word types.
(NOP, parse_instruction): Use 64-bit meta type.
* libguile/vm-engine.c (load-f64, load-u64): New instructions.
* module/language/bytecode.scm (compute-instruction-arity): Add parser
for new instruction word types.
* module/language/cps/compile-bytecode.scm (compile-function): Add
special-cased assemblers for new instructions, and also for scm->u64
and u64->scm which I missed before.
* module/language/cps/effects-analysis.scm (load-f64, load-u64): New
instructions.
* module/language/cps/slot-allocation.scm (compute-needs-slot): load-f64
and load-u64 don't need slots.
(compute-var-representations): Update for new instructions.
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
Specialize scm->f64 and scm->u64 to make-f64 and make-u64.
* module/language/cps/types.scm (load-f64, load-u64): Wire up to type
inference, though currently type inference only runs before
specialization.
* module/language/cps/utils.scm (compute-defining-expressions): For some
reason I don't understand, it's possible to see two definitions that
are equal but not equal? here. Allow for now.
(compute-constant-values): Punch through type conversions to get
constant u64/f64 values.
* module/system/vm/assembler.scm (assembler): Support for new word
types. Export the new assemblers.
* libguile/vm-engine.c (add/immediate, sub/immediate)
(uadd/immediate, usub/immediate, umul/immediate): New instructions.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/language/cps/slot-allocation.scm (compute-needs-slot):
* module/language/cps/types.scm:
* module/system/vm/assembler.scm (system):
* module/language/cps/effects-analysis.scm: Support
for new instructions.
* module/language/cps/optimize.scm (optimize-first-order-cps): Move
primcall specialization to the last step -- the only benefit of doing
it earlier was easier reasoning about side effects, and we're already
doing that in a more general way with (language cps types).
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
Specialize add and sub to add/immediate and sub/immediate, and
specialize u64 addition as well. U64 specialization doesn't work now
though because computing constant values doesn't work for U64s; oh
well.
* libguile/vm-engine.c: Remove add1 and sub1 instructions. Will replace
with add/immediate and sub/immediate.
* module/language/tree-il/peval.scm (peval): If we reify a new
<primcall>, expand it. Removes 1- and similar primcalls.
* module/language/tree-il/primitives.scm: Don't specialize (+ x 1) to 1+.
(expand-primcall): New export, does a single primcall expansion.
(expand-primitives): Use the new helper.
* module/language/cps/effects-analysis.scm:
* module/language/cps/primitives.scm:
* module/language/cps/types.scm:
* module/system/vm/assembler.scm: Remove support for add1 and sub1 CPS
primitives.
* test-suite/tests/peval.test ("partial evaluation"): Adapt tests that
expect 1+/1- to expect +/-.
* module/system/repl/debug.scm (frame->module): Remove. Has been broken
for a while, had no callers, and was calling frame-procedure. We can
revive again in a better way, like ice-9 local-eval.
* module/system/vm/traps.scm (frame-matcher): Always match on a
procedure's code, instead of the value in slot 0. Prevents confusion
with closure-optimized procedures, re-use of slot 0, and untagged
values in slot 0.
(trap-at-procedure-call, trap-in-procedure)
(trap-instructions-in-procedure, trap-at-procedure-ip-in-range)
(trap-at-source-location, trap-in-dynamic-extent)
(trap-calls-in-dynamic-extent, trap-instructions-in-dynamic-extent):
Update to adapt to frame-matcher change and remove #:closure?
argument, effectively changing the default behavior to #:closure? #t.
* doc/ref/api-debug.texi (Low-Level Traps): Update documentation.
* doc/ref/scheme-using.texi (Debug Commands):
* module/system/repl/command.scm (procedure): Remove REPL command.
Since there is a closure binding and we have improved the ,registers
output, this is no longer necessary and by removing it we remove
another bogus use of frame-procedure.
* module/system/vm/frame.scm (frame-call-representation): Never use
frame-procedure, as we don't know that slot 0 is a SCM value and even
if it were, we don't know that it corresponds to the procedure being
applied, except in the case of primcalls. Print _ as the procedure
name if we don't know it, instead of #f.
* libguile/frames.c (frame_procedure_name_var): New static definition.
(init_frame_procedure_name_var): New helper.
(scm_frame_procedure_name): New function that returns the name of the
frame's procedure, as frame-procedure is to be deprecated.
* libguile/frames.h (scm_frame_procedure_name): Export.
* module/ice-9/boot-9.scm (exception-printers): Use frame-procedure-name
instead of procedure-name on frame-procedure.
* module/system/vm/frame.scm (frame-procedure-name): New private
function, implementing scm_frame_procedure_name.
(frame-call-representation): Use frame-procedure-name to get the
procedure name to print.
We need to be able to identify frames that are primitive applications
without assuming that slot 0 in a frame is an SCM value and without
assuming that value is the procedure being applied.
* libguile/gsubr.c (scm_i_primitive_code_p): New helper.
(scm_i_primitive_arity): Use the new helper.
* libguile/gsubr.h: Declare the new helper.
* libguile/programs.h:
* libguile/programs.c (scm_program_code_p): New function, replacing
scm_primitive_p.
(scm_primitive_call_ip): Fix FUNC_NAME definition.
* module/statprof.scm (sample-stack-procs, count-call): Identify
primitive frames from the IP, not the frame-procedure. Avoids the
assumption that slot 0 in a frame is a SCM value.
(statprof-proc-call-data): Adapt to primitive-code? change.
* module/system/vm/frame.scm (frame-call-representation): Identify
primitive frames from the IP, not the closure. Still more work to do
here to avoid assuming slot 0 is a procedure.
* module/system/vm/program.scm: Export primitive-code? instead of
primitive?.
(program-arguments-alist, program-arguments-alists): Identify
primitives from the code instead of the flags on the program. Not
sure this is a great change, but it does avoid having to define a
primitive? predicate in Scheme.
* module/language/cps/compile-bytecode.scm (compile-function): Always
define a 'closure binding in slot 0.
* module/system/vm/frame.scm (available-bindings): No need to futz
around not having a closure binding.
* module/system/vm/debug.scm (arity-arguments-alist): Expect a closure
binding.
* test-suite/tests/rtl.test: Emit definitions for the closure.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/language/cps/primitives.scm (*branching-primcall-arities*):
* module/language/cps/type-fold.scm (equal?):
* module/language/cps/types.scm (equal?):
* module/language/tree-il/compile-cps.scm (convert): `equal?' is no
longer a branching primcall, because it isn't inline. The
implementation could lead to bad backtraces also, as it didn't save
the IP, and actually could lead to segfaults as it didn't reload the
SP after the return. There is an eqv? fast-path, though.
* module/system/vm/assembler.scm (br-if-equal): Remove interface.
* module/system/vm/disassembler.scm (code-annotation):
(compute-labels): No need to handle br-if-equal.
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION):
* module/system/vm/assembler.scm (*bytecode-minor-version*): Bump
bytecode version to prevent 2.1.1 users from thinking that they don't
need to make clean after pulling.
* libguile/vm-engine.c (fadd, fsub, fmul, fdiv): New instructions.
* module/language/cps/effects-analysis.scm:
* module/language/cps/types.scm: Wire up support for new instructions.
* module/system/vm/assembler.scm: Export emit-fadd and friends.
* module/language/tree-il/compile-cps.scm (convert): Box results of
bv-f32-ref and bv-f64-ref. Unbox the argument to bv-f32-set! and
bv-f64-set!.
* libguile/vm-engine.c (bv-f32-ref, bv-f64-ref): Results are raw.
(bv-f32-set!, bv-f64-set!): Take unboxed arguments.
* module/system/vm/assembler.scm (emit-scm->f64, emit-f64->scm):
Export.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/language/cps/effects-analysis.scm: Add support for scm->f64 and
f64->scm.
* module/language/cps/slot-allocation.scm (compute-var-representations):
Add cases for primops returning raw values.
* module/language/cps/types.scm (bv-f32-ref, bv-f32-set!)
(bv-f64-ref, bv-f64-set!): Deal in &f64 values instead of reals.
* libguile/loader.c (scm_find_slot_map_unlocked): Rename from
scm_find_dead_slot_map_unlocked.
* libguile/vm.c (struct slot_map_cache_entry, struct slot_map_cache)
(find_slot_map): Rename, changing "dead_slot" to "slot".
(enum slot_desc): New type.
(scm_i_vm_mark_stack): Interpret slot maps as having two bits per
slot, allowing us to indicate that a slot is live but not a pointer.
* module/language/cps/compile-bytecode.scm (compile-function): Adapt to
emit-slot-map name change.
* module/system/vm/assembler.scm (<asm>): Rename dead-slot-maps field to
slot-maps.
(emit-slot-map): Rename from emit-dead-slot-map.
(link-frame-maps): 2 bits per slot.
* module/language/cps/slot-allocation.scm (lookup-slot-map): Rename from
lookup-dead-slot-map.
(compute-var-representations): New function.
(allocate-slots): Adapt to encode two-bit slot representations.
* module/language/cps/compile-bytecode.scm (compile-function): Remove
special cases for nullary and unary returns; instead always use
return-values and rely on hinting to try to place values in the right
slot already.
* module/system/vm/assembler.scm (emit-init-constants): Use
return-values.
* module/system/vm/disassembler.scm (code-annotation): Add annotation
for return-values.
* doc/ref/vm.texi: Update for new stack layout.
* module/system/vm/disassembler.scm (code-annotation): Print the frame
sizes after alloc-frame, reset-frame, etc to make reading the
disassembly easier.
* module/system/vm/disassembler.scm (define-stack-effect-parser)
(stack-effect-parsers, instruction-stack-size-after): New stack size
facility.
(define-clobber-parser, clobber-parsers, instruction-slot-clobbers):
Take incoming and outgoing stack sizes as arguments to interpret
SP-relative clobbers.
* module/system/vm/frame.scm (compute-frame-sizes): New helper that
computes frame sizes for each position in a function.
(compute-killv): Adapt to compute the clobbered set given the computed
frame sizes.
* libguile/vm-engine.c: S24/S12/S8 operands addressed relative to the
SP, not the FP. Cache the SP instead of a FP-relative locals
pointer. Further cleanups to follow.
* libguile/vm.c (vm_builtin_call_with_values_code): Adapt to mov operand
addresing change.
* module/language/cps/compile-bytecode.scm (compile-function): Reify
SP-relative local indexes where appropriate.
* module/system/vm/assembler.scm (emit-fmov*): New helper, exported as
emit-fmov.
(shuffling-assembler, define-shuffling-assembler): Rewrite to shuffle
via push/pop/drop.
(standard-prelude, opt-prelude, kw-prelude): No need to provide for
shuffling args.
* test-suite/tests/rtl.test: Update.
* module/language/cps/slot-allocation.scm: Don't reserve slots 253-255.
* libguile/vm-engine.c: Renumber opcodes, and take the opportunity to
fold recent additions into more logical places. Be more precise when
describing the encoding of operands, to shuffle local references only
and not constants, immediates, or other such values.
(SP_REF, SP_SET): New helpers.
(BR_BINARY, BR_ARITHMETIC): Take full 24-bit operands. Our shuffle
strategy is to emit push when needed to bring far locals near, then
pop afterwards, shuffling away far destination values as needed; but
that doesn't work for conditionals, unless we introduce a trampoline.
Let's just do the simple thing for now. Native compilation will use
condition codes.
(push, pop, drop): Back from the dead! We'll only use these for
temporary shuffling though, when an opcode can't address the full
24-bit range.
(long-fmov): New instruction, like long-mov but relative to the frame
pointer.
(load-typed-array, make-array): Don't use a compressed encoding so
that we can avoid the shuffling case. It would be a pain, given that
they have so many operands already.
* module/language/bytecode.scm (compute-instruction-arity): Update for
new instrution word encodings.
* module/system/vm/assembler.scm: Update to expose some opcodes
directly, without the need for shuffling wrappers. Adapt to
instruction word encodings change.
* module/system/vm/disassembler.scm (disassembler): Adapt to instruction
coding change.
* module/system/repl/debug.scm (print-frame): Pass #:top-frame? #t for
the top frame.
* module/system/vm/frame.scm (available-bindings): Be permissive and
allow #:top-frame? #f even when the IP is at the start of the
function.
* libguile/goops.h (SCM_VTABLE_FLAG_GOOPS_STATIC): Reserve the fourth
GOOPS flag to indicate that a class has static slot allocation.
* libguile/goops.c (scm_init_goops_builtins): Define
vtable-flag-goops-static for goops.scm.
* module/oop/goops.scm (class-has-statically-allocated-slots?): New
helper.
(build-slots-list): Instead of the ad-hoc checks for <class> or
<slot>, use the new helper.
(initialize): Accept #:static-slot-allocation? keyword.
* module/system/foreign-object.scm (make-foreign-object-type): Declare
foreign object classes as having static slot allocation.
* test-suite/tests/goops.test ("static slot allocation"): Add tests.
* module/system/vm/assembler.scm (link-debug): Fix for source properties
that don't have line and column, as are currently being produced by
the new lalr.
* libguile/vm-engine.c (allocate-struct, struct-ref, struct-set!): New
instructions, to complement their "immediate" variants.
* module/language/cps/compile-bytecode.scm (compile-fun):
* module/system/vm/assembler.scm (system): Wire up the new instructions.
Fixes <http://bugs.gnu.org/19354>.
Reported by Linas Vepstas <linasvepstas@gmail.com>.
* module/system/vm/assembler.scm (write-sources): Intern the filename
only if it's a string. (For sockets, the filename is a symbol).