Add fused get_loc0_loc1 opcode (#55)

get_loc0 and get_loc1 are individually very frequent opcodes _and_ they
are very often paired together, making them ideal candidates for opcode
fusion.

Reduces microbench.js running time by about 4%.
This commit is contained in:
Ben Noordhuis 2023-11-13 00:54:13 +01:00 committed by GitHub
parent ba9569c76f
commit f404980ec0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 0 deletions

View file

@ -302,6 +302,7 @@ DEF( get_loc8, 2, 0, 1, loc8)
DEF( put_loc8, 2, 1, 0, loc8) DEF( put_loc8, 2, 1, 0, loc8)
DEF( set_loc8, 2, 1, 1, loc8) DEF( set_loc8, 2, 1, 1, loc8)
DEF( get_loc0_loc1, 1, 0, 2, none_loc)
DEF( get_loc0, 1, 0, 1, none_loc) DEF( get_loc0, 1, 0, 1, none_loc)
DEF( get_loc1, 1, 0, 1, none_loc) DEF( get_loc1, 1, 0, 1, none_loc)
DEF( get_loc2, 1, 0, 1, none_loc) DEF( get_loc2, 1, 0, 1, none_loc)

View file

@ -14976,6 +14976,14 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj,
CASE(OP_put_loc8): set_value(ctx, &var_buf[*pc++], *--sp); BREAK; CASE(OP_put_loc8): set_value(ctx, &var_buf[*pc++], *--sp); BREAK;
CASE(OP_set_loc8): set_value(ctx, &var_buf[*pc++], JS_DupValue(ctx, sp[-1])); BREAK; CASE(OP_set_loc8): set_value(ctx, &var_buf[*pc++], JS_DupValue(ctx, sp[-1])); BREAK;
// Observation: get_loc0 and get_loc1 are individually very
// frequent opcodes _and_ they are very often paired together,
// making them ideal candidates for opcode fusion.
CASE(OP_get_loc0_loc1):
*sp++ = JS_DupValue(ctx, var_buf[0]);
*sp++ = JS_DupValue(ctx, var_buf[1]);
BREAK;
CASE(OP_get_loc0): *sp++ = JS_DupValue(ctx, var_buf[0]); BREAK; CASE(OP_get_loc0): *sp++ = JS_DupValue(ctx, var_buf[0]); BREAK;
CASE(OP_get_loc1): *sp++ = JS_DupValue(ctx, var_buf[1]); BREAK; CASE(OP_get_loc1): *sp++ = JS_DupValue(ctx, var_buf[1]); BREAK;
CASE(OP_get_loc2): *sp++ = JS_DupValue(ctx, var_buf[2]); BREAK; CASE(OP_get_loc2): *sp++ = JS_DupValue(ctx, var_buf[2]); BREAK;
@ -29661,6 +29669,14 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s)
pos_next = cc.pos; pos_next = cc.pos;
break; break;
} }
/* transformation: get_loc(0) get_loc(1) -> get_loc0_loc1 */
if (idx == 0 && code_match(&cc, pos_next, OP_get_loc, 1, -1)) {
if (cc.line_num >= 0) line_num = cc.line_num;
add_pc2line_info(s, bc_out.size, line_num);
dbuf_putc(&bc_out, OP_get_loc0_loc1);
pos_next = cc.pos;
break;
}
add_pc2line_info(s, bc_out.size, line_num); add_pc2line_info(s, bc_out.size, line_num);
put_short_code(&bc_out, op, idx); put_short_code(&bc_out, op, idx);
} }