From f4e3fce9ea80973269d24b7179ae2ad2cbff83d0 Mon Sep 17 00:00:00 2001 From: Mattias EngdegĂ„rd Date: Wed, 8 Oct 2025 18:03:08 +0200 Subject: exec_byte_code: use fixed registers for top and pc (bug#79610) GCC seems to have difficulty allocating important global interpreter variables in registers; telling it which ones to use for 'top' and 'pc' makes a big difference and seems to ease pressure enough for it to deal with other variables as well. We do it for AMD64 and ARM64. Clang doesn't seem to need these directives. It does result in -Wclobbered warnings that seem difficult to silence. * src/bytecode.c (BC_REG_TOP, BC_REG_PC): New. (exec_byte_code): Use them. --- src/bytecode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/bytecode.c b/src/bytecode.c index e116936e55d..c3fc3100e21 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -449,6 +449,20 @@ valid_sp (struct bc_thread_state *bc, Lisp_Object *sp) return sp < (Lisp_Object *)fp && sp + 1 >= fp->saved_fp->next_stack; } +/* GCC seems to have difficulty putting important variables in + registers, so give it some heavy-handed assistance by specifying + which ones to use. Use callee-saved registers to reduce spill/fill. */ +#if __GNUC__ && !__clang__ && defined __x86_64__ +#define BC_REG_TOP asm ("rbx") +#define BC_REG_PC asm ("r12") +#elif __GNUC__ && !__clang__ && defined __aarch64__ +#define BC_REG_TOP asm ("x19") +#define BC_REG_PC asm ("x20") +#else +#define BC_REG_TOP +#define BC_REG_PC +#endif + /* Execute the byte-code in FUN. ARGS_TEMPLATE is the function arity encoded as an integer (the one in FUN is ignored), and ARGS, of size NARGS, should be a vector of the actual arguments. The @@ -466,8 +480,8 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template, struct bc_thread_state *bc = ¤t_thread->bc; /* Values used for the first stack record when called from C. */ - Lisp_Object *top = NULL; - unsigned char const *pc = NULL; + register Lisp_Object *top BC_REG_TOP = NULL; + register unsigned char const *pc BC_REG_PC = NULL; Lisp_Object bytestr = AREF (fun, CLOSURE_CODE); -- cgit v1.2.1