* module/language/cps/cse.scm (compute-equivalent-subexpressions): When
CSE sees a definition like `(cons a b)', it will also record an
"auxiliary definition" for `(car x)', where x is the variable defined
by the cons, whereby calling `(car x)' can reduce to `a' if there is
no intervening effect that clobbers the definitions. However, when
the successor of the cons is a control-flow join, then any variables
defined there have multiple definitions. It's incorrect to add the
aux definition in that case.
* test-suite/tests/compiler.test ("cse auxiliary definitions"): New
test.
This fixes a bug whereby the compiler would sometimes allocate floats in
marked space.
* libguile/gc-inline.h (scm_inline_gc_malloc_pointerless_words): New
internal helper.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (allocate_pointerless_words):
(allocate_pointerless_words_with_freelist): New intrinsics.
* libguile/jit.c (compile_allocate_pointerless_words):
(compile_allocate_pointerless_words_immediate): New compilers.
* libguile/vm-engine.c (allocate_pointerless_words)
(allocate_pointerless_words_immediate): New opcodes.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/language/cps/effects-analysis.scm (param):
* module/language/cps/reify-primitives.scm (reify-primitives):
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
* module/language/cps/types.scm (allocate-words):
(allocate-words/immediate):
* module/system/vm/assembler.scm (system): Add support for the new
opcodes.
* libguile/intrinsics.c (scm_atan1): New intrinsic, wrapping scm_atan.
(scm_bootstrap_intrinsics): Add new intrinsics.
* libguile/intrinsics.h (scm_t_f64_from_f64_f64_intrinsic): New
intrinsic type.
(SCM_FOR_ALL_VM_INTRINSICS): Add intrinsics for floor, ceiling, sin,
cos, tan, asin, acos, atan, and their unboxed counterparts.
* libguile/jit.c (sp_f64_operand): New helper.
(compile_call_f64_from_f64, compile_call_f64_from_f64_f64): Call out
to intrinsics.
* libguile/vm-engine.c (call-f64<-f64-f64): New opcode.
* module/language/cps/effects-analysis.scm: Add new intrinsics.
* module/language/cps/reify-primitives.scm (compute-known-primitives):
Add new intrinsics.
* module/language/cps/slot-allocation.scm (compute-var-representations):
Add 'f64 slot types for the new unboxed intrinsics.
* module/language/cps/specialize-numbers.scm (specialize-operations):
Support unboxing the new intrinsics.
* module/language/cps/types.scm: Define type inferrers for the new
intrinsics.
* module/language/tree-il/cps-primitives.scm: Define CPS translations
for the new intrinsics.
* module/language/tree-il/primitives.scm (*interesting-primitive-names*):
(*effect-free-primitives*, atan): Define primitive resolvers.
* module/system/vm/assembler.scm: Export assemblers for the new
intrinsics.
(define-f64<-f64-f64-intrinsic): New helper.
* module/language/cps/compile-bytecode.scm (compile-function): When
shuffling return values, we need to reset the frame after any "extra"
values are read and before any "extra" values may be set.
Some components of this have been wired up for a while; this commit
finishes the compiler, runtime, and JIT support.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (scm_bootstrap_intrinsics): Declare the new
intrinsics.
* libguile/jit.c (compile_call_f64_from_f64): Define code generators for
the new intrinsics.
* libguile/vm-engine.c (call-f64<-f64): New instruction.
* module/language/cps/effects-analysis.scm:
* module/language/cps/reify-primitives.scm (compute-known-primitives):
* module/language/cps/slot-allocation.scm (compute-var-representations):
* module/language/cps/specialize-numbers.scm (specialize-operations):
* module/language/tree-il/cps-primitives.scm (abs):
* module/system/vm/assembler.scm (system, define-f64<-f64-intrinsic):
(sqrt, abs, fsqrt, fabs):
* module/language/cps/types.scm (fsqrt, fabs): Add new f64<-f64
primitives.
* module/language/cps/closure-conversion.scm (compute-elidable-closures):
New function.
(convert-one, convert-closures): Add ability to set "self" variable of
$kfun to $f, hopefully avoiding passing that argument in some cases.
* module/language/cps/compile-bytecode.scm (compile-function): Pass the
has-closure? bit on through to the assembler.
* module/system/vm/assembler.scm (begin-standard-arity)
(begin-opt-arity, begin-kw-arity): Only reserve space for the closure
as appropriate.
* module/language/cps/slot-allocation.scm (allocate-args)
(compute-defs-and-uses, compute-needs-slot)
(compute-var-representations): Allow for closure slot allocation
differences.
* module/language/cps/cse.scm (compute-defs):
* module/language/cps/dce.scm (compute-live-code):
* module/language/cps/renumber.scm (renumber, compute-renaming):
(allocate-args):
* module/language/cps/specialize-numbers.scm (compute-significant-bits):
(compute-defs):
* module/language/cps/split-rec.scm (compute-free-vars):
* module/language/cps/types.scm (infer-types):
* module/language/cps/utils.scm (compute-max-label-and-var):
* module/language/cps/verify.scm (check-distinct-vars):
(compute-available-definitions): Allow closure to be #f.
* module/language/cps/simplify.scm (eta-reduce): Fix renaming of labels
referenced by prompts. Thanks a million to Stefan Israelsson Tampe
for the report and the fix! Fixes#33652.
Fixes <https://bugs.gnu.org/31474> and related bugs.
Reported by Jan Nieuwenhuizen <janneke@gnu.org>.
* module/language/cps/types.scm (next-power-of-two): Remove procedure.
(non-negative?, lognot*, saturate+, saturate-, logand-bounds)
(logsub-bounds, logior-bounds, logxor-bounds): New procedures. Use them
to improve and fix bugs in the range analysis of the type inferrers for
'logand', 'logsub', 'logior', 'ulogior', 'logxor', 'ulogxor', and
'lognot'.
* am/bootstrap.am (SOURCES):
* module/Makefile.am (SOURCES): Handle renamve of handle-interrupts.scm
to loop-instrumentation.scm.
* libguile/jit.h (SCM_JIT_COUNTER_ENTRY_INCREMENT): Rename from
SCM_JIT_COUNTER_CALL_INCREMENT.
* libguile/vm-engine.c (instrument-entry): Rename from instrument-call.
* module/language/cps/compile-bytecode.scm (compile-function): Add
handle-interrupts code before calls and returns. Compile the
"instrument-loop" primcall to an "instrument-loop" instruction and a
"handle-interrupts" instruction.
(lower-cps): Adapt to add-loop-instrumentation name change.
* module/language/cps/loop-instrumentation.scm: Rename from
handle-interrupts.scm and just add "instrument-loop" primcalls in
loops. The compiler will add handle-interrupts primcalls as
appropriate.
* module/system/vm/assembler.scm (<jit-data>): New data type, for
emitting embedded JIT data.
(<meta>): Add field for current JIT data.
(make-meta): Initialize current JIT data.
(emit-instrument-entry*, emit-instrument-loop*): New instruction
emitters that reference the current JIT data.
(end-program): Now that all labels are known, arrange to serialize the
JIT data.
(link-data): Reserve space for JIT data, and add relocs to initialize
the "start" / "end" fields.
This should reduce frame sizes.
* libguile/vm-engine.c (halt): Adapt to multiple-values change. Also
adapt to not having the boot closure on the stack.
(receive, receive-values, subr-call, foreign-call): Adapt to expect
values one slot down.
(prompt): Capture one less word for the values return.
* libguile/vm.c (vm_dispatch_pop_continuation_hook):
(vm_dispatch_abort_hook): Adapt for where to expect values.
(vm_builtin_values_code): Add a call to shuffle-down before
returning. This is more overhead than what existed before, but the
hope is that the savings elsewhere pay off.
(vm_builtin_values_code): Adapt to different values location.
(reinstate_continuation_x, compose_continuation): Adapt to place
resume args at right position.
(capture_delimited_continuation): Remove unused sp and ip arguments.
(abort_to_prompt): Adapt to capture_delimited_continuation change.
(scm_call_n): Adapt to not reserve space for the boot closure.
* module/language/cps/compile-bytecode.scm (compile-function): When
returning values, adapt reset-frame call for return calling convention
change. Adapt truncating or rest returns to expect values in the
right place.
* module/language/cps/slot-allocation.scm (compute-shuffles):
(allocate-lazy-vars, allocate-slots): Allocate values from the "proc
slot", not proc-slot + 1.
* module/system/vm/assembler.scm (emit-init-constants): Reset the frame
before returning so that the return value is in the right place.
* test-suite/tests/rtl.test: Update for return convention change.
* libguile/foreign.c (get_foreign_stub_code): Update for return calling
convention change.
* libguile/frames.h: Add machine return address to diagram.
(SCM_FRAME_MACHINE_RETURN_ADDRESS):
(SCM_FRAME_SET_MACHINE_RETURN_ADDRESS): New macros.
(SCM_FRAME_PREVIOUS_SP):
(SCM_FRAME_DYNAMIC_LINK):
(SCM_FRAME_SET_DYNAMIC_LINK): Adapt for new frame size.
* libguile/vm-engine.c (halt): Set frame size to 3.
(call, call-label): Set mRA to 0.
* libguile/vm.c (push_interrupt_frame, reinstate_continuation_x):
(scm_call_n): Set frame size to 3. In push_interrupt_frame, init the
mRA of the frame.
(vm_builtin_call_with_values_code, vm_handle_interrupt_code): Allocate
larger frames.
* module/language/cps/slot-allocation.scm (allocate-slots): Frame size
is 3.
* module/system/vm/disassembler.scm (define-clobber-parser): Bump frame
size.
* libguile/frames.c (scm_frame_return_address): Use
SCM_FRAME_VIRTUAL_RETURN_ADDRESS.
(scm_c_frame_previous): Likewise.
* libguile/frames.h: Update diagram for new names.
(union scm_vm_stack_element): Rename "as_ip" to "as_vcode", and
add "as_mcode" for machine code pointers.
(SCM_FRAME_VIRTUAL_RETURN_ADDRESS)
(SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS): Rename to these, from
SCM_FRAME_RETURN_ADDRESS and SCM_FRAME_SET_RETURN_ADDRESS.
* libguile/vm-engine.c (halt, call, call-label, return-values)
(return-from-interrupt): Adapt to renamings. Make "halt" have frame
size as a parameter.
* libguile/vm.c (scm_i_vm_mark_stack): Adapt to renaming.
(push_interrupt_frame): Take mRA as additional argument. In future we
will set it as frame mRA.
(capture_continuation): Adapt to renaming.
(scm_call_n): Adapt to renaming and make frame size adjustable.
(push_interrupt_frame, reinstate_continuation_x): Make frame size
adjustable.
* module/language/cps/slot-allocation.scm (allocate-slots): Make frame
size adjustable.
* libguile/intrinsics.h (scm_t_thread_mra_intrinsic): New type; use for
push_interrupt_frame.
(scm_t_thread_u8_scm_sp_vra_intrinsic): Rename from the same but was
"ra" instead of "vra", and change type to uint32_t*.
* module/system/vm/disassembler.scm (define-clobber-parser):
Parameterize clobber set for calls by frame size.
* libguile/fluids.c (scm_i_fluid_ref): New internal function.
(scm_fluid_ref): Use scm_i_fluid_ref.
* libguile/intrinsics.h:
* libguile/intrinsics.c (current_module): New intrinsic.
* libguile/modules.c (scm_i_current_module): New internal function.
(scm_current_module): Use new internal function.
* module/language/cps/reify-primitives.scm (compute-known-primitives):
Add current-module as an intrinsic primitive.
* module/system/vm/assembler.scm (define-scm<-thread-intrinsic):
(current-module): Arrange to compile to intrinsic call.
* libguile/intrinsics.c (scm_bootstrap_intrinsics):
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Add new define!
intrinsic.
* module/language/cps/compile-bytecode.scm (compile-function): Adapt
compilation for define! to take two arguments.
* module/language/cps/effects-analysis.scm (current-module): Update
define! for two arguments.
* module/language/tree-il/compile-cps.scm (convert): When reifying
"define", grab the current module.
* module/system/vm/assembler.scm (define!): Define assembler as
intrinsic.
* module/system/vm/assembler.scm (<cache-cell>): Remove "scope" member.
Just be an opaque key comparable with equal?.
(intern-cache-cell): Remove scope arg.
(intern-module-cache-cell): Remove; callers use intern-cache-cell now.
(cache-current-module!, cached-toplevel-box, cached-module-box): Create
cache keys that by construction won't collide between types.
(cache-ref, cache-set!): Add new macro assemblers.
* module/language/cps/reify-primitives.scm:
* module/language/cps/compile-bytecode.scm: Add cases for new macro
instructions.
* libguile/intrinsics.c (scm_to_uint64_truncate): New intrinsic.
(scm_bootstrap_intrinsics): Init new intrinsics.
* libguile/intrinsics.h: Add scm->u64, scm->u64/truncate, and scm->s64
as intrinsics, with their corresponding types.
* libguile/vm-engine.c (call-u64<-scm, call-s64<-scm): New intrinsic
calling ops.
(scm->u64, scm->s64, scm->u64/truncate): Disable opcodes.
* module/language/cps/reify-primitives.scm (compute-known-primitives):
Add intrinsics as new macroinstructions.
* module/system/vm/assembler.scm: Declare new intrinsic assemblers.
* module/language/cps/effects-analysis.scm (string-ref): Remove effects
declaration, given that the primitive is exploded now.
* module/language/cps/reify-primitives.scm (compute-known-primitives):
Add string-set!.
* libguile/vm-engine.c (string-set!): Disable opcode.
* module/language/cps/types.scm (string-ref, string-set!): Remove type
checker and inferrers for string-ref and string-set!, as both are
exploded. In the case of string-set! there are still type-check
effects in the intrinsic call but they can't be elided by the checker,
as we don't track when strings are read-only.
* module/language/tree-il/compile-cps.scm (ensure-char): New helper.
(string-set!): New primcall exploded converter.
* module/language/cps/types.scm (annotation->type):
* module/language/cps/effects-analysis.scm (annotation->memory-kind):
Add case for string memory kinds. Remove special type and effect
inferrers for string-length.
* module/language/cps/slot-allocation.scm (compute-var-representations):
Remove string-length.
* module/language/tree-il/compile-cps.scm (ensure-string): New helper.
(string-length): Add custom converter.
* module/language/cps/reify-primitives.scm (compute-known-primitives):
Treat add, sub, and so on as known primitives.
* libguile/vm-engine.c: Remove code for now-unused instructions.