1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 20:00:19 +02:00
Commit graph

9315 commits

Author SHA1 Message Date
Andy Wingo
449ef7d975 Prevent Lightning from stompling our registers
* libguile/jit.c (emit_exit): Add uses of SP and FP.
2018-09-02 09:21:54 +02:00
Andy Wingo
1f42a6042e Add ability to stop JIT after N compilations.
* libguile/jit.c (jit_stop_after, jit_pause_when_stopping): New locals.
  (scm_jit_compute_mcode): Add ability to stop after N compilations.
  (scm_jit_enter_mcode): Comment out printfs for the time being.
  (scm_init_jit): Init locals from environment variables.
2018-09-01 11:28:59 +02:00
Andy Wingo
7c0bfcb097 Minor 32-bit untag-fixnum optimization
* libguile/jit.c (compile_untag_fixnum): Minor optimization in 32-bit
  case.
2018-09-01 10:29:05 +02:00
Andy Wingo
dafa648915 Fix compilation of compile_eq
* libguile/jit.c (compile_eq): Compare to register, not immediate.
2018-09-01 10:11:17 +02:00
Andy Wingo
79be7028e4 More JIT debugging
* libguile/jit.c (compile1): Add debug for when instructions are first
  compiled.  Will be removed when all is working.
  (compute_mcode): Add debugging about what code is compiled.
  (scm_sys_jit_compile): Remove per-instruction output.
  (scm_jit_compute_mcode): Actually compile JIT code.  Use
  GUILE_JIT_COUNTER_THRESHOLD to control when JIT happens.
2018-08-31 15:50:46 +02:00
Andy Wingo
cc997293e2 JIT threshold controlled by environment variable
* libguile/jit.c (scm_jit_counter_threshold): Make a static variable
  instead of a compile-time constant.
  (scm_init_jit): Init scm_jit_counter_threshold from
  GUILE_JIT_COUNTER_THRESHOLD environment variable.  Default is -1
  indicating "never JIT".
* libguile/vm-engine.c (instrument-entry, instrument-loop): Adapt to new
  variable.
2018-08-31 11:28:38 +02:00
Andy Wingo
def671974c Minor optimization in compile_alloc_frame
* libguile/jit.c (compile_alloc_frame): Remove useless FP reload.
2018-08-31 10:54:34 +02:00
Andy Wingo
dac43443a3 Fix bind-kwargs JIT compilation
* libguile/jit.c (COMPILE_X8_C24__C8_C24__X8_C24__N32): Fix unpacking of
  N32 arg.
2018-08-29 22:29:39 +02:00
Andy Wingo
6da132cb95 Fix JIT compilation of composable continuations
* libguile/control.c (compose_continuation_code): Fix offset of code
  end.
* libguile/jit.c (compile_compose_continuation): Fix test for mcode not
  null.
2018-08-29 22:15:20 +02:00
Andy Wingo
f32d17d386 Fix jit function data for goto_continuation_code
* libguile/continuations.c (goto_continuation_code): Fix offset of end
  of code.
2018-08-29 21:44:38 +02:00
Andy Wingo
15314fdc07 Fix JIT compilation of shuffle-down
* libguile/jit.c (compile_shuffle_down): Fix compilation.
2018-08-29 20:29:57 +02:00
Andy Wingo
c02c89d533 Fix JIT compilation of call-with-prompt
* libguile/jit.c (compile_prompt): Actually push the MRA arg.
  (analyze): Mark call continuations as entries, as both FP and SP are
  set then, and also mark prompt handlers as entries (and blocks).
2018-08-29 20:00:03 +02:00
Andy Wingo
66fb76db2b Fix miscompilation for "abort" opcode
* libguile/jit.c (compile_abort): Fix miscompilation.
2018-08-29 19:41:47 +02:00
Andy Wingo
f2089ceee9 Add fast paths to intrinsics
* libguile/intrinsics.c (add_immediate, sub_immediate, less_p)
  (numerically_equal_p): Add fast paths.  Makes one test locally go from
  .77s interpreted to .60s.
  (scm_to_uint64_truncate): Add a likelihood annotation.
