From e1228154e1f050746c33384f969ece0dd9ebba42 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Wed, 17 Sep 2025 15:15:40 +0200 Subject: [PATCH] Make native lisp code reflect EQ C implementation * src/comp.c (ABI_VERSION): Bump new version (comp_t): add 'eq'. (helper_link_table): add 'slow_eq'. (emit_slow_eq): New function. (emit_EQ): Rework to reflect EQ implementation. (declare_runtime_imported_funcs): Import 'slow_eq'. (Fcomp__init_ctxt): Register emitter 'emit_eq' for op code Qeq. This and the previous 2 commits increase elisp-benchmarks performance by 3.6% on my test machine. Also a (small) reduction in eln size comes with it. --- src/comp.c | 107 ++++++++++++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/src/comp.c b/src/comp.c index 1e06f83dcbd..162716279b2 100644 --- a/src/comp.c +++ b/src/comp.c @@ -468,7 +468,7 @@ load_gccjit_if_necessary (bool mandatory) /* Increase this number to force a new Vcomp_abi_hash to be generated. */ -#define ABI_VERSION "11" +#define ABI_VERSION "12" /* Length of the hashes used for eln file naming. */ #define HASH_LENGTH 8 @@ -630,6 +630,7 @@ typedef struct { gcc_jit_function *add1; gcc_jit_function *sub1; gcc_jit_function *negate; + gcc_jit_function *eq; gcc_jit_function *car; gcc_jit_function *cdr; gcc_jit_function *setcar; @@ -693,6 +694,7 @@ static void *helper_link_table[] = helper_unbind_n, helper_save_restriction, helper_GET_SYMBOL_WITH_POSITION, + slow_eq, helper_sanitizer_assert, record_unwind_current_buffer, set_internal, @@ -1480,17 +1482,6 @@ emit_CONSP (gcc_jit_rvalue *obj) return emit_TAGGEDP (obj, Lisp_Cons); } -static gcc_jit_rvalue * -emit_BARE_SYMBOL_P (gcc_jit_rvalue *obj) -{ - emit_comment ("BARE_SYMBOL_P"); - - return gcc_jit_context_new_cast (comp.ctxt, - NULL, - emit_TAGGEDP (obj, Lisp_Symbol), - comp.bool_type); -} - static gcc_jit_rvalue * emit_SYMBOL_WITH_POS_P (gcc_jit_rvalue *obj) { @@ -1511,52 +1502,46 @@ emit_SYMBOL_WITH_POS_P (gcc_jit_rvalue *obj) } static gcc_jit_rvalue * -emit_SYMBOL_WITH_POS_SYM (gcc_jit_rvalue *obj) +emit_slow_eq (gcc_jit_rvalue *x, gcc_jit_rvalue *y) { - emit_comment ("SYMBOL_WITH_POS_SYM"); + gcc_jit_rvalue *args[] = + { emit_coerce (comp.lisp_obj_type, x), + emit_coerce (comp.lisp_obj_type, y) }; - gcc_jit_rvalue *arg [] = { obj }; - return gcc_jit_context_new_call (comp.ctxt, - NULL, - comp.symbol_with_pos_sym, - 1, - arg); + return emit_call (intern_c_string ("slow_eq"), + comp.bool_type, + ARRAYELTS (args), + args, + false); } static gcc_jit_rvalue * emit_EQ (gcc_jit_rvalue *x, gcc_jit_rvalue *y) { - return - emit_OR ( - gcc_jit_context_new_comparison ( - comp.ctxt, NULL, - GCC_JIT_COMPARISON_EQ, - emit_XLI (x), emit_XLI (y)), - emit_AND ( - gcc_jit_lvalue_as_rvalue ( - gcc_jit_rvalue_dereference (comp.f_symbols_with_pos_enabled_ref, - NULL)), - emit_OR ( - emit_AND ( - emit_SYMBOL_WITH_POS_P (x), - emit_OR ( - emit_AND ( - emit_SYMBOL_WITH_POS_P (y), - emit_BASE_EQ ( - emit_XLI (emit_SYMBOL_WITH_POS_SYM (x)), - emit_XLI (emit_SYMBOL_WITH_POS_SYM (y)))), - emit_AND ( - emit_BARE_SYMBOL_P (y), - emit_BASE_EQ ( - emit_XLI (emit_SYMBOL_WITH_POS_SYM (x)), - emit_XLI (y))))), - emit_AND ( - emit_BARE_SYMBOL_P (x), - emit_AND ( - emit_SYMBOL_WITH_POS_P (y), - emit_BASE_EQ ( - emit_XLI (x), - emit_XLI (emit_SYMBOL_WITH_POS_SYM (y)))))))); + gcc_jit_rvalue *base_eq = emit_BASE_EQ (x, y); + gcc_jit_rvalue *symbols_with_pos_enabled_rval = gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference (comp.f_symbols_with_pos_enabled_ref, + NULL)); + + gcc_jit_rvalue *expect_args[] = + { emit_coerce (comp.long_type, symbols_with_pos_enabled_rval), + gcc_jit_context_new_rvalue_from_int (comp.ctxt, + comp.long_type, + 0) }; + + gcc_jit_rvalue *likely_symbols_with_pos_enabled = emit_coerce ( + comp.bool_type, + gcc_jit_context_new_call ( + comp.ctxt, + NULL, + gcc_jit_context_get_builtin_function (comp.ctxt, + "__builtin_expect"), + 2, + expect_args)); + + return emit_OR ( + base_eq, + emit_AND (likely_symbols_with_pos_enabled, emit_slow_eq (x, y))); } static gcc_jit_rvalue * @@ -2598,6 +2583,21 @@ emit_consp (Lisp_Object insn) 1, &res); } +static gcc_jit_rvalue * +emit_eq (Lisp_Object insn) +{ + gcc_jit_rvalue *x = emit_mvar_rval (SECOND (insn)); + gcc_jit_rvalue *y = emit_mvar_rval (THIRD (insn)); + gcc_jit_rvalue *res = emit_EQ (x, y); + res = emit_coerce (comp.bool_type, res); + return gcc_jit_context_new_call (comp.ctxt, + NULL, + comp.bool_to_lisp_obj, + 1, + &res); +} + + static gcc_jit_rvalue * emit_car (Lisp_Object insn) { @@ -2930,6 +2930,10 @@ declare_runtime_imported_funcs (void) ADD_IMPORTED (helper_GET_SYMBOL_WITH_POSITION, comp.lisp_symbol_with_position_ptr_type, 1, args); + args[0] = comp.lisp_obj_type; + args[1] = comp.lisp_obj_type; + ADD_IMPORTED (slow_eq, comp.bool_type, 2, args); + args[0] = comp.lisp_obj_type; args[1] = comp.lisp_obj_type; ADD_IMPORTED (helper_sanitizer_assert, comp.lisp_obj_type, 2, args); @@ -4515,6 +4519,7 @@ Return t on success. */) register_emitter (Qadd1, emit_add1); register_emitter (Qsub1, emit_sub1); register_emitter (Qconsp, emit_consp); + register_emitter (Qeq, emit_eq); register_emitter (Qcar, emit_car); register_emitter (Qcdr, emit_cdr); register_emitter (Qsetcar, emit_setcar);