guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 02/05: Minor refactors to jit.c


From: Andy Wingo
Subject: [Guile-commits] 02/05: Minor refactors to jit.c
Date: Fri, 24 Aug 2018 05:44:37 -0400 (EDT)

wingo pushed a commit to branch lightning
in repository guile.

commit 7854460fac3838f886b2f135ae067fccac526966
Author: Andy Wingo <address@hidden>
Date:   Thu Aug 23 19:45:36 2018 +0200

    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.
---
 libguile/jit.c | 354 ++++++++++++++++++++++++++++-----------------------------
 1 file changed, 175 insertions(+), 179 deletions(-)

diff --git a/libguile/jit.c b/libguile/jit.c
index ef9534b..048b897 100644
--- a/libguile/jit.c
+++ b/libguile/jit.c
@@ -510,6 +510,8 @@ emit_direct_tail_call (scm_jit_state *j, const uint32_t 
*vcode)
 
       if (data->mcode)
         {
+          /* FIXME: Jump indirectly, to allow mcode to be changed
+             (e.g. to add/remove breakpoints or hooks).  */
           jit_patch_abs (jit_jmpi (), data->mcode);
         }
       else
@@ -557,183 +559,6 @@ emit_sp_set_scm (scm_jit_state *j, uint32_t slot, 
jit_gpr_t val)
     jit_stxi (8 * slot, SP, val);
 }
 