2018-08-29 18:40:56 +02:00
Andy Wingo
24d09b16b6 Maybe enter JIT when returning from interpreted functions
* libguile/jit.c (scm_jit_compute_mcode): Minor optimization.
* libguile/vm-engine.c (return-values): Maybe return to JIT code.
2018-08-29 17:54:19 +02:00
Andy Wingo
c03e2bbbb4 JIT tracks register clobbers
* libguile/jit.c (struct scm_jit_state): Add beginnings of a little
  local register allocator.
  (reset_register_state): New helper.
  (clear_scratch_register_state): Use new helper.
  (record_gpr_clobber, record_fpr_clobber): New helpers, used when there
  may be cached variables in registers, called when registers are
  written.
  (set_sp_cache_gpr, set_sp_cache_fpr): New helpers, called when results
  are written to the stack.
  (emit_retval, emit_movi, emit_ldxi, DEFINE_CLOBBER_RECORDING_EMITTER_R)
  (DEFINE_CLOBBER_RECORDING_EMITTER_P, DEFINE_CLOBBER_RECORDING_EMITTER_R_I)
  (DEFINE_CLOBBER_RECORDING_EMITTER_R_R): New wrappers for Lightning API
  that also records register clobbers.  Update callers.
  (save_reloadable_register_state): New helper.
  (restore_reloadable_register_state): Rename from
  ensure_register_state.
2018-08-29 14:01:20 +02:00
Andy Wingo
10bfd55ec3 JIT: Store FP in register during procedure prolog/epilog
* libguile/jit.c (scm_jit_state): Add op_attrs array, for a pre-pass,
  and store state of what's in registers.
  (SP, FP): Reassign to scratch registers, as in general these need to
  be reloaded anyway after callouts.
  (die, DIE, ASSERT, UNREACHABLE): Add better invariant-testing.
  (clear_register_state, clear_scratch_register_state)
  (set_register_state, has_register_state, ASSERT_HAS_REGISTER_STATE):
  Add machinery to track state of SP and FP.  Can eventually track
  scratch register assignments as well.  Adapt code to use these.
  (compile_atomic_ref_scm_immediate): Compile to a vanilla load on x86.
  (compile_handle_interrupts): Analogous atomic-ref changes here.
  (analyze): New helper, a simple once-through pre-pass to identify
  branch targets.
  (compile): Only generate labels for branch targets.  Reset register
  state at branch targets.
  (compute_mcode): Initialize j->op_attrs appropriately.
2018-08-28 16:03:21 +02:00
Andy Wingo
4fb99e9454 Bug-fix for alloc-frame and stack moving
* libguile/jit.c (emit_push_frame): Simplification; we never need to
  store old_fp and new_fp at once.
  (compile_alloc_frame): Fix to not keep a pointer into the stack across
  a stack expansion.
2018-08-26 15:13:01 +02:00
Andy Wingo
98b4c46a36 Minor JIT refactor
* libguile/jit.c (emit_alloc_frame_for_sp): Remove unused "fp" arg.
  Adapt callers.
2018-08-26 10:25:52 +02:00
Andy Wingo
18dfe48fc4 Fuse comparisons and branches in JIT
* libguile/jit.c (emit_load_compare_result)
  (emit_store_compare_result): Remove these.
  (emit_branch_if_frame_locals_count_not_eq): New helper.
  (fuse_conditional_branch): New helper.
* libguile/jit.c (compile_u64_numerically_equal)
  (compile_u64_less, compile_s64_less, compile_f64_numerically_equal)
  (compile_f64_less, compile_numerically_equal, compile_less)
  (compile_check_arguments, compile_check_positional_arguments):
  (compile_immediate_tag_equals, compile_heap_tag_equals)
  (compile_eq, compile_heap_numbers_equal)
  (compile_s64_imm_numerically_equal, compile_u64_imm_less)
  (compile_imm_u64_less, compile_s64_imm_less, compile_imm_s64_less):
  Fuse conditional branches, to avoid going through compare-result.
  (compile_jl, compile_je, compile_jnl, compile_jne, compile_jge)
  (compile_jnge): Abort, since they shouldn't be reachable.
2018-08-25 16:20:49 +02:00
Andy Wingo
dfc0b902dc JIT refactor
* libguile/jit.c (struct scm_jit_state): Store next ip, so that
  compilers can fuse opcodes.
  (op_lengths): New static variable.
  (emit_direct_tail_call): Add a fast case for self-recursion.
  (compile1): Move IP advancement out of the specific arity compilers;
  instead precompute a "next_ip", that can be incremented.
