exec_byte_code: reduce use of semi-global 'op' (bug#79610)

* src/bytecode.c (exec_byte_code):
Re-type op from int to ptrdiff_t, which avoids some useless conversions.
Reduce its use by using local variables for intra-block use,
and another variable (arg) where it doesn't need to be alive across
instruction dispatch.  We also eliminate it where performance doesn't
matter by re-fetching it from the instruction stream.

All this should help the register allocator.
This commit is contained in:
Mattias Engdegård
2025-09-22 18:33:01 +02:00
parent 8ed5b4378a
commit b72e352cb4

View File

@@ -533,7 +533,8 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
while (true)
{
int op;
ptrdiff_t op;
ptrdiff_t arg;
enum handlertype type;
if (BYTE_CODE_SAFE && !valid_sp (bc, top))
@@ -601,7 +602,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
FIRST
{
CASE (Bvarref7):
op = FETCH2;
arg = FETCH2;
goto varref;
CASE (Bvarref):
@@ -610,16 +611,16 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
CASE (Bvarref3):
CASE (Bvarref4):
CASE (Bvarref5):
op -= Bvarref;
arg = op - Bvarref;
goto varref;
/* This seems to be the most frequently executed byte-code
among the Bvarref's, so avoid a goto here. */
CASE (Bvarref6):
op = FETCH;
arg = FETCH;
varref:
{
Lisp_Object v1 = vectorp[op], v2;
Lisp_Object v1 = vectorp[arg], v2;
if (XBARE_SYMBOL (v1)->u.s.redirect != SYMBOL_PLAINVAL
|| (v2 = XBARE_SYMBOL (v1)->u.s.val.value,
BASE_EQ (v2, Qunbound)))
@@ -631,7 +632,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
CASE (Bgotoifnil):
{
Lisp_Object v1 = POP;
op = FETCH2;
arg = FETCH2;
if (NILP (v1))
goto op_branch;
NEXT;
@@ -679,18 +680,18 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
CASE (Bvarset3):
CASE (Bvarset4):
CASE (Bvarset5):
op -= Bvarset;
arg = op - Bvarset;
goto varset;
CASE (Bvarset7):
op = FETCH2;
arg = FETCH2;
goto varset;
CASE (Bvarset6):
op = FETCH;
arg = FETCH;
varset:
{
Lisp_Object sym = vectorp[op];
Lisp_Object sym = vectorp[arg];
Lisp_Object val = POP;
if (XBARE_SYMBOL (sym)->u.s.redirect == SYMBOL_PLAINVAL
&& !XBARE_SYMBOL (sym)->u.s.trapped_write)
@@ -710,11 +711,11 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
/* ------------------ */
CASE (Bvarbind6):
op = FETCH;
arg = FETCH;
goto varbind;
CASE (Bvarbind7):
op = FETCH2;
arg = FETCH2;
goto varbind;
CASE (Bvarbind):
@@ -723,18 +724,18 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
CASE (Bvarbind3):
CASE (Bvarbind4):
CASE (Bvarbind5):
op -= Bvarbind;
arg = op - Bvarbind;
varbind:
/* Specbind can signal and thus GC. */
specbind (vectorp[op], POP);
specbind (vectorp[arg], POP);
NEXT;
CASE (Bcall6):
op = FETCH;
arg = FETCH;
goto docall;
CASE (Bcall7):
op = FETCH2;
arg = FETCH2;
goto docall;
CASE (Bcall):
@@ -743,10 +744,10 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
CASE (Bcall3):
CASE (Bcall4):
CASE (Bcall5):
op -= Bcall;
arg = op - Bcall;
docall:
{
DISCARD (op);
DISCARD (arg);
#ifdef BYTE_CODE_METER
if (byte_metering_on && SYMBOLP (TOP))
{
@@ -770,7 +771,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
error ("Lisp nesting exceeds `max-lisp-eval-depth'");
}
ptrdiff_t call_nargs = op;
ptrdiff_t call_nargs = arg;
Lisp_Object call_fun = TOP;
Lisp_Object *call_args = &TOP + 1;
@@ -815,11 +816,11 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
}
CASE (Bunbind6):
op = FETCH;
arg = FETCH;
goto dounbind;
CASE (Bunbind7):
op = FETCH2;
arg = FETCH2;
goto dounbind;
CASE (Bunbind):
@@ -828,44 +829,44 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
CASE (Bunbind3):
CASE (Bunbind4):
CASE (Bunbind5):
op -= Bunbind;
arg = op - Bunbind;
dounbind:
unbind_to (specpdl_ref_add (SPECPDL_INDEX (), -op), Qnil);
unbind_to (specpdl_ref_add (SPECPDL_INDEX (), -arg), Qnil);
NEXT;
CASE (Bgoto):
op = FETCH2;
arg = FETCH2;
op_branch:
op -= pc - bytestr_data;
arg -= pc - bytestr_data;
if (BYTE_CODE_SAFE
&& ! (bytestr_data - pc <= op
&& op < bytestr_data + bytestr_length - pc))
&& ! (bytestr_data - pc <= arg
&& arg < bytestr_data + bytestr_length - pc))
emacs_abort ();
quitcounter += op < 0;
quitcounter += arg < 0;
if (!quitcounter)
{
quitcounter = 1;
maybe_gc ();
maybe_quit ();
}
pc += op;
pc += arg;
NEXT;
CASE (Bgotoifnonnil):
op = FETCH2;
arg = FETCH2;
if (!NILP (POP))
goto op_branch;
NEXT;
CASE (Bgotoifnilelsepop):
op = FETCH2;
arg = FETCH2;
if (NILP (TOP))
goto op_branch;
DISCARD (1);
NEXT;
CASE (Bgotoifnonnilelsepop):
op = FETCH2;
arg = FETCH2;
if (!NILP (TOP))
goto op_branch;
DISCARD (1);
@@ -965,7 +966,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
struct handler *c = handlerlist;
handlerlist = c->next;
top = c->bytecode_top;
op = c->bytecode_dest;
arg = c->bytecode_dest;
bc = &current_thread->bc;
struct bc_frame *fp = bc->fp;
@@ -1105,10 +1106,12 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
NEXT;
CASE (BlistN):
op = FETCH;
DISCARD (op - 1);
TOP = Flist (op, &TOP);
NEXT;
{
ptrdiff_t n = FETCH;
DISCARD (n - 1);
TOP = Flist (n, &TOP);
NEXT;
}
CASE (Blength):
TOP = Flength (TOP);
@@ -1224,10 +1227,12 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
NEXT;
CASE (BconcatN):
op = FETCH;
DISCARD (op - 1);
TOP = Fconcat (op, &TOP);
NEXT;
{
ptrdiff_t n = FETCH;
DISCARD (n - 1);
TOP = Fconcat (n, &TOP);
NEXT;
}
CASE (Bsub1):
TOP = (FIXNUMP (TOP) && XFIXNUM (TOP) != MOST_NEGATIVE_FIXNUM
@@ -1410,10 +1415,12 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
NEXT;
CASE (BinsertN):
op = FETCH;
DISCARD (op - 1);
TOP = Finsert (op, &TOP);
NEXT;
{
ptrdiff_t n = FETCH;
DISCARD (n - 1);
TOP = Finsert (n, &TOP);
NEXT;
}
CASE (Bpoint_max):
PUSH (make_fixed_natnum (ZV));
@@ -1676,7 +1683,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
for that instead. */
/* CASE (Bstack_ref): */
error ("Invalid byte opcode: op=%d, ptr=%"pD"d",
op, pc - 1 - bytestr_data);
pc[-1], pc - 1 - bytestr_data);
/* Handy byte-codes for lexical binding. */
CASE (Bstack_ref1):
@@ -1715,14 +1722,16 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
NEXT;
}
CASE (BdiscardN):
op = FETCH;
if (op & 0x80)
{
op &= 0x7F;
top[-op] = TOP;
}
DISCARD (op);
NEXT;
{
ptrdiff_t n = FETCH;
if (n & 0x80)
{
n &= 0x7F;
top[-n] = TOP;
}
DISCARD (n);
NEXT;
}
CASE (Bswitch):
{
@@ -1750,7 +1759,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
for (ptrdiff_t i = h->count - 1; i >= 0; i--)
if (BASE_EQ (v1, HASH_KEY (h, i)))
{
op = XFIXNUM (HASH_VALUE (h, i));
arg = XFIXNUM (HASH_VALUE (h, i));
goto op_branch;
}
}
@@ -1759,7 +1768,7 @@ exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
ptrdiff_t i = hash_find (h, v1);
if (i >= 0)
{
op = XFIXNUM (HASH_VALUE (h, i));
arg = XFIXNUM (HASH_VALUE (h, i));
goto op_branch;
}
}