-static void
-emit_mov (scm_jit_state *j, uint32_t dst, uint32_t src, jit_gpr_t t)
-{
-  /* FIXME: The compiler currently emits "push" for SCM, F64, U64,
-     and S64 variables.  However SCM values are the usual case, and
-     on a 32-bit machine it might be cheaper to move a SCM than to
-     move a 64-bit number.  */
-  if (sizeof (void*) < sizeof (union scm_vm_stack_element))
-    {
-      uintptr_t src_offset = src * sizeof (union scm_vm_stack_element);
-      uintptr_t dst_offset = dst * sizeof (union scm_vm_stack_element);
-
-      jit_ldxi (t, SP, src_offset + sizeof (void*));
-      jit_stxi (dst_offset + sizeof (void*), SP, t);
-      if (src_offset == 0)
-        jit_ldr (t, SP);
-      else
-        jit_ldxi (t, SP, src_offset);
-      if (dst_offset == 0)
-        jit_str (SP, t);
-      else
-        jit_stxi (dst_offset, SP, t);
-    }
-  else
-    {
-      emit_sp_ref_scm (j, t, src);
-      emit_sp_set_scm (j, dst, t);
-    }
-}
-
-static void
-emit_run_hook (scm_jit_state *j, jit_gpr_t t, scm_t_thread_intrinsic f)
-{
-  jit_node_t *k;
-  jit_ldxi_ui (T0, THREAD, thread_offset_trace_level);
-  k = jit_beqi (T0, 0);
-  emit_store_current_ip (j, T0);
-  emit_call_r (j, f, THREAD);
-  emit_reload_sp (j);
-  jit_patch (k);
-}
-
-static jit_node_t*
-emit_branch_if_frame_locals_count_less_than (scm_jit_state *j, jit_gpr_t fp,
-                                             jit_gpr_t t, uint32_t nlocals)
-{
-  jit_subr (t, fp, SP);
-  return jit_blti (t, nlocals * sizeof (union scm_vm_stack_element));
-}
-
-static jit_node_t*
-emit_branch_if_frame_locals_count_eq (scm_jit_state *j, jit_gpr_t fp,
-                                      jit_gpr_t t, uint32_t nlocals)
-{
-  jit_subr (t, fp, SP);
-  return jit_beqi (t, nlocals * sizeof (union scm_vm_stack_element));
-}
-
-static jit_node_t*
-emit_branch_if_frame_locals_count_greater_than (scm_jit_state *j, jit_gpr_t fp,
-                                                jit_gpr_t t, uint32_t nlocals)
-{
-  jit_subr (t, fp, SP);
-  return jit_bgti (t, nlocals * sizeof (union scm_vm_stack_element));
-}
-
-static void
-emit_load_fp_slot (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t fp, uint32_t 
slot)
-{
-  jit_subi (dst, fp, (slot + 1) * sizeof (union scm_vm_stack_element));
-}
-
-static jit_node_t *
-emit_branch_if_immediate (scm_jit_state *j, jit_gpr_t r)
-{
-  return jit_bmsi (r, 6);
-}
-
-static void
-emit_load_heap_object_word (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
-                            uint32_t word)
-{
-  if (word == 0)
-    jit_ldr (dst, r);
-  else
-    jit_ldxi (dst, r, word * sizeof(SCM));
-}
-
-static void
-emit_load_heap_object_tc (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
-                          scm_t_bits mask)
-{
-  emit_load_heap_object_word (j, dst, r, 0);
-  jit_andi (dst, dst, mask);
-}
-
-static jit_node_t *
-emit_branch_if_heap_object_has_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
-                                   scm_t_bits mask, scm_t_bits tc)
-{
-  emit_load_heap_object_tc (j, t, r, mask);
-  return jit_beqi (t, tc);
-}
-
-static jit_node_t *
-emit_branch_if_heap_object_not_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
-                                   scm_t_bits mask, scm_t_bits tc)
-{
-  emit_load_heap_object_tc (j, t, r, mask);
-  return jit_bnei (t, tc);
-}
-
-static jit_node_t *
-emit_branch_if_heap_object_not_tc7 (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
-                                    scm_t_bits tc7)
-{
-  return emit_branch_if_heap_object_not_tc (j, r, t, 0x7f, tc7);
-}
-
-static jit_node_t*
-emit_entry_trampoline (scm_jit_state *j)
-{
-  jit_node_t *thread, *ip, *exit;
-  jit_prolog ();
-  jit_frame (entry_frame_size);
-  thread = jit_arg ();
-  ip = jit_arg ();
-  /* Load our reserved registers: THREAD and SP.  */
-  jit_getarg (THREAD, thread);
-  emit_reload_sp (j);
-  /* Jump to the mcode!  */
-  jit_getarg (JIT_R0, ip);
-  jit_jmpr (JIT_R0);
-  exit = jit_indirect ();
-  /* When mcode returns, interpreter should continue with vp->ip.  */
-  jit_ret ();
-  return exit;
-}
-
-static void
-emit_handle_interrupts_trampoline (scm_jit_state *j)
-{
-  jit_prolog ();
-  jit_tramp (entry_frame_size);
-
-  /* Precondition: IP synced, MRA in T0.  */
-  emit_call_r_r (j, scm_vm_intrinsics.push_interrupt_frame, THREAD, T0);
-  emit_reload_sp (j);
-  emit_direct_tail_call (j, scm_vm_intrinsics.handle_interrupt_code);
-}
-
-static scm_i_pthread_once_t initialize_handle_interrupts_trampoline_once =
-  SCM_I_PTHREAD_ONCE_INIT;
-static void
-initialize_handle_interrupts_trampoline (void)
-{
-  scm_thread *thread = SCM_I_CURRENT_THREAD;
-  scm_jit_state saved_jit_state, *j = thread->jit_state;
-
-  memcpy (&saved_jit_state, j, sizeof (*j));
-
-  j->jit = jit_new_state ();
-  emit_handle_interrupts_trampoline (j);
-  handle_interrupts_trampoline = jit_emit ();
-  jit_clear_state ();
-
-  memcpy (j, &saved_jit_state, sizeof (*j));
-}
-
-static void
-emit_free_variable_ref (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t prog,
-                        size_t n)
-{
-  emit_load_heap_object_word (j, dst, prog,
-                              n + program_word_offset_free_variable);
-}
-
 /* Use when you know that the u64 value will be within the size_t range,
    for example when it's ensured by the compiler.  */
 static void