2018-08-25 14:36:58 +02:00
Andy Wingo
9574245676 Fix again the unknown-filling of alloc-frame
* libguile/jit.c (compile_alloc_frame): Yet another fix, because I am an
  idiot.
2018-08-24 16:19:51 +02:00
Andy Wingo
d0c9d20626 Fix JIT compilation of bind-rest
* libguile/jit.c (compile_bind_rest): Fix.
2018-08-24 14:59:47 +02:00
Andy Wingo
3920b99125 Fix fp-ref, fp-set! helpers in jit for signedness
* libguile/jit.c (emit_fp_ref_scm, emit_fp_set_scm): Fix signedless of
  offsets.
2018-08-24 12:58:54 +02:00
Andy Wingo
02a9e76b57 Fix bug in compile-alloc-frame
* libguile/jit.c (compile_alloc_frame): Fix alloc-frame filling in of
  undefined values for when previous frame size was unknown.
2018-08-24 12:14:29 +02:00
Andy Wingo
5603079995 Clear frame size after subr-call, return-values
* libguile/jit.c (compile_return_values, compile_subr_call): Clear frame
  size.
2018-08-24 11:43:50 +02:00
Andy Wingo
270147cf88 Fix r12 register spec for lightning with sysv x86-64 ABI
* libguile/lightning/lib/jit_x86.c (_rvs): Mark R12 as callee-save.
2018-08-24 11:43:09 +02:00
Andy Wingo
25e9b0f79d 32-bit fix for emit_run_hook
* libguile/jit.c (emit_run_hook): Use sign-extending load, as unsigned
  load doesn't exist on 32-bit targets.
2018-08-23 19:53:17 +02:00
Andy Wingo
7854460fac Minor refactors to jit.c
* libguile/jit.c (emit_direct_tail_call): Add FIXME.
  (emit_mov): Simplify implementation.
  (emit_branch_if_frame_locals_count_less_than):
  (emit_branch_if_frame_locals_count_eq):
  (emit_branch_if_frame_locals_count_greater_than):
  (emit_load_fp_slot):
  (emit_branch_if_immediate):
  (emit_load_heap_object_word):
  (emit_load_heap_object_tc):
  (emit_branch_if_heap_object_has_tc):
  (emit_branch_if_heap_object_not_tc):
  (emit_branch_if_heap_object_not_tc7):
  (emit_entry_trampoline):
  (emit_handle_interrupts_trampoline):
  (initialize_handle_interrupts_trampoline):
  (emit_free_variable_ref): Move later in the file.
2018-08-23 19:45:36 +02:00
Andy Wingo
bf035d9385 Fix load width of get-ip-relative-addr
* libguile/jit.c (emit_get_ip_relative_addr): Fix load width.
2018-08-23 17:19:15 +02:00
Andy Wingo
065efdd101 Fix in-tree builds
* libguile/Makefile.am (AM_CPPFLAGS): Use -iquote for $(builddir)
  instead of -I, to avoid having in-tree builds find libguile/poll.h for
  <poll.h>.
2018-08-23 10:47:00 +02:00
Andy Wingo
fd1deab3c3 Optimizations to subr-call
* libguile/jit.c (compile_subr_call): Optimizations.
2018-08-23 10:27:27 +02:00
Andy Wingo
01a79bed89 Comments in the JIT
* libguile/jit.c: Add some overview comments.
2018-08-23 10:24:30 +02:00
Daniel Llorens
01c14512d6 Add $(builddir) to include path in libguile/Makefile.am 2018-08-21 18:41:34 +02:00
Andy Wingo
77695612f4 Add support for labels, and fix a bug in uadd/imm and usub/imm.
* libguile/jit.c (add_inter_instruction_patch, compile, compute_mcode):
  Add support for labels.
  (compile_uadd_immediate, compile_usub_immediate): Fix cases where we
  were adding the wrong operand as an immediate.
2018-08-20 15:35:47 +02:00
Andy Wingo
d7fcdd9a2e Add out-of-line handle-interrupts trampoline stub
* libguile/jit.c (emit_handle_interrupts_trampoline)
  (initialize_handle_interrupts_trampoline)
  (compile_handle_interrupts): Handle most of the slow case of
  handle-interrupts out-of-line, to avoid code bloat.
2018-08-20 14:57:00 +02:00
Andy Wingo
916c570557 Tweak to instrument-entry
* libguile/vm-engine.c (instrument-entry): Eagerly check if data->mcode
  is already set, and in that case just jump directly without checking
  the counter.
2018-08-20 12:45:07 +02:00
Andy Wingo
9c76a1ad42 Fix frame popping in JIT
* libguile/jit.c (emit_entry_trampoline): Don't bother hackily trying to
  save registers; the "jit_frame" call handles that.
  (compile_return_values, compile_return_from_interrupt): Fix bug when
  computing previous FP: no need to add frame_overhead_slots.
  (emit_load_prev_fp_offset, emit_store_prev_fp_offset): Rename from
  emit_load_prev_frame_size, emit_store_prev_frame_size.
  (emit_push_frame): Adapt to emit_store_prev_frame_size.  Don't
  subtract off the frame_overhead_slots.
  (scm_jit_enter_mcode): Comment out a printf for the time being.
2018-08-20 12:45:00 +02:00
Andy Wingo
d00150303d JIT compilation tweaks
* libguile/jit.c (emit_alloc_frame_for_sp, compile_current_thread): Fix
  some ldxr/ldxi stxr/stxi confusions.
  (compile_alloc_frame): Omit if the frame size is already correct.
  (compile, compute_mcode, scm_sys_jit_compile, scm_jit_enter_mcode):
  Add a bit more debugging.
2018-08-20 11:43:46 +02:00
Andy Wingo
4a9de64f81 Fix default code allocator in Lightning
* libguile/lightning/lib/lightning.c (_jit_emit): The default code
  allocator will simply mmap a code buffer, try to emit into that
  buffer, and if it fails, try again with a larger buffer.  However the
  buffer size starts at 0, for some reason.  Why?  I can't see the
  reason.  Change the default to 4096.  In the future we will need to
  implement our own allocator anyway so that we can pack multiple JIT
  runs in one page.
2018-08-20 08:59:19 +02:00
Andy Wingo
dca1e9d7bd Manual JIT interface via %jit-compile
* libguile/init.c (scm_i_init_guile): Call scm_init_jit ().
* libguile/jit.c (enter_mcode, exit_mcode): New static members; code
  pointers for the JIT trampoline.
  (emit_exit): New helper.  The Lightning tramp/frame mechanism that we
  use needs to exit via a jmp instead of a return.  Adapt callers of
  jit_ret.
  (emit_entry_trampoline): Use the "frame" mechanism to enter the JIT.
  (compile1): Add missing "break" after case statements.  Oops!
  (compile): Add prolog and "tramp" to compiled functions.
  (initialize_jit): New local routine to init the JIT on demand.
  (compute_mcode): New helper, to compile a function.
  (scm_sys_jit_compile): New function, exported to Scheme as
  %jit-compile.
  (scm_jit_compute_mcode): Return the existing mcode if the function is
  at the start.
  (scm_jit_enter_mcode): Call the enter_mcode trampoline.
* libguile/jit.h (struct scm_jit_state): Declare, so we can make
  pointers to it.
* libguile/threads.h (struct scm_thread): Add jit_state member.
* libguile/threads.c (on_thread_exit): Free the jit state.
2018-08-20 08:56:35 +02:00
Andy Wingo
698bff8748 First implementation of a template JIT
* libguile/jit.c: Implement most of a JIT.  Untested and still needs to
  be wired up.
2018-08-19 17:39:16 +02:00
Andy Wingo
110310b3e7 Expose scm_vm_builtin_ref internally
* libguile/vm-builtins.h:
* libguile/vm.c (scm_vm_builtin_ref): Expose internally.
2018-08-19 17:38:59 +02:00
Andy Wingo
cf0270cb4c Add internal function mapping subr index to function
* libguile/gsubr.h:
* libguile/gsubr.c (scm_subr_function_by_index): New internal function.
  (scm_subr_function): Use new function.
2018-08-19 17:38:11 +02:00
Andy Wingo
3827769aff Add instrumentation to VM builtins
* libguile/intrinsics.h: Add "intrinsic" for handle-interrupts code.
  Unlike the other intrinsics, this one isn't a function.