@@ -807,7 +632,9 @@ emit_sp_ref_ptr (scm_jit_state *j, jit_gpr_t dst, uint32_t 
src)
 {
   emit_sp_ref_u64 (j, dst, src);
 }
-#else
+
+#else /* SCM_SIZEOF_UINTPTR_T >= 8 */
+
 static void
 emit_sp_ref_u64 (scm_jit_state *j, jit_gpr_t dst_lo, jit_gpr_t dst_hi,
                  uint32_t src)
@@ -876,7 +703,7 @@ emit_sp_ref_ptr (scm_jit_state *j, jit_gpr_t dst, uint32_t 
src)
 {
   emit_sp_ref_u64_lower_half (j, dst, src);
 }
-#endif
+#endif /* SCM_SIZEOF_UINTPTR_T >= 8 */
 
 static void
 emit_sp_ref_f64 (scm_jit_state *j, jit_gpr_t dst, uint32_t src)
@@ -900,6 +727,175 @@ emit_sp_set_f64 (scm_jit_state *j, uint32_t dst, 
jit_gpr_t src)
     jit_stxi_d (offset, SP, src);
 }
 
+
+static void
+emit_mov (scm_jit_state *j, uint32_t dst, uint32_t src, jit_gpr_t t)
+{
+  emit_sp_ref_scm (j, t, src);
+  emit_sp_set_scm (j, dst, t);
+
+  /* FIXME: The compiler currently emits "push", "mov", etc for SCM,
+     F64, U64, and S64 variables.  However SCM values are the usual
+     case, and on a 32-bit machine it might be cheaper to move a SCM
+     than to move a 64-bit number.  */
+  if (sizeof (void*) < sizeof (union scm_vm_stack_element))
+    {
+      /* Copy the high word as well.  */
+      uintptr_t src_offset = src * sizeof (union scm_vm_stack_element);
+      uintptr_t dst_offset = dst * sizeof (union scm_vm_stack_element);
+
+      jit_ldxi (t, SP, src_offset + sizeof (void*));
+      jit_stxi (dst_offset + sizeof (void*), SP, t);
+    }
+}
+
+static void
+emit_run_hook (scm_jit_state *j, jit_gpr_t t, scm_t_thread_intrinsic f)
+{
+  jit_node_t *k;
+  jit_ldxi_ui (T0, THREAD, thread_offset_trace_level);
+  k = jit_beqi (T0, 0);
+  emit_store_current_ip (j, T0);
+  emit_call_r (j, f, THREAD);
+  emit_reload_sp (j);
+  jit_patch (k);
+}
+
+static jit_node_t*
+emit_branch_if_frame_locals_count_less_than (scm_jit_state *j, jit_gpr_t fp,
+                                             jit_gpr_t t, uint32_t nlocals)
+{
+  jit_subr (t, fp, SP);
+  return jit_blti (t, nlocals * sizeof (union scm_vm_stack_element));
+}
+
+static jit_node_t*
+emit_branch_if_frame_locals_count_eq (scm_jit_state *j, jit_gpr_t fp,
+                                      jit_gpr_t t, uint32_t nlocals)
+{
+  jit_subr (t, fp, SP);
+  return jit_beqi (t, nlocals * sizeof (union scm_vm_stack_element));
+}
+
+static jit_node_t*
+emit_branch_if_frame_locals_count_greater_than (scm_jit_state *j, jit_gpr_t fp,
+                                                jit_gpr_t t, uint32_t nlocals)
+{
+  jit_subr (t, fp, SP);
+  return jit_bgti (t, nlocals * sizeof (union scm_vm_stack_element));
+}
+
+static void
+emit_load_fp_slot (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t fp, uint32_t 
slot)
+{
+  jit_subi (dst, fp, (slot + 1) * sizeof (union scm_vm_stack_element));
+}
+
+static jit_node_t *
+emit_branch_if_immediate (scm_jit_state *j, jit_gpr_t r)
+{
+  return jit_bmsi (r, 6);
+}
+
+static void
+emit_load_heap_object_word (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
+                            uint32_t word)
+{
+  if (word == 0)
+    jit_ldr (dst, r);
+  else
+    jit_ldxi (dst, r, word * sizeof(SCM));
+}
+
+static void
+emit_load_heap_object_tc (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t r,
+                          scm_t_bits mask)
+{
+  emit_load_heap_object_word (j, dst, r, 0);
+  jit_andi (dst, dst, mask);
+}
+
+static jit_node_t *
+emit_branch_if_heap_object_has_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
+                                   scm_t_bits mask, scm_t_bits tc)
+{
+  emit_load_heap_object_tc (j, t, r, mask);
+  return jit_beqi (t, tc);
+}
+
+static jit_node_t *
+emit_branch_if_heap_object_not_tc (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
+                                   scm_t_bits mask, scm_t_bits tc)
+{
+  emit_load_heap_object_tc (j, t, r, mask);
+  return jit_bnei (t, tc);
+}
+
+static jit_node_t *
+emit_branch_if_heap_object_not_tc7 (scm_jit_state *j, jit_gpr_t r, jit_gpr_t t,
+                                    scm_t_bits tc7)
+{
+  return emit_branch_if_heap_object_not_tc (j, r, t, 0x7f, tc7);
+}
+
+static jit_node_t*
+emit_entry_trampoline (scm_jit_state *j)
+{
+  jit_node_t *thread, *ip, *exit;
+  jit_prolog ();
+  jit_frame (entry_frame_size);
+  thread = jit_arg ();
+  ip = jit_arg ();
+  /* Load our reserved registers: THREAD and SP.  */
+  jit_getarg (THREAD, thread);
+  emit_reload_sp (j);
+  /* Jump to the mcode!  */
+  jit_getarg (JIT_R0, ip);
+  jit_jmpr (JIT_R0);
+  exit = jit_indirect ();
+  /* When mcode returns, interpreter should continue with vp->ip.  */
+  jit_ret ();
+  return exit;
+}
+
+static void
+emit_handle_interrupts_trampoline (scm_jit_state *j)
+{
+  jit_prolog ();
+  jit_tramp (entry_frame_size);
+
+  /* Precondition: IP synced, MRA in T0.  */
+  emit_call_r_r (j, scm_vm_intrinsics.push_interrupt_frame, THREAD, T0);
+  emit_reload_sp (j);
+  emit_direct_tail_call (j, scm_vm_intrinsics.handle_interrupt_code);
+}
+
+static scm_i_pthread_once_t initialize_handle_interrupts_trampoline_once =
+  SCM_I_PTHREAD_ONCE_INIT;
+static void
+initialize_handle_interrupts_trampoline (void)
+{
+  scm_thread *thread = SCM_I_CURRENT_THREAD;
+  scm_jit_state saved_jit_state, *j = thread->jit_state;
+
+  memcpy (&saved_jit_state, j, sizeof (*j));
+
+  j->jit = jit_new_state ();
+  emit_handle_interrupts_trampoline (j);
+  handle_interrupts_trampoline = jit_emit ();
+  jit_clear_state ();
+
+  memcpy (j, &saved_jit_state, sizeof (*j));
+}
+
+static void
+emit_free_variable_ref (scm_jit_state *j, jit_gpr_t dst, jit_gpr_t prog,
+                        size_t n)
+{
+  emit_load_heap_object_word (j, dst, prog,
+                              n + program_word_offset_free_variable);
+}
+
 static void
 add_inter_instruction_patch (scm_jit_state *j, jit_node_t *label,
                              const uint32_t *target)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]