* libguile/programs.c (try_parse_arity): Add cases for instructions used
  in VM builtins.
  (scm_primitive_call_ip): Return #f if call-ip not found.
* libguile/vm-engine.c (handle-interrupts): Get code from intrinsics.
* libguile/vm.c
* libguile/vm.c (instrumented_code, define_vm_builtins): Add
  instrumentation to the builtins, so that they can be JIT-compiled.
  (INIT_BUILTIN): Remove min-arity setting; the fallback min-arity
  interpreter should figure it out.
  (scm_bootstrap_vm): Call the new define_vm_builtins function.
* libguile/gsubr.c (primitive_call_ip): Return 0 if call IP not found.
  (primitive_subr_idx): Interpret call ip == 0 as not-a-subr.
* module/system/vm/program.scm (program-arguments-alist): Allow a #f
  call-ip.
2018-08-17 08:50:33 +02:00
Andy Wingo
e6304fb242 Define intrinsics for atomic ops
* libguile/intrinsics.h:
* libguile/intrinsics.c (atomic_ref_scm, atomic_set_scm):
  (atomic_swap_scm, atomic_compare_and_swap_scm): New intrinsics, given
  that lightning doesn't know atomics.
  (scm_bootstrap_intrinsics): Init new intrinsics.
* libguile/vm-engine.c (atomic-scm-ref/immediate)
  (atomic-scm-set!/immediate, atomic-scm-swap!/immediate)
  (atomic-scm-compare-and-swap!/immediate): Use intrinsics, to be like
  the JIT.
2018-08-13 22:00:19 +02:00
Andy Wingo
0188bd3816 64-bit intrinsic args and return values passed indirectly on 32-bit
* libguile/intrinsics.h (INDIRECT_INT64_INTRINSICS): New definition.  If
  true, int64 args and return values are passed by reference.  Here to
  make JIT easier.
* libguile/intrinsics.c (indirect_scm_to_int64, indirect_scm_to_uint64):
  (indirect_scm_to_uint64_truncate, indirect_scm_from_int64):
  (indirect_scm_from_uint64, indirect_lsh, indirect_rsh): New indirect
  variants.
  (scm_bootstrap_intrinsics): Use indirect variants as appropriate.
* libguile/vm-engine.c: Update to call indirect intrinsics if
  appropriate.
2018-08-13 22:00:15 +02:00
Andy Wingo
d4abe8bbed Avoid needless 64-bit args on 32-bit machines for some intrinsics
* libguile/intrinsics.h:
* libguile/intrinsics.c (string_set_x): Change to take size_t and u32 as
  args.
  (allocate_words): Change to take size_t as arg.
* libguile/vm.c (expand_apply_argument): Rename from rest_arg_length,
  and also handle the stack manipulation.
* libguile/vm-engine.c (expand-apply-argument): Update for intrinsic
  change.
  (call-scm-sz-u32): Rename from call-scm-u64-u64, as it matches its
  uses and will compile better on 32-bit systems.
* module/system/vm/assembler.scm (define-scm-sz-u32-intrinsic):
  (string-set!): Update for new instrinsic call inst.
* libguile/jit.c (compile_call_scm_sz_u32): Adapt.
2018-08-13 14:30:01 +02:00
Andy Wingo
11940f4c72 Update error-wrong-num-args intrinsic prototype
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (error_wrong_num_args): Take the thread as an
  arg, instead of the ostensible callee.
* libguile/vm-engine.c: Update callers of wrong-num-args intrinsic to
  pass a thread instead.
2018-08-13 10:59:09 +02:00
Andy Wingo
5df43b60a9 Adapt JIT calling convention; continuations take mra from stack
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Update prototype of
  capture-continuation.
* libguile/jit.h:
* libguile/jit.c (scm_jit_enter_mcode): Return void, not the vra.
  Instead, we expect the code to set vp->ip for the vra.
* libguile/vm-engine.c (instrument-entry, instrument-loop)
  (return-values, abort): Adapt scm_jit_enter_mcode calling convention.
  (capture-continuation): No need to pass an mra; the intrinsic will
  read it from the stack.
* libguile/vm.c (capture_continuation): Remove mra arg, as we take mra
  from the continuation.
  (scm_call_n): Adapt to scm_jit_enter_mcode change.
2018-08-13 10:32:13 +02